When I added ‘support for ARM/Kinetis‘ to my bucket list in my Percepio+Trace post, I knew it will not be straight forward. But it was a lot harder than I thought. I had to burn many week-end hours. But finally I have Percepio Trace with FreeRTOS up and running for Kinetis and ARM Cortex-M4 with CodeWarrior for MCU10.2 :-).
The screenshot below shows an application on the Tower Kinetis K60 board:
The ARM Cortex-M4 specific SysTick required some tweaks, plus a re-organization of the include files because of the Processor Expert Low Level Driver concept. Initially the timing was off by a factor of two because of the SysTick scaling factor or 2, and I believe I even found a bug in the trace library (which I have reported). At least with my fix the timing is now shown correctly.
/* * portTicks.h * * Interface header file to the Processor Expert Tick counter. * This file is used to access the interface, especially for performance * counters (e.g. for Percepio Trace). * That way the a module can interface this wrapper header file instead * of one of the standard FreeRTOS header files. * * Created on: 05.07.2012 * Author: Erich Styger */ #ifndef PORTTICKS_H_ #define PORTTICKS_H_ void vOnCounterRestart(void); /* RTOS tick handler */ /* support for trace and access to tick counter */ #include "Inhr1.h" /*! * \brief Return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time * \return Tick counter value. The value is reset at tick interrupt time. * */ portLONG uxGetTickCounterValue(void); #if Inhr1_COUNTER_DIR == DIR_DOWN #define FREERTOS_HWTC_DOWN_COUNTER 1 #define FREERTOS_HWTC_PERIOD Inhr1_PERIOD_TICKS /* counter is decrementing from this value to zero */ #else #define FREERTOS_HWTC_DOWN_COUNTER 0 #define FREERTOS_HWTC_PERIOD Inhr1_PERIOD_TICKS /* counter is incrementing from zero to this value */ #endif /* tick information for Percepio Trace */ /* undefine previous values, where dummy anyway: make sure this header file is included last! */ #undef HWTC_COUNT_DIRECTION #undef HWTC_PERIOD #undef HWTC_DIVISOR #undef HWTC_COUNT #if FREERTOS_HWTC_DOWN_COUNTER #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING #define HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is decrementing from this value to zero */ #else #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING #define HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is incrementing from zero to this value */ #endif #define HWTC_DIVISOR 2 #define HWTC_COUNT (uxGetTickCounterValue()) #endif /* PORTTICKS_H_ */
This file is part of the FreeRTOS component, and is used by the Percepio Trace library. This header file was needed to deal with the way how Processor Expert includes other component header files.
The reason for the change is the way how Processor Expert has organized the header file includes for targets like Kinetis (using Logical Device Drivers): it pretty much includes all component header files in its common files. I don’t understand why they made that change? It caused a lot of headache because the FreeRTOS queue.c is using a private (non void pointer) type to access queues.
Wherever the Percepio Trace library needs access to the tick/timer information, I had to ensure that this new header file was included as last include, as shown below for trcPort.c:
#include "FreeRTOS.h" #include "trcPort.h" #include "trcUser.h" #if 1 /* << EST */ #include "portTicks.h" #endif #if (configUSE_TRACE_FACILITY == 1) #if (INCLUDE_SAVE_TO_FILE == 1) static char* prvFileName = NULL; #endif
With this now I can trace my applications on Kinetis, and given the 128K of RAM on the devices like K60 makes it possible to do long and extended trace runs.