11.07.2015 Views

Manual - Quantum Leaps

Manual - Quantum Leaps

Manual - Quantum Leaps

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

QP state machine frameworks for AVRQDKAtmel AVR with Atmel StudioDocument Revision LMarch 2014Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLCwww.quantum-leaps.comwww.state-machine.com


Table of Contents1 Introduction ..................................................................................................................................................... 11.1 About QP .................................................................................................................................................... 21.2 About QM ................................................................................................................................................... 31.3 About this QDK .............................................................................................................................................. 31.4 Licensing QP .............................................................................................................................................. 41.5 Licensing QM .............................................................................................................................................. 42 Getting Started ................................................................................................................................................ 52.1 Installation ...................................................................................................................................................... 52.2 Building the QP Libraries ............................................................................................................................... 72.3 Building the Examples .................................................................................................................................... 82.4 Running the Examples ................................................................................................................................... 93 The Vanilla QP Port ......................................................................................................................................... 113.1 Compiler Options Used .................................................................................................................................. 113.2 The qep_port.h Header File ........................................................................................................................... 113.3 The qf_port.h Header File .............................................................................................................................. 123.4 BSP for AVR .................................................................................................................................................. 143.5 QP Idle Loop Customization in QF_onIdle() ................................................................................................... 153.6 Assertion Handling Policy in Q_onAssert() .................................................................................................... 164 The QK Port ..................................................................................................................................................... 174.1 Compiler and Linker Options Used ................................................................................................................ 174.2 The qk_port.h Header File ............................................................................................................................. 174.3 The QK-specific Interrupt Processing in the BSP ........................................................................................... 184.4 Idle Loop Customization in the QK_onIdle() ................................................................................................... 195 The QS Software Tracing Instrumentation ................................................................................................... 206 Related Documents and References ............................................................................................................. 227 Contact Information ........................................................................................................................................ 23


QDKAVR with Atmel Studiowww.state-machine.com/avr2 Getting StartedThis section describes how to install, build, and use QDK-AVR-GNU based two examples. Thisinformation is intentionally included early in this document, so that you could start using the QDK as soonas possible. The main focus of this section is to walk you quickly through the main points without slowingyou down with full-blown detail.NOTE: This QDK assumes that the standard QP distribution consisting of QEP, QF, and QK hasbeen installed, before installing this QDK. It is also strongly recommended that you read the QPtutorial before you start experimenting with this QDK.2.1 InstallationThe QDK code is distributed in a ZIP archive (qdkc_avr-gnu.zip. You can unzip the archive into thesame directory into which you’ve installed all the standard QP components. The installation directory youchoose will be referred henceforth as QP Root Directory . The following Listing 1 shows thedirectory structure and selected files included in the QDK-AVR-GNU distribution. (Please note that the QPdirectory structure is described in detail in a separate Application Note: “QP Directory Structure”):Listing 1 Selected QP directories and files after installing QDK-AVR-GNU. The highlightedelements are included in the standard QDK-AVR-GNU distribution.qpc\- QP installation directory+-doc\| +-AN_DPP.pdf - Application Note “Dining Philosopher Problem Example”| +-QDK_AVR-GNU-STK600.pdf – This QDK <strong>Manual</strong> “QDK AVR with GNU Compiler”|+-include/- QP public include files|+-ports/- QP ports| +-avr/ - AVR port| | +-qk/ - QK (<strong>Quantum</strong> Kernel) ports| | | +-gnu/ - GNU compiler| | | | +-dbg/ - QP library – Debug configuration| | | | | +-libqp_atmega2560.a - QP library| | | | +-rel/ - QP library – Release configuration| | | | +-spy/ - QP library – Spy configuration| | | | || | | | +-make_atmega2560.bat - make script for building the QP libraries| | | | +-qep_port.h - QEP port| | | | +-qf_port.h - QF port| | | | +-qk_port.h - QK port| | | | +-qk_port.c - QK port implementation| | | | +-qs_port.h - QS port| | | | +-qp_port.h - QP port| | || | +-vanilla/ - “vanilla” ports| | | +-gnu/ - GNU compiler| | | | +-dbg/ - QP library – Debug configuration| | | | +-dbg/ - QP library – Release configuration| | | | +-spy/ - QP library – Spy configuration| | | | | +-libqp_atmega2560.a - QP library| | | | || | | | +-make_atmega2560.bat - make script for building the QP librariesCopyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.5 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr| | | | +-qep_port.h - QEP port| | | | +-qf_port.h - QF port| | | | +-qs_port.h - QS port| | | | +-qp_port.h - QP port|+-examples/- subdirectory containing the examples| +-avr/ - AVR port| | || | +-qk/ - QK examples| | | +-gnu/ - GNU AVR compiler| | | | +-dpp-qk-stk600-atmega2560/ - DPP example for AVR STK600-ATMEGA2560| | | | | +-Debug/ - directory containing the Debug build| | | | | +-Release/ - directory containing the Release build| | | | | +-Spy/ - directory containing the Spy build| | | | | +-dpp-qk-stk600-atmega2560.cproj – Atmel Studio 6 project| | | | | +-dpp-qk-stk600-atmega2560.atsln – Atmel Studio 6 solution| | | | | +-dpp.h - the DPP header file| | | | | +-dpp.qm - QM model for the DPP application| | | | | +-bsp.c - Board Support Package for AVR| | | | | +-bsp.h - BSP header file| | | | | +-main.c - the main function| | | | | +-philo.c - the Philosopher active object| | | | | +-table.c - the Table active object| | || | +-vanilla/ - “vanilla” examples| | | +-gnu/ - GNU AVR compiler| | | | +-dpp-stk600-atmega2560/ - DPP example for AVR STK600-ATMEGA2560| | | | | +-Debug/ - directory containing the Debug build| | | | | +-Release/ - directory containing the Release build| | | | | +-Spy/ - directory containing the Spy build| | | | | +-dpp-stk600-atmega2560.cproj – Atmel Studio 6 project| | | | | +-dpp-stk600-atmega2560.atsln – Atmel Studio 6 solution| | | | | +-dpp.h - the DPP header file| | | | | +-dpp.qm - QM model for the DPP application| | | | | +-bsp.c - Board Support Package for AVR| | | | | +-bsp.h - BSP header file| | | | | +-main.c - the main function| | | | | +-philo.c - the Philosopher active object| | | | | +-dpp.h - the DPP header file| | | | | +-table.c - the Table active objectCopyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.6 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr2.2 Building the QP LibrariesAll QP components are deployed as libraries that you statically link to your application.-QP is deployed asa library that you statically link to your application. The pre-built QP libraries for various buildconfigurations are provided inside the \ports\avr\ directory (see Listing 1). This section describessteps you need to take to rebuild the libraries yourself.NOTE: To streamline and simplify the QP-library build process, <strong>Quantum</strong> <strong>Leaps</strong> software does notuse the vendor-specific IDEs, such as the GNU Embedded Workbench IDE, for building the QPlibraries. Instead, this QDK provides command-line build process based on simple batch scripts.The build process for your application is largely independent on the QP-library builds. In fact, onceyou have the QP libraries, you typically don’t need to rebuild them—at least not on the daily basis asyou work on your application. This QDK uses the Atmel AVRStudio IDE to build the exampleapplications, but you are free to use any other build strategy.The code distribution contains all the batch file make_atmega2560.bat for building all the libraries locatedin \ports\avr\vanilla\gnu\ directory.For example, to build the debug version of all the QP libraries for the AVR, with the GNU AVR compiler,you open a console window on a Windows PC, change directory to \ports\avr\vanilla\gnu\,and invoke the batch by typing at the command prompt the following command:make_atmega2560The make process should produce the QP libraries in the location: \ports\avr\vanilla\gnu\-dbg\. The make_atmega2560.bat assumes that the GNU-AVR toolset has been installed in thedirectory C:\tools\Atmel\Studio_6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain.NOTE: You need to adjust the symbol GNU_AVR at the top of the make_atmega2560.bat file ifyou’ve installed the Atmel Studio in a different directory.In order to take advantage of the Q-SPY instrumentation, you need to build the Spy version of the QPlibraries. You achieve this by invoking the make_atmega2560.bat utility with the “spy” target, like this:make_atmega2560 spyThe make process should produce the QP libraries in the directory: \ports\avr\vanilla\gnu\-spy\.NOTE: The QP libraries and QP applications can be built in the following three build configurations:Debug - this configuration is built with full debugging information and minimal optimization. When theQP framework finds no events to process, the framework busy-idles until there are new events toprocess.Release - this configuration is built with no debugging information and high optimization. Singlesteppingand debugging is effectively impossible due to the lack of debugging information andoptimized code, but the debugger can be used to download and start the executable. When the QPframework finds no events to process, the framework puts the CPU to sleep until there are newevents to process.Spy - like the debug variant, this variant is built with full debugging information and minimaloptimization. Additionally, it is build with the QP's Q-SPY trace functionality built in. The on-boardserial port and the Q-Spy host application are used for sending and viewing trace data. Like theDebug configuration, the QP framework busy-idles until there are new events to process.You choose the build configuration by providing a target to the make_atmega2560.bat utility. The defaulttarget is “dbg”. Other targets are “rel”, and “spy” respectively. The following table summarizes thetargets accepted by make_atmega2560.bat.Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.7 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr2.3 Building the ExamplesThe QDK contains the Atmel Studio project files located in \examples\avr\vanilla\gnu\dppstk600-atmega2560\dpp-stk600-atmega2560.avrslnfor the “vanilla” version, and in \-examples\avr\qk\gnu\dpp-qk-stk600-atmega2560\dpp-qk-stk600-atmega2560.avrsln for theQK version, respectively.Figure 4 The DPP example project opened in Atmel Studio.The build configuration is selected by the drop-down box.Select buildconfigurationCopyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.8 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr2.4 Running the ExamplesFigure 5 shows how to make internal connections on the STK600 board to enable the external LEDs andthe external RS-232 port (see also Figure 1). The LEDs are connected to PORTD with the flat-bandcable. The RS-232 SPARE port is connected with the PORTE pins 0 and 1 with a 2-wire cable as shownFigure 5.After loading the DPP example to the board, the external LEDs connected to PORTD should startblinking. The LEDs 0-4 represent philosophers 0-4. An LED-on represents an “eating” philosopher.Extinguished LED represents philosopher “thinking” or “hungry”.Figure 5 The connections on the STK600-ATMEGA2560.PORTDto LEDsPORTE pins PE0/PE1 toRS232 SPARE RXD/TXDThe last LED 7 is used to visualize the idle loop activity. The LED 7 is rapidly toggled on and off from theidle callback, so its intensity is proportional to the frequency of idle loop.As the application is running, the status LEDs at the bottom of the board (see Figure 1) should blinkindicating the changing status of the Dining Philosophers. If you downloaded the Spy build configurationto the target board, you could launch the QSPY host utility to observe the output in the human-readableformat.NOTE: The QSPY host utility is now included in the Qtools collection, which is available for aseparate download from www.state-machine.com/downlaods. The following discussion assumes thatyou have downloaded and installed Qtools, including adding the Qtools directory to the PATHvariable on your system.You launch the QSPY utility on a Windows PC as follows:qspy –c COM5 –b 38400 –O2 –F2 –E1 –P1 –B1This will start the QSPY host application to listen on COM5 serial port with baud rate 38400. (Please usethe actual virtual COM port number on your PC.) The following screen shot shows the QSPY output fromthe DPP run:Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.9 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr3 The Vanilla QP PortThe “vanilla” port shows how to use <strong>Quantum</strong> Platform on a “bare metal” AVR-based system without anyunderlying multitasking kernel.In the “vanilla” version of the QP, the only component requiring platform-specific porting is the QF. Theother two components: QEP and QS require merely recompilation and will not be discussed here.Obviously, with the vanilla port you’re not using the QK component.In case of AVR, the “vanilla” QF port is very similar to the generic “vanilla” port described in Chapter 9 of[PSiCC2].3.1 Compiler Options UsedThe most important GNU compiler options (used both for building the QP libraries and the final applicationimage) are as follows::: adjust these flags to the specific AVR variant that you're usingset MCU_TARGET=atmega2560. . .set CCFLAGS=-g -O2 -c -mmcu=%MCU_TARGET% -WallIn particular, the device used was ATmega2560. You might want to replace this command file to matchyour AVR device.NOTE: The most important parameter that you might want to customize for your application is theAVR device (MCU_TARGET). You need to change this symbol consistently in the make_2560.batscript for building the QP libraries as well as in the Atmel Studio project file for your application.3.2 The qep_port.h Header FileAVR is a Harvard architecture that uses different program and data spaces as well as different CPUinstructions to access these two address spaces (data memory is 8-bit wide while program memory is 16-bit wide). Consequently, one of the biggest concerns in AVR programs is to correctly allocate and accessconstant data in the program space (ROM) rather than the precious RAM. Since the ROM resides in adifferent address space, you need to tell the compiler to place variables there. You also need a way toaccess the data (i.e., the compiler has to use the lpm instruction.)The GCC-AVR compiler supports data in the program memory only partially through the__attribute__((progmem)) extension. By tagging a variable with __attribute__((progmem)), youcan force it to reside in the ROM. However, the compiler support ends at this point. It is yourresponsibility to correctly access the PROGMEM variables. The GCC-AVR provides merely a bunch ofmacros (all defined in the avr\pgmspace.h header file).Listing 2 The mechanism of allocating and accessing data in ROM in qep_port.h#define Q_ROM/* the macro 'PROGMEM' allocates const objects to ROM */PROGMEM/* the macro 'Q_ROM_BYTE' reads a byte from ROM */#define Q_ROM_BYTE(rom_var_) pgm_read_byte_near(&(rom_var_))#include /* C99-standard exact-width integers */#include /* accessing data in the program memory (PROGMEM) */#include "qep.h" /* QEP platform-independent public interface */Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.11 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avrAs shown in Listing 2, the qep_port.h header file defines the mechanism of allocating and accessingbyte-wide data in ROM by means of two macros Q_ROM and Q_ROM_BYTE(), respectively. Subsequently,all QP components (such as QEP, QF, QK, and QS) use the Q_ROM attribute and Q_ROM_BYTE() macro tocorrectly access the data in ROM.3.3 The qf_port.h Header FileThe QF header file for the AVR port with the GNU compiler is located in /ports/avr/vanilla/-gnu/qf_port.h. The most important aspect of the port is the interrupt locking/unlocking policy (QFcritical section).3.3.1 The QF Critical SectionThe AVR microcontrollers do not provide any advanced interrupt prioritization in hardware. In other words,if you enable interrupts at the CPU level (by setting the GIE flag in the SR), the AVR hardware will allowall interrupts, including the interrupt level currently being serviced. For that reason unlocking interruptsinside ISRs is not advisable, because ISRs are typically not reentrant. Consequently, QF services invokedfrom the ISRs (such as QF_tick(), QF_publish(), QActive_postFIFO, etc.) must not inadvertentlyunlock interrupts that are locked in hardware upon the entry to the interrupt processing. All this meansthat QF must use an interrupt locking/unlocking scheme that allows for nesting critical sections. QFprovides such a policy called “saving and restoring interrupt status” and described in Chapter 7 of[PSiCC2].. . .Listing 3 The QF critical section defined in qf_port.h.(1) #define QF_INT_DISABLE() cli()(2) #define QF_INT_ENABLE() sei()/* QF interrupt disable/enable *//* QF critical section entry/exit */(3) #define QF_CRIT_STAT_TYPE uint8_t(4) #define QF_CRIT_ENTRY(stat_) do { \(stat_) = SREG; \cli(); \} while (0)(5) #define QF_CRIT_EXIT(stat_) (SREG = (stat_))(4) #include /* SREG definition */(5) #include /* cli()/sei() */. . .(1) The interrupt-disable macro resolves to the CLI instruction on the AVR(2) The interrupt-enable macro resolves to the SEI instruction on the AVR(3) “saving and restoring interrupt status” interrupt locking policy requires specifying the type of the“interrupt lock key” (see Chapter 7 of [PSiCC2]). Here QF_CRIT_STAT_TYPE is defined as uint8_t(8-bit unsigned integer)(4) The interrupt locking macro QF_CRIT_ENTRY() is first saving the SREG and then disabling interrupts.(Please note that the do {…} while (0) loop around the macro is only necessary for syntacticallycorrect grouping of instructions.) The macro expands to the following assembly code (assuming thatkey_ is allocated in r24):in r24,SREG ; (key_) = SREGCopyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.12 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avrcli; cli();(5) The QF_CRIT_EXIT() macro restores the SREG saved before. The macro expands to the followingassembly code (assuming that key_ is located in r24):out SREG,r24 ; SREG = (key_)Please note the following properties of this QF critical section implementation:• The copying of the SREG is performed outside of critical section, so it does not add to the interrupt latency.The macro expands to very efficient machine code without any function-call overheads.• If the interrupts were unlocked before QF_CRIT_ENTRY(), the QF_CRIT_EXIT() macro will set the I bit inthe SREG. Conversely, if the interrupts are already locked (SREG.7 == 0) before QF_CRIT_ENTRY(), theQF_CRIT_EXIT() macro will not set the the I bit in the SREG, so the interrupts won’t be enabled.Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.13 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr3.4 BSP for AVRThe Board Support Package (BSP) for AVR is very simple. However, there are some important detailsthat you need to pay attention to.3.4.1 Board Initialization and the Timer TickThe BSP is minimal, but generic for most AVR devices. The most important step is initialization of Timer 0to deliver the time tick interrupt at the desired rate (BSP_TICKS_PER_SEC):void BSP_init(void) {DDRD = 0xFF; /* All PORTD pins are outputs for LEDs */PORTD = 0x00; /* trun off all LEDs */}if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */Q_ERROR();}QS_RESET();As you will see in the Timer0 interrupt initialization (in the file isr.c), Timer 0 is initialized with a prescalerof 1/1024. If you choose a different value of the prescaler, you’d need to adjust the OCR0A accordingly.NOTE: At this point the TCCR0A register of the Timer0 is not written yet (should be 0 out of reset), tokeep the Timer0 stopped. This is done to keep the time stamp for QS instrumentation at zero, untilthe interrupts are configured and started.3.4.2 Starting Interrupts in QF_onStartup()QP invokes the QF_onStartup() callback just before starting the event loop inside QF_run(). TheQF_onStartup() function must configure and start the interrupts. In this BSP only the timer tick interruptis started.void QF_onStartup(void) {/* set Timer2 in CTC mode, 1/1024 prescaler, start the timer ticking */TCCR2A = ((1


QDKAVR with Atmel Studiowww.state-machine.com/avr* interrupt is automatically cleard in hardware when the ISR runs.*/#ifdef Q_SPY(2) l_tickTime += (F_CPU / BSP_TICKS_PER_SEC / 1024);#endif(3) QF_TICK(&l_TIMER2_COMPA);}(1) The definition of the interrupt function must begin with the ISR() macro.(2) The update of the local l_tickTime variable is only performed in the SPY build configuration toprovide a 32-bit time stamp for tracing (see also Section 5).(3) The time-tick ISR must invoke QF_TICK(), and can also perform other actions, if necessary. Thefunction QF_TICK() cannot be reentered, that is, it necessarily must run to completion and returnbefore it can be called again. This requirement is automatically fulfilled, because here interrupts arelocked throughout the interrupt processing.3.5 QP Idle Loop Customization in QF_onIdle()This QF port uses the standard QF_run() “vanilla” implementation described in Chapter 7 in the [PSiCC2]book. The standard QF_run() can very easily detect the situation when no events are available, in whichcase QF_run() calls the QF_onIdle() callback. You can use QF_onIdle() to suspended the CPU tosave power, if your CPU supports such a power-saving mode. Please note that QF_onIdle() is calledrepetitively from the event loop whenever the event loop has no more events to process, in which caseonly an interrupt can provide new events. The QF_onIdle() callback is called with interrupts disabled,because the determination of the idle condition might change by any interrupt posting an event.AVR supports several power-saving levels (consult the AVR data sheet for details). The following piece ofcode shows the QF_onIdle() callback that puts AVR into the idle power-saving mode. Please note thatAVR architecture allows for very atomic setting the low-power mode and enabling interrupts at the sametime.Listing 5 QF_onIdle() for the “vanilla” AVR port(1) void QF_onIdle() { /* NOTE: interrupts DISABLED */LED_ON(7);LED_OFF(7);(2) #ifdef Q_SPY /* use the idle cycles for QS transmission */QF_INT_ENABLE();if ((UCSR0A & (1


QDKAVR with Atmel Studiowww.state-machine.com/avr}#elif defined NDEBUG(3) SMCR = (0


QDKAVR with Atmel Studiowww.state-machine.com/avr4 The QK PortThe QP port with the preemptive kernel (QK) is remarkably simple and very similar to the “vanilla” port. Inparticular, the interrupt locking/unlocking policy is the same, and the BSP is identical, except some smalladditions to the ISRs.The DPP example for the QK port is provided in the directory \examples\avr\qk\gnu\dpp-qkstk600-atmega2560.4.1 Compiler and Linker Options UsedThe compiler and linker used in the QK port are identical to those used in the “vanilla” port describedearlier. The only additional consideration is the C-stack size, which in the QK application is generallylarger than in the non-preemptive case of the “vanilla” port.NOTE: The QK port uses the same compiler and linker options as the “vanilla” port. However, due tothe increased stack usage with the preemptive kernel, you might need to adjust the stack sizeparameter.4.2 The qk_port.h Header FileIn the QK port, the only QP component requiring customization is the QK. You configure and customizeQK through the header file qk_port.h, which is located in the QP ports directory\ports\avr\qk\gnu\.4.2.1 The QK Critical SectionThe interrupt locking/unlocking policy in the QK port is the same as in the vanilla port (Section 3.3.1).4.2.2 The QK Interrupt Entry and ExitThe QK port to AVR uses ISRs written in C, declared with the ‘ISR(TIMER2_COMPA_vect) macro, exactlyas described in Section 3.4.3 for the vanilla port. QK, however, requires a specific interrupt entry and exitactions that are performed in the following two QK macros defined in the qk_port.h header file:Listing 6 QK interrupt entry and exit macros defined in the\ports\avr\qk\gnu\qk_port.h header file.(1) #define QK_ISR_ENTRY() (++QK_intNest_)/* QK interrupt entry and exit */(2) #define QK_ISR_EXIT() do { \(3) --QK_intNest_; \(4) if (QK_intNest_ == (uint8_t)0) { \(5) uint8_t p = QK_schedPrio_(); \(6) if (p != (uint8_t)0) { \(7) QK_sched_(p); \} \} \} while (0)#include "qk.h" /* QK platform-independent public interface */Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.17 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr(1) The macro QK_IRQ_ENTRY() is called with interrupts disabled. The macro increments the QKinterrupt nesting level QK_intNest_, which prevents synchronous preemptions inside ISRs.(2) The macro QK_IRQ_EXIT() is called with interrupts disabled, because interrupts are neverunlocked throughout the ISR processing. The do {…} while (0) loop around the macro is thestandard way of syntactically-correct grouping of instructions.(3) The QK interrupt nesting level is reduced to account for leaving one interrupt level.(4) Only when the QK interrupt nesting indicates that the ISR returns to the task level...(5-6) The QK_schedPrio_() function returns the highest priority task ready to run or zero if no task has ahigher priority than the current level.(7) The QK scheduler is invoked to keep launching the high-priority tasks as long as they are above thecurrently serviced priority (see [PSiCC2], Figure 10.2, items (6) through (8)). The QK scheduler isdesigned to be called with with interrupts disabled and also returns with interrupts disabled, althoughit enables interrupts before launching any task.4.3 The QK-specific Interrupt Processing in the BSPAs mentioned at the beginning to the QK port section, the BSP for the QK port is identical as the BSP forthe “vanilla” port, except of adding the QK-specific interrupt entry and exit to each ISR.Listing 7 The time tick ISR in the QK port.(1) ISR(TIMER2_COMPA_vect) {(2) QK_ISR_ENTRY(); /* inform QK about entering the ISR *//* No need to clear the interrupt source since the Timer0 compare* interrupt is automatically cleard in hardware when the ISR runs.*/(3) #ifdef Q_SPY(4) l_tickTime += (F_CPU / BSP_TICKS_PER_SEC / 1024);#endif(5) QF_tick();(6) QK_ISR_EXIT(); /* inform QK about exiting the ISR */}(1) The definition of the interrupt function must begin with the ISR() macro.(2) The QK_ISR_ENTRY() macro informs QK about entering the ISR by incrementing the QK interruptnesting level.(3-4) The update of the local l_tickTime variable is only performed in the SPY build configuration toprovide a 32-bit time stamp for tracing (see also Section 5).(5) The time-tick ISR must invoke QF_tick(), and can also perform other actions, if necessary. Thefunction QF_tick() cannot be reentered, that is, it necessarily must run to completion and returnbefore it can be called again. This requirement is automatically fulfilled, because here interrupts arelocked throughout the interrupt processing.(6) The QK_ISR_EXIT() macro informs QK about exiting the ISR. The macro performs also invokes theQK scheduler to check for asynchronous preemptions.Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.18 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr4.4 Idle Loop Customization in the QK_onIdle()If you’re using the QK preemptive kernel, the idle task is handled differently than in the “vanilla” port. Inthe absence of events to process, the QK invokes the QK_onIdle() callback function to give you anopportunity to perform some processing outside of the time-critical parts of the code or to give you anopportunity to conserve power by putting the CPU in a power-saving mode. In contrast to QF_onIdle(),QK_onIdle() is entered with interrupts already unlocked.void QK_onIdle(void) {QF_INT_DISABLE();LED_ON(7);LED_OFF(7);QF_INT_ENABLE();#ifdef Q_SPY /* use the idle cycles for QS transmission */if ((UCSR0A & (1


QDKAVR with Atmel Studiowww.state-machine.com/avr5 The QS Software Tracing InstrumentationThis QDK demonstrates how to use the QS software tracing instrumentation to generate real-time trace ofa running QP application. Normally, the QS instrumentation is inactive and does not add any overhead toyour application, but you can turn the instrumentation on by defining the Q_SPY macro and recompiling thecode.QS is a software tracing facility built into all QP components and also available to the Application code.QS allows you to gain unprecedented visibility into your application by selectively logging almost allinteresting events occurring within state machines, the framework, the kernel, and your application code.QS software tracing is minimally intrusive, offers precise time-stamping, sophisticated runtime filtering ofevents, and good data compression (see Chapter 11 in PSiCC2 [PSiCC2]).QS can be configured to send the trace data out of the serial port of the target device. On the AVR, QSuses the built-in USART to send the trace data to the host. The STK600 board has the RS232 levelshifteralready installed and available as the serial port (see Figure 1). The QS platform-dependentimplementation is located in the file bsp.c and looks as follows:Listing 8 QSpy implementation to send data out of the USART serial port of the AVR.(1) #ifdef Q_SPY(2) #define QS_BUF_SIZE (256)(3) #define BAUD_RATE 38400(4) static QSTimeCtr l_tickTime;(5) uint8_t QS_onStartup(void const *arg) {(6) static uint8_t qsBuf[QS_BUF_SIZE]; /* buffer for <strong>Quantum</strong> Spy */uint16_t n;(7) QS_initBuf(qsBuf, sizeof(qsBuf));n = BSP_CPU_HZ / 16 / BAUD_RATE - 1; /* Set baud rate */UBRR0H = (uint8_t)(n >> 8);UBRR0L = (uint8_t)n;/* enable transmitter in polled mode, no interrupts */UCSR0B = (0


QDKAVR with Atmel Studiowww.state-machine.com/avrUDR0 = (uint8_t)b; /* stick the byte to the TX UDR */}}/*..........................................................................*//* NOTE: getTime is invoked within a critical section (interrupts disabled) */(10) QSTimeCtr QS_onGetTime(void) {(11) if ((TIFR0 & (1


QDKAVR with Atmel Studiowww.state-machine.com/avr6 Related Documents and ReferencesDocument[PSiCC2] “Practical UML Statecharts in C/C++,Second Edition”, Miro Samek, Newnes, 2008[QP 08] “QP Reference <strong>Manual</strong>”, <strong>Quantum</strong><strong>Leaps</strong>, LLC, 2008[QL AN-Directory 07] “Application Note: QPDirectory Structure”, <strong>Quantum</strong> <strong>Leaps</strong>, LLC, 2007[QL AN-DPP 08] “Application Note: DiningPhilosopher Problem Application”, <strong>Quantum</strong><strong>Leaps</strong>, LLC, 2008[Pardue 05] “C Programming forMicrocontrollers”, Joe Pardue, Smiley Micros,2005“ATmega Data Sheet”, Atmel“GNU AVR C/C++ Compiler: Reference Guide”,GNU Systems[Samek 07a] “Using Low-Power Modes inForeground/Background Systems”, Miro Samek,Embedded System Design, October 2007http://www.state-machine.com/doxygen/qpn/http://www.state-machine.com/doc/AN_DPP.pdfhttp://www.smileymicros.comLocationAvailable from most online book retailers, such asamazon.com. See also: http://www.statemachine.com/psicc2.htmhttp://www.statemachine.com/doc/AN_QP_Directory_Structure.pdfhttp://www.atmel.com/dyn/resources/-prod_documents/doc2514.pdfThe PDF version of this document is included in theGNU Embedded Workbench for AVR.http://www.embedded.com/design/202103425Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.22 of 23


QDKAVR with Atmel Studiowww.state-machine.com/avr7 Contact Information<strong>Quantum</strong> <strong>Leaps</strong>, LLC103 Cobble Ridge DriveChapel Hill, NC 27516USA+1 866 450 LEAP (toll free, USA only)+1 919 869-2998 (FAX)e-mail: info@quantum-leaps.comWEB : http://www.quantum-leaps.comhttp://www.state-machine.com“Practical UMLStatecharts in C/C++,Second Edition:Event DrivenProgramming forEmbedded Systems”,by Miro Samek,Newnes, 2008Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.23 of 23

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!