Extreme HAL debugging

I really like the  .NET Micro Framework and especially the emulator story. There is nearly nothing that you cannot do. It could be a little bit easier if some classes and methods where not internal. But ok, excellent and a huge step ahead anyway.


I found a way to decorate the low level HAL (hardware abstraction layer) drivers to monitor when they are accessed by an emulated MF application. So you could debug and monitor low level access eg. to GPIO-Ports and serial ports.


First we need a driver that wraps the original driver (so that we do not need to write all from scratch) and delegates the method calls to the original after logging the call and the parameters.


using System;



using System.Diagnostics;


using Microsoft.SPOT.Emulator;


using Microsoft.SPOT.Emulator.Gpio;


 


namespace Kuehner.SPOT.Emulator


{


    internal class GpioDriverDecorator : EmulatorComponent, IGpioDriver


    {


        private readonly IGpioDriver decoratedDriver;


 


        public GpioDriverDecorator(IGpioDriver decoratedDriver)


        {


            if (decoratedDriver == null)


                throw new ArgumentNullException(“decoratedDriver”);


            this.decoratedDriver = decoratedDriver;


        }


 


        #region IGpioDriver Members


        uint IGpioDriver.Attributes(uint pin)


        {


            return this.decoratedDriver.Attributes(pin);


        }


 


        void IGpioDriver.DisablePin(uint pin, int resistorState, uint direction, uint altFunction)


        {


            this.decoratedDriver.DisablePin(pin, resistorState, direction, altFunction);


        }


 


        bool IGpioDriver.EnableInputPin(uint pin, bool glitchFilterEnable, IntPtr isr, IntPtr isrParam, int interruptEdge, int resistorState)


        {


            return this.decoratedDriver.EnableInputPin(pin, glitchFilterEnable, isr, isrParam, interruptEdge, resistorState);


        }


 


        bool IGpioDriver.EnableInputPin(uint pin, bool glitchFilterEnable, IntPtr isr, int interruptEdge, int resistorState)


        {


            return this.decoratedDriver.EnableInputPin(pin, glitchFilterEnable, isr, interruptEdge, resistorState);


        }


 


        void IGpioDriver.EnableOutputPin(uint pin, bool initialState)


        {


            this.decoratedDriver.EnableOutputPin(pin, initialState);


        }


 


        uint IGpioDriver.GetDebounce()


        {


            return this.decoratedDriver.GetDebounce();


        }


 


        int IGpioDriver.GetPinCount()


        {


            return this.decoratedDriver.GetPinCount();


        }


 


        bool IGpioDriver.GetPinState(uint pin)


        {


            bool pinState = this.decoratedDriver.GetPinState(pin);


            Trace.WriteLine(string.Format(“GetPinState pin={0} is {1}”, pin, pinState), “IGpioDriver”);


            return pinState;


        }


 


        bool IGpioDriver.Initialize()


        {


            return this.decoratedDriver.Initialize();


        }


 


        bool IGpioDriver.PinIsBusy(uint pin)


        {


            return this.decoratedDriver.PinIsBusy(pin);


        }


 


        bool IGpioDriver.ReservePin(uint pin, bool reserve)


        {


            return this.decoratedDriver.ReservePin(pin, reserve);


        }


 


        bool IGpioDriver.SetDebounce(long debounceTime)


        {


            return this.decoratedDriver.SetDebounce(debounceTime);


        }


 


        void IGpioDriver.SetPinState(uint pin, bool pinState)


        {


            Trace.WriteLine(string.Format(“SetPinState pin={0}, pinState={1}”, pin, pinState), “IGpioDriver”);


            this.decoratedDriver.SetPinState(pin, pinState);


        }


 


        bool IGpioDriver.Uninitialize()


        {


            return this.decoratedDriver.Uninitialize();


        }


        #endregion


    }


}


Then we need a managed HAL to hook up the drivers.


 



using System;


using System.Reflection;


using Microsoft.SPOT.Emulator;


using Microsoft.SPOT.Emulator.Com;


using Microsoft.SPOT.Emulator.Gpio;


 


namespace Kuehner.SPOT.Emulator


{


    public class MonitoringHal : Hal


    {


        private readonly IComDriver decoratedComDriver;


        private readonly IGpioDriver decoratedGpioDriver;


 


        public MonitoringHal()


        {


            this.decoratedComDriver = this.Com;


            this.Com = new ComDriverDecorator(this.decoratedComDriver);


            this.decoratedGpioDriver = this.Gpio;


            this.Gpio = new GpioDriverDecorator(this.decoratedGpioDriver);


        }


 


        public override void SetupComponent()


        {


            base.SetupComponent();


            //set the internal emulator property for the original component since this property


            //is only set if the component is registered and it is needed to work correctly


            SetEmulator(this.decoratedComDriver);


            SetEmulator(this.decoratedGpioDriver);


        }


 


        private void SetEmulator(object component)


        {


            System.Diagnostics.Debug.Assert(component is EmulatorComponent);


            MethodInfo mi = typeof(EmulatorComponent).GetMethod(“SetEmulator”, BindingFlags.NonPublic | BindingFlags.Instance);


            mi.Invoke(component, new object[] { this.Emulator });


        }


    }


}


 


This was very extreme stuff and you usually might not need it. But it helps to understand how the emulator works.


 

2 thoughts on “Extreme HAL debugging”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>