BSP430
20141115
Board Support Package for MSP430 microcontrollers
|
A key requirement for BSP430 is the ability to have independent software modules that require access to timer, port, or other peripheral interrupts without requiring that the source code for the interrupt service routine be modified to add or remove support for these modules. This is accomplished using a callback infrastructure.
The declarations associated with the callback infrastructure are included in the <bsp430/periph.h> header.
Two types of callback function are declared:
When registered, the callback function is invoked from within the interrupt handler upon receipt of the corresponding event.
A HAL structure supporting interrupts will include pointers to structures that define a chain of callbacks to be invoked in particular events. There is one structure for each callback style, those being sBSP430halISRVoidChainNode and sBSP430halISRIndexedChainNode. These structures contain only two fields: sBSP430halISRVoidChainNode.next_ni is a pointer to the next callback in the chain, while sBSP430halISRVoidChainNode.callback_ni is the pointer to the function that will service the callback.
The HAL structure tags holding the start of the callback chain, as well as the sBSP430halISRVoidChainNode.next_ni tags within chain nodes, must only be mutated while interrupts are disabled. The steps required to add or remove a valid from the chain are straightforward and can be explicitly coded if only one callback will ever be used. Nonetheless, in the general case you should assume other resources may be linked into the callback and that the node you are removing may no longer be the head of the chain. Utility macros as exemplified below support these operations:
The callback chain infrastructure supports an arbitrary number of notifications resulting from a single event. In many cases, it would be improper to invoke chain elements past the point where the event was completely handled. In addition, it is necessary to inform the interrupt handler top half when a low power mode should be exited. This information is conveyed to the interrupt through the return value of the callback handler, using a set of flags formed by combining bit values defined in <bsp430/periph.h>. The current set of callback flags is:
Name | Purpose |
---|---|
BSP430_HAL_ISR_CALLBACK_EXIT_LPM | Interrupt handler wakes from LPM by clearing the BSP430_CORE_LPM_EXIT_MASK bits in the status register stored on interrupt entry |
BSP430_HAL_ISR_CALLBACK_BREAK_CHAIN | Interrupt handler does not invoke any subsequent callbacks in the chain |
BSP430_HAL_ISR_CALLBACK_YIELD | Interrupt handler should inform an RTOS that a context switch is required |
BSP430_HAL_ISR_CALLBACK_DISABLE_INTERRUPT | Interrupt handler should disable the peripheral-specific interrupt |
The return value from a handler which receives an input character is likely to be:
BSP430_HAL_ISR_CALLBACK_BREAK_CHAIN indicates that the handler has consumed the input; it would be inappropriate to continue to pass it on to subsequent handlers. BSP430_HAL_ISR_CALLBACK_EXIT_LPM is added to cause the interrupt to exit any low power mode it might be in, so that normal processing can deal with the event.
The return value from a handler which transmits an output character and for which there are no additional output characters queued would add BSP430_HAL_ISR_CALLBACK_DISABLE_INTERRUPT, to inhibit the transmission interrupt from recurring. See vBSP430serialWakeupTransmit_rh.
In some cases it is helpful for the callback function to be provided additional information, for example state that is exchanged between the interrupt routine and control flow outside the interrupt. Rather than provide another parameter to the callback handler, such state can be stored in a location at a fixed offset from the callback chain node that is already passed.
The following code from the console utility demonstrates how to provide a buffer for incoming characters that is specific to the callback structure. The same technique can be used for other state.
Copyright 2012-2014, Peter A. Bigot