Tutorial: Freedom with FreeRTOS and Kinetis-L

In my earlier tutorials “Enlightning the Freedom KL25Z Board” and “Accelerating the KL25Z Freedom Board” I have not used an RTOS. In this one I’m creating a project from scratch and run it with the open source FreeRTOS operating system, using the FRDM-KL25Z Freedom board. MCU10.3 comes with gcc, and is nicely integrated with Eclipse and CodeWarrior. With this tutorial, it is possible to get an RTOS up and running on a Kinetis device very quickly.

I have a KL25Z which has 128 KByte FLASH and 16 KByte of RAM. What I want to explore is if things could fit as well to the KL0 family where the smallest device has only 8 KByte of FLASH and 1 KByte of RAM. Can this work?

Related Tutorials

I’m using the Eclipse based CodeWarrior for MCU10.3. Things are slightly different for MCU10.2. Where things are different, I have noted this below so you should be able to run that tutorial with MCU10.2 and Kinetis without much changes.

In order not to repeat too many steps, it would be good if you are familiar with the following tutorials, at least on a high level:

Installing more Processor Expert Components

I’m using a Processor Expert component for FreeRTOS which makes things really easy. This and other components are not part of the standard CodeWarrior distribution. I assume know now how to install more components as shown in the previous tutorials mentioned above. If not, here are the quick steps what to do:

  1. Download the latest archive of all available components from GitHub. See this post how to import it.
  2. Unzip the archive to a folder on your hard disk.
  3. Start CodeWarrior and select the menu Processor Expert > Import Package.
  4. Browse to the folder from step 2 and select all *.PEupd files and press ‘Open’ button.

Note: If the new components do not show up in the ‘Component Library’ Processor Expert view, then use the ‘Refresh’ context menu on that view.

Creating the project with the wizard

In the Commander View, I press ‘New MCU project’:

Commander view to create new project

Commander view to create new project

MCU10.2 users: that view does not exist in 10.2. The menu File > New > Bareboard Project does the same.

This opens the New Bareboard Project Wizard. The next steps are pretty obvious:

  1. Give the project a name.
  2. Select the device (MKL25Z128 for the Freedom board).
  3. Select the connection (Open Source SDA for the Freedom board).
  4. Use the default build tools and language settings.
  5. Select Processor Expert for rapid application development

This will create you a project:

Freedom RTOS Project created

Freedom RTOS Project created

Processor Expert Views

If the Processor Expert views are not shown, use the menu Processor Expert > Show View:

Show Processor Expert Views

Show Processor Expert Views

Build the project

Time to build the project. Select the project root folder and use the ‘hammer’ icon to build it:

Build Project

Build Project

This starts code generation followed by compiling and linking the code.

MCU10.2 users: in earlier CodeWarrior versions you might need to generate code first manually. For this select the Processor Expert.pe file in the ‘Project Panel’ view and select ‘Generate Processor Expert code’.

Size Check: Bareboard

We have now created a bareboard (no RTOS yet) application. It is interesting to see what kind of impact (ROM, RAM) the RTOS will have. If you are using gcc and have enabled the code size information (see “Code Size Information with gcc for ARM/Kinetis”):

Bareboard Code Size

Bareboard Code Size

MCU10.2 or non-gcc users: that kind of information is only available with gcc.

Adding the RTOS

To add the RTOS, I use the ‘Components Library’ view:

FreeRTOS in Components Library view

FreeRTOS in Components Library view

The ‘Filter’ text at the bottom shows the selected project. Double clicking on the FreeRTOS component will add it to the project, along with the shared Utility component:

RTOS added

RTOS added

Configuring the RTOS

The component gets created with the defaults, but still you might need to go through the setings to make things matching your needs.

The first thing to check are the Kinetis specific settings: here I make sure I select the core plus the desired interrupt settings (within the boundaries): typically the RTOS runs on the lowest priority, while the ‘Max SysCall Interrupt Priority’ marks the interrupt level where interrupts can use RTOS calls (see FreeRTOS on Cortex).

Kinetis Settings

Kinetis Settings

In above settings I have the ‘SysTick’ enabled, so the RTOS will directly configure the tick timer. Then I only need to specify the tick rate:

FreeRTOS Tick Rate

FreeRTOS Tick Rate

MCU10.2 users only: Enabling Supervisor Call and Pendable Service

MCU10.3 comes with a better RTOS integration for FreeRTOS, where the RTOS can install interrupt vectors. For MCU10.2 it is necessary to set up two vectors: the Supervisor Call and Pendable Service which are used by the RTOS. In the CPU component, both vectors shall be enabled:

Supervisor Call and Pendable Service enabled for K60

Supervisor Call and Pendable Service enabled for K60

After generating code, it will create two hooks in Events.c where I need to add two calls to the RTOS (highlighted):

/*
** ===================================================================
**     Event       :  Cpu_OnSupervisorCall (module Events)
**
**     Component   :  Cpu [MK60N512MD100]
**     Description :
**         This event is called when the Supervisor Call exception had
**         occurred. This event is automatically enabled when the
**          property is set to 'Enabled'.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_OnSupervisorCall(void)
{
  vPortSVCHandler();
}

/*
** ===================================================================
**     Event       :  Cpu_OnPendableService (module Events)
**
**     Component   :  Cpu [MK60N512MD100]
**     Description :
**         This event is called when the Pendable Service exception had
**         occurred. This event is automatically enabled when the
**         <Pendable Service> property is set to 'Enabled'.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_OnPendableService(void)
{
  vPortPendSVHandler();
}

Size Check: Added the RTOS

Generate Code/Build again, and we have the normal ANSI start-up code with the RTOS added. Time for a quick size check:

Application with RTOS

Application with RTOS

So this means for the RTOS alone roughly 3 KByte for Code and 2 KByte of RAM with the default configuration. We will look into ways how to get that reduced later.

Application main()

Processor Expert has created for me the following main() code inside ProcessorExpert.c file:

int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  PE_low_level_init();
  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */
  /* For example: for(;;) { } */

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;){}
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

With PE_low_level_init() it initializes all drivers, and the macro PEX_RTOS_START() starts the scheduler.

Adding LEDs

I’m reusing what I have created in “Tutorial: Enlightening the Freedom KL25Z Board”and add the components for the RGB LED to my project. For this I can copy-paste the components from one project to the other. To keep things simple, I just use the red and green LED.

MCU10.2 users: copy-paste is not supported, but you can drag&drop the components.

Added Red and Green LEDs

Added Red and Green LEDs

Tasks to Toggle LED

Next step is to add tasks which toggle my LEDs. A task is nothing else than a function which is known to the RTOS that it is a task (we come to that later). To toggle an LED in a task is a simple endless loop in a function. I add the code below to my ProcessorExpert.c file (but it could be in any other source file too):

static portTASK_FUNCTION(Task1, pvParameters) {
  (void)pvParameters; /* parameter not used */
  for(;;) {
    LED1_Neg();
    FRTOS1_vTaskDelay(1000/portTICK_RATE_MS);
  }
}

Don’t be confused by the portTASK_FUNCTION() macro: it is a way how in FreeRTOS task functions are defined to hide machine specific information. The macro is implemented as

#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)

for ARM/Kinetis. If you want, you could write a task as well as:

static void Task1(void *pvParameters) {
  (void)pvParameters; /* parameter not used */
  for(;;) {
    LED1_Neg();
    FRTOS1_vTaskDelay(1000/portTICK_RATE_MS);
  }
}

vTaskDelay() will suspend the task for the given amount of milliseconds (1000 milliseconds in above case).

So I create two such tasks, one for each LED.

Creating Tasks

Tasks needs to be created too, and this is accomplished using the xTaskCreate() API call:

if (FRTOS1_xTaskCreate(
    Task1,  /* pointer to the task */
    (signed portCHAR *)"Task1", /* task name for kernel awareness debugging */
    configMINIMAL_STACK_SIZE, /* task stack size */
    (void*)NULL, /* optional task startup argument */
    tskIDLE_PRIORITY,  /* initial priority */
    (xTaskHandle*)NULL /* optional task handle to create */
   ) != pdPASS)
{
   for(;;){}; /* Out of heap memory? */
}

The first argument is the task function, followed by the task name. Additionally the task stack size, the argument (pvParameters in the task), the initial priority, and an optional task handle pointer needs to be specified.

xTaskCreate() has a return value which should be checked. The most common cause for a task creation failure is running out of heap. FreeRTOS is using a shared heap to for all the task stacks and the dynamic kernel data structure. With this in mind, we can tune our system a bit….

Reducing the Footprint for KL0

As stated above: FreeRTOS runs easily on a KL25Z. But what if I only have 8 KByte of FLASH and 1 KByte of RAM as on the smallest Kinetis-KL0 listed on the Freescale web site, like the KL0 family?

As FreeRTOS is using its own heap, we can reduce the one set up in the Processor Expert CPU component Build options tab. And as each RTOS task is having a stack in the heap, I can reduce the stack size too:

CPU stack size in CPU component and build options

CPU stack size in CPU component and build options

OK, now time to look at the RTOS configuration itself. The RTOS configuration provides several opportunities for footprint reduction:

Reduced RTOS Footprint

Reduced RTOS Footprint

  • The Task Name Length is used for debugging only. I don’t need it.
  • 40 for Minimal Stack Size should be enough (this is equivalent to 40*4=120 Bytes).  per task. I just need to keep in mind that there is no separate interrupt stack.
  • UPDATE: The tasks are using the PSP (Process Stack Pointer) with the stack space assigned to the task. The interrupts continue to use the MSP (Main Stack Pointer) which is active at startup and main() time: So the interrupts do *not* share the task stack space.
  • I only have 2 priorities in my application, so I can reduce the number of Priorities.
  • I’m not planning to use Queue and Mutex, so I can turn that off.
  • I only allocate memory, so Memory Allocation Scheme 1 is fine.
  • Each Task plus the IDLE task needs 120 bytes of stack, so 750 bytes Heap Size sounds good.

Now time to generate code and link the application. Now I have added the RTOS and my application (two tasks flashing each an LED):

Code and Data Size for RTOS plus Application

Code and Data Size for RTOS plus Application

That’s not bad: 6 KByte for Code plus 1 KByte of RAM :-).

Optimize for Size

So far I have compiled the code with -O0 (no optimization). An easy way to shrink the code size is to optimize the code for size. For this, there is an option in the ARM gcc compiler:

GNU gcc compiler optimization level

GNU gcc compiler optimization level

Note: The RTOS port is very sensitive to compiler optimizations, because the stack frame might be different. The FreeRTOS Processor Expert component V1.200 or later supports automatic detection of gcc compiler optimization level.

MCU10.2 and non-gcc Kinetis/ARM compiler users: the compiler optimization level needs to be configured in the FreeRTOS component (Compiler Optimization Level property).

And this has a very positive impact on the code size:

Application optimized for code size

Application optimized for code size

So I only need 5 KByte of FLASH with 1 KByte of RAM :-). So with this I know I can fit it into a very small device. Of course for the KL25Z I can go ahead and give it more room with more heap and stack size if I want and need it.

Summary

Unlike with many RTOS, it is easily possible to fit FreeRTOS into any of the currently defined Kinetis devices. Of course an 8 KByte FLASH/1 KByte RAM device is not necessarily something which needs an RTOS, but it is good to know that FreeRTOS is tiny and efficient enough to even fit that category. With FreeRTOS I have an ideal RTOS for all the devices I use, and is very scalable: from the tiny 8bit S08, to the 16bit S12, and up to all 32bit ColdFire and Kinetis high-end devices, and down again to the tiny 32bit Kinetis-L K0 one. Not to forget all the other processors which are supported by this open source project.

The sources of this project are available here.

Happy Freedom 🙂

Advertisements

122 thoughts on “Tutorial: Freedom with FreeRTOS and Kinetis-L

  1. Pingback: Tutorial: Touching the Freedom KL25Z Board | MCU on Eclipse

  2. Pingback: Forcing/Checking Kinetis Compiler Optimization Level | MCU on Eclipse

  3. Hey Erich,
    I am new in the Field of freeRTOS and Processor expert. This tutorial helped me a lot to understand freeRTOS and PE. I tried to get this example running on a Kinetis TWR-K60N512. But unfortunetly it doesn’t work. I did everything as you explained, well I changed the Port Pins for the LEDs to PORT A PIN11 and PORT A PIN28. Do i have to consider special settings for the Heap or Stack Size with the Board I am using?

    Anothor minor issue is, that i don’t see the code size displayed in teh Console. How can I change the settings?

    regards, Manuel

    Like

  4. Hello,
    Yes I am using 10.3 Beta. Thanks for the link! Now I am able to see the Code Size, which is preety nice.
    I would really appreciate it, if you would do that. Do you have any hint what i have could done wrong?

    Would you recommend to start the program in debug or in Run Mode?

    thanks

    Like

  5. Hi Erich,
    I cannot get the component to load properly for the KL25Z. I get an error with TickLDD. It reports “Error in the inherited component settings” and fails to generate code. Would you be able to offer any suggestions on what might be wrong?

    Thanks

    Like

  6. Pingback: Tutorial: IAR + FreeRTOS + Freedom Board | MCU on Eclipse

  7. Hi,
    Thanks for those informations but am using eclipse C/C++ to programm my STM32F4, so i want to know if you have this tutorial using eclipse C/C++.
    Thanks

    Like

  8. Hi. Erich.
    I’m having this error: http://i.imgur.com/BzOfqBE.png

    Generator: FAILURE: at line 122: Symbol is already defined and cannot be redefined with new value “ivINT_PendableSrvReq” (file: Drivers\sw\RTOSAdaptor\FreeRTOS_RTOSAdaptor.prg)

    Generator: FAILURE: at line 122: Symbol is already defined and cannot be redefined with new value “ivINT_SVCall” (file: Drivers\sw\RTOSAdaptor\FreeRTOS_RTOSAdaptor.prg)

    Following all the steps and importing the project (http://www.steinerberg.com/EmbeddedComponents/Examples/FreedomBoard/Freedom_RTOS.zip). In both cases I’ve had the same error.

    Like

  9. Hello Erich,

    For some reason, my Counter Frequency is returning an error:

    Do you know what may be causing it? I am using MCU 10.4.

    Thanks,
    Thiago

    Like

    • Hello Thiago,
      Which CPU are you using?
      your screenshot at

      shows ‘list of values’. Can you change it to ‘fixed value’?
      Interestingly, in my MCU10.4 I only have ‘fixed value’.

      I hope this helps.

      Like

      • I’ve changed it to Fixed but the field was still blank. Then I double clicked on the 20. MHz value and it worked.

        Im using the FRDM-KL25Z (Freedom Board).

        Thanks

        Like

      • Hi Thiago,
        ok, I see now what you were running into. In MCU10.3 it has automatically assigned the tick counter frequency, but in 10.4 an additional step is needed. I have extended the article to cover this. Many thanks for pointing this out!

        Like

  10. Hi
    I am using CodeWarrior MCU v10.3 with PE plugin. I have the following difficulty

    I build my project for FRDM-KL25Z on code warrior, I can build it successfully but I am not able to run the output file (.hex) downloaded from flash directory to FRDM-KL25Z drive. Sometimes it works as expected, but many times i am not able to see it running (LED blinking etc).

    At times when i paste the output file 2nd time it starts running ( might sound wierd but it does happen). Many times SDA LED gives series of blinks for 2 seconds repetitively.

    I dont what is going wrong.

    Best Regards
    Gauti

    Like

    • Hello,
      could you try if the same thing happens if you copy the file from a DOS shell/prompt (not with the Windows Explorer)?
      It could be that your Explorer is doing strange things (if you are using Windows).
      I hope this helps.

      Like

      • Hi Erich
        I tried on DOS shell and observed a similar behavior. I am not sure, bit can this be due to .SDA drivers?

        Like

      • I have seen failures of the OpenSDA MSD bootloader because of the host writing things to the MSD device in an unexpected fashion. For example this is causing problems if using a Mac computer (because the Mac tries to write other stuff to the MSD device). Or if you are using a file manager extension (like ‘File Commander’ or similar): they write as well in an unsupported fashion to the MSD device. So what else can write to your device? Maybe your virus scanner? Can you disable it?

        Like

  11. Thanks Erich…..
    The problem is, if i try to download a modified application (newer file also with the same name), the overwriting of the file is not consistent or the bootloader does’nt use the newer file.
    Whereas if an application with a different name is downloaded, it works as expected.

    Like

    • Hi Gauti,
      is ‘different application’ a really different file, or just the same application with a different file name? I’m thinking that your host system might somehow cache the application file? Or maybe you have some ‘USB memory stick accelerator’ or similar installed? What version of Windows are you using? Win7? Win8?

      Like

      • Hi Erich…
        I was using Win Xp with Copy accelerator (Teracopy) to download the file.
        ‘different application’ is a new file having new project (application)
        n sorry for very late reply..

        BR
        Gauti

        Like

  12. Pingback: Hacking the Heating System for Cooling – Geothermal Drilling with extra Benefits | MCU on Eclipse

  13. another awesome article thanks!
    Question about FreeRTOS, I can’t seem to totally eliminate the CommandInterpreter… for small projects it seems like this will save code. I did delete the generated files and it compiled OK… just wondering if that’s acceptable?

    Like

    • Hi Marc,
      and has your code size reduced? The linker should remove all functions which are not used anyway, so I think you will not see any savings? Yes, I could make a setting not to generate the files. That would save some disk space for the project, and compilation time.

      Like

    • Hi Marc,
      I have implemented now a setting in the FreeRTOS properties, so you can completely disable the command interpreter. As expected, this had no impact on the code size. Anyway I think a good thing, as two source files are not generated if not needed.

      Like

      • i have to leave this project for a few days, i just got it to actually fit… i had noticed two functions from the command interpreter being compiled but at the time it didn’t fit so I couldn’t check the impact on overall code size… I’ll get back to it and let you know before updating my beans. thanks!

        Like

  14. Problems with NVIC in CW10.4 and PE Component FreeRTOS:

    I developed a few smaller applications using the PE FreeRTOS Component of Erich in CW10.2 on a K60 Towerboard. A few days ago I upgraded to CW10.4 and run into trouble when I tried to run my FreeRTOS based applications. The applications are crashing to the ‘CPU Interrupt’. They always crash at the following function:

    void vPortYieldFromISR(void) {
    /* Set a PendSV to request a context switch. */
    *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET_BIT;
    /* Barriers are normally not required but do ensure the code is completely
    within the specified behaviour for the architecture. */
    __asm volatile( “dsb” );
    __asm volatile( “isb” );
    }
    However it seems to me they crash not always when this function is called. Sometimes it works – sometimes it doesn’t. Any ideas?

    Best Regards
    Markus

    Like

      • I am almost sure it is a problem with the NVIC. Is it really OK not to configure the pendable and the SVC interrupt in the PE Component of the processor anymore?

        Like

      • I’m on MCU 10.4 now. I know that 10.3 changed things, and if I remember right in 10.2 it was needed to set it up in the processor. I’ll verify it with 10.4, and then I see if I can download 10.2, just in case.

        Like

      • BTW I just discovered that the demo for FreeRTOS and gcc does not work with version 7.5.0 anymore. During the project build it complains about a lot of the Queue Sets items.

        Regards
        Markus

        Like

      • I think the problem with the 7.5.0 came when you are loading a project into CW10.4 that was setup with the 7.4.2 before. If you changed in the meantime the component to 7.5.0. you get messages from you old FreeRTOS PE component like:

        ERROR: at line 149: Unknown macro: “useQueueSets” (file: Beans\FreeRTOS\FreeRTOS.chg)

        I disabled the original 7.4.2 component from your project (that is displayed as 7.5.0 in the RTOS Version field within the component inspector) and load the new 7.5.0 component to the project. After that everything works fine.
        However that reminds me to a problem I saw with many projects that I transfered from CW10.2 to CW10.4. A lot of things has to be adjusted manually in the PE components. Sometimes I gave up and did the whole thing new because I was not able to understand the error messages. Hopefully CW10.5 and onwards will be really upward compatible.

        Like

      • I see. The thing is this: the new 7.5.0 component has more fields/different attributes. So if you load my 7.5.0 project into your system which has 7.4.2, then error very likely will show up.
        Unless I’m getting it wrong. So things are compatible to the new version, but not necessarily backward.
        Anyway, I have tried the 7.5.0 FreeRTOS with MCU10.2 on a K60N512 (non-gcc with the Freescale compiler), and that showed a little problem in the assembly code. So there has been at least a small problem, so that investigation was worthwile to do. But anyway, as the Freescale ARM compiler is EOL and the future is gcc, I do not pay attention to that legacy compiler.

        Like

    • So I investigated further and discovered that I get a bus fault when executing the command:
      *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET_BIT;
      in the ISR vPortYieldFromISR().
      This ISR is called by portYIELD_WITHIN_API() and again called by xQueueGenericReceive() – that leads in my application to a blocked tasked that is the reason the scheduler is called.

      I am absolutly no expert for the NVIC. However from the ARM documentation web site I got the following sentence:
      You can only fully access the NVIC from privileged mode, but you can cause interrupts to enter a pending state in user mode if you enable the Configuration Control Register. Any other user mode access causes a bus fault.

      Could this be a hint for the source of my crashed application?

      Like

      • Is this with one of my applications on GitHub? There might be many reasons for a bus fault. One of it is if the interrupt priorities are set wrong. Are you callin RTOS functions from interrupt service routines? You are using the K60, right? I admit I have used more the KL25Z recently, but I’m not aware of any problems with my K60 applications. If you want and can, you might send me your application to the email address mentioned in the About page of this blog, and I should be able to have a look at tomorrow.

        Like

      • Dear Erich,

        I just send the whole project including some comments to your personal email address. I also switched into German to make it easier for probably both of us. For sure the solution will be posted here in English again 🙂

        Markus

        Like

      • Ok, it looks like the RTOS was running as M4, instead of M4F with floating point enabled. The thing is that if you run tasks using hardware floating point, then the RTOS needs to be aware of it because usage of the floating point registers changes the stack frames.

        Like

      • Hi Erich,

        thank you very much for your ‘remote debugging’ from Texas. It is exactly as your described. I had configured in the ‘New Project’ wizard to use the FPU of the K60F. However in the RTOS component I disabled it and choose a M4 core.
        Stupid mistake from my side.

        Best Regards
        Markus

        Like

  15. Another way to save a little bit of code space and RAM space (a few bytes each), but a lot of run-time heap space, is to:

    #define portBASE_TYPE char

    in portmacro.h. Normally it’s ‘long’ for the ARM port. This probably slows the code down a bit, that’s the tradeoff. You also need to check ‘char is signed’ under settings->C compiler-> miscellaneous.
    I had to change the properties of portmacro.h to ‘read only’ to get the change to stick – the FreeRTOS PE component regenerates that file even if you disable generating code in it’s component setting. It would be nice, if possible, to allow changing portBASE_TYPE from the PE component, maybe a good use for the ‘advanced’ or ‘expert’ setting…?

    Like

    • See http://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html about this topic:

      portBASE_TYPE
      This is defined to be the most efficient, natural, type for the architecture. For example, on a 32-bit architecture portBASE_TYPE will be defined to be a 32-bit type. On a 16-bit architecture portBASE_TYPE will be defined to be a 16-bit type. If portBASE_TYPE is define to char then particular care must be taken to ensure signed chars are used for function return values that can be negative to indicate an error.

      How much have you saved with this? I’m wondering because this type is mostly used for return codes, and only few times in data structures/etc. And there is still the alignment in structures. And I see that then the number of items in queues would be limited to 256 too. While I could easily add a property where you can define a char as portBASE_TYPE, I think this might create more harm than benefits?

      Like

      • Yes and in http://www.freertos.org/FAQMem.html


        Scheduler Itself 236 bytes (can easily be reduced by using smaller data types).

        I’m still investigating exactly how much I save. So far (on MKL04Z16VFK4) it seems about 16-20 bytes each of code and data (small program with 4 tasks) of static space. But I think it might be using more of the GCC stack (launching FreeRTOS from main()) (not sure yet), but what’s most noticeable is that it’s using much less of the FreeRTOS heap, which on the KL02 is precious. I would also comment that (1) you can also define portBASE_TYPE as ‘short’ if you need e.g. >256 queue entries etc., and (2) so far, I have yet to use queues anywhere near 256 entries with these small processors (including a product with a bunch of RF packet processing), that would basically consume all the RAM in some of them! So I think it could be a good option for people (but, that’s why I thought, maybe expose only in the ‘expert’ or ‘advanced’ modes…?).

        Changing subject, any thoughts on why portmacro.h (and some other files, I suspect) are regenerated even if the component is ‘frozen’?

        Like

      • About the code generation: indeed, that ‘do not generated code’ only works for the main module files (FRTOS1.c and FRTOS1.h). I have reported this now to Freescale, maybe there is something wrong how I generate/copy the other files, I don’t know. Thanks for detecting this!

        Like

      • yes, I regularly update from github sans .PEupd, now that I read your get-started guide 🙂 But I’m battling something odd… seems the MSP (SP_MAIN) stack is not reserved, I see some of my strings from my app are copied there… trying to figure out what’s going on!

        Like

  16. Hi, If I’ve got two task (e.g. toogle led red and green), how can I set up what is the task that should be executed first of all?

    thanks

    Like

    • Hi Jose,
      different ways to do this:
      a) When you create all tasks before you start the scheduler, assign that task you want to start first the highest priority. The scheduler will always run the task with the highest priority first.
      b) before you start the scheduler, just create one task. This task then will create all the other tasks (you can create tasks inside a task). That way you know which task is started first (as a startup task).

      I hope this helps,
      Erich

      Like

  17. if some task has a very large code and either this task exceeds one period tick or the tick interrupts the task, what happens when the task returns to the running state?

    Like

    • Hi Jose,
      that depends on the task priority. The tick interrupt happens, and the code executes the tick interrupt service routine. Inside the tick service routine, the RTOS checks if there are any pending tasks with higher priorities. If so, it will switch context to the higher priority task. If your task is the one with the highest priority, or all others are blocked or waiting, then your task will execute again. There are differences if you are in pre-emptive mode or not, or if there are tasks with the same priority. But your task will not ‘notice’ that something happened during the tick interrupt.

      Like

  18. Hi ,

    I m new to this, i have downloaded the source code and compiled , i getting error PE_LDD_COMPONENT_RTOSTICKLDD1_ID undeclared , what might be wrong , please help me to sort it out

    Like

      • yes i have installed processor expert component and generated code with pe also , i using 10.5 version

        Like

      • Got it, thank you!

        It looks like the project still had some artifacts using the Tick Timer LDD. That could happen if you changed the settings from using a dedicated Tick Timer, and then switching to use directly the SysTick. In that case, Processor Expert might not detect that the RTOSTICKLDD is not used any more, and it is not removed.

        Steps to fix it:
        – delete the Generated_Code folder
        – remove #include “RTOSTICKLDD1.h”
        from Events.h and Processor Expert.c
        – generate code again
        – build
        Now everything should be fine.
        I have fixed two warnings in the code of ProcessorExpert.c and sent the project back to you. Hopefully that resolves the problems.

        Like

  19. Hi ,
    1) i have uart driver generated by PE, i need to know what modification should i do in this driver ,so that i can use it with freertos,

    2) In comment it mentioned {Default RTOS Adapter} in uart driver what it means.
    Ex
    /* {Default RTOS Adapter} Critical section begin, general PE function is used */
    EnterCritical();
    DeviceDataPrv->InpDataPtr = (uint8_t*)BufferPtr; /* Store a pointer to the input data. */
    DeviceDataPrv->InpDataNumReq = Size; /* Store a number of characters to be received. */
    DeviceDataPrv->InpRecvDataNum = 0x00U; /* Set number of received characters to zero. */
    /* {Default RTOS Adapter} Critical section end, general PE function is used */
    ExitCritical();

    Like

    • By default, you do not need to use any modification in the driver at all to use it with FreeRTOS.
      if you are using the serial port with one task only, then nothing to do neither.
      If you are accessing the serial port from several tasks, then you need to either a) use a semaphore with an access routine or b) use a queue as interprocess communication or c) use my Shell component which has a setting to use an RTOS (in that case a semaphore is implemented to allow mutual access).
      I hope this helps?
      Bottom line is that you do not need to change uart driver generated by PE.

      Like

  20. Hi erich
    I’am sorry if I disturb you on a sunday.
    I’am trying to run the freeRTOS (version V8.0.1) on my board a FDRM K64F, I’am using Code
    Warrior MCU 10.6 so I did not enable “Supervisor Call and Pendable Service”, when I upload the code on the board the functions PE_low_level_init(); and FRTOS1_xTaskCreate(); seems to work both.
    But when the program enter in the macro PEX_RTOS_START(); the board is like running an infinite loop and no leds are blinking.

    If you could help me, I would be grateful
    Mathieu

    Like

    • That’s what Sundays are for: to deal with problems ;-). I’m not sure what you mean with that you did not enable the supervisor calls and pendable services? They are needed (and enabled) in the PEX_RTOS_START() anyway. Maybe you can send me your project to the email address listed on the about page of this blog? No promise, but I should be able to have a quick look.

      Like

  21. Silly me, I looked to your article “Nordic Semiconductor nRF24L01+ with the Freescale FRDM-K64F Board”, and i setted up the total heap size to 20000 and enabled the floating point support (ARM family : M4F), now the application runs perfectly.

    Thanks for your website and sorry if i made you waste your time -_-

    Like

  22. Hi, Thank you for the great tutorial. My project requires both FreeRTOS and SPI (Interrupt mode) communication. I’m using processor export components for both. However, after adding the FreeRTOS component, SPI (Master mode) send functions (SendChar, SendBlock) fails to generate any clock or MOSI signal. I’ve unchecked “disable interrupts on startup” in FreeRTOS properties but that didn’t help. Changing the SPI to Polling mode solves this problem, but I need interrupt based SPI for my project. I have also tried writing directly to SPI’s Data register (SPIx_DL), which generated the Clock and MOSI signal properly, but no lock with the interrupt based PE functions.

    I’m using a Cortex M0 MKL26Z128VF4, and CodeWarrio for MCU 10.6, Processor Expert for MCU 10.6

    Like

    • Hello,
      thanks :-).
      Are you using the SPI *before* starting the scheduler/RTOS? Interrupts are disabled until the RTOS gets started, so this is maybe your problem?
      I’m using SPI with interrupts in many of my projects with FreeRTOS, but I try to use it from a task context, and not before starting the tasks.

      Like

      • Thank you Erich that was exactly what I was doing. I also tested running my code inside a task before, but there were other memory problems that I hadn’t caught.
        Your FreeRTOS component is very useful.

        Like

  23. Erich, your tutorials are great, keep them coming.
    I have 2 questions on the freeRTOS component, and components in general:
    I’m using CW10.6 and the plugins from the master.zip file (the git files failed for invalid LZH headers) .

    1) The functions to put the hooks in events.c Cpu_OnSupervisorCall() and Cpu_OnPendableService do not exist. However the hooks that you placed into them are installed in the vector table. Is this normal for freertosV8.0.1?

    2) How does one update the RTOS? The component is for 8.0.1, the latest release is currently 8.1.2.

    Thanks,
    Aaron

    Like

  24. Hi Erich,

    Thanks to your article I could run a task! 😉 I did exactly as described in the article with the FRDM-KL25Z, but instead of using the LED component, I used bitIO. So far all went well. But then I tried to run two tasks, each should blinks its own LED. I started the scheduler after the creation of tasks in main and then… nothing happened … No LED blinked! Do you have any advice?

    Thanks,

    Matheus

    Like

    • Hi Matheus,
      using the BitIO is fine too. Have you debugged your project? Run it with the debugger, then halt/suspend the target. I guess it will stay in the Events.c in the ‘out of heap memory’ hook, if you have not enough heap allocated in the FreeRTOS component. How much heap do you have assigned? Increase that value, and then it should be ok. I hope this helps.

      Like

      • I forgot about how much memory was before, but with 800 of heap and stack to 100 for tasks, worked well! I dont see any method like “out of heap memory” in events.c. But I found FRTOS1_vApplicationStackOverflowHook! I dont tested the halt debug to see!
        Thanks, your articles help me a lot and saved me much time!

        Like

  25. Hi,
    Great post.

    I have one problem, though.
    I have 2 tasks just like in your example. each of the them blinks on its own, but when I try to make them both work, I see no blink at all, meaning that no task has started.

    i am using KDS version 1.1.1

    thanks!

    Like

    • Have you debugged your project with the debugger? Run the application, then halt the target with the debugger. Most likely you run into the problem that you do not have enough RTOS heap allocated: increase the heap size in the RTOS settings.

      Like

  26. Hello Erich,

    I have a project of mine which was tested previously. Its working fine. Into that project I have added freeRTOS component. After that code is getting blocked at spi interrupt. I am new to freeRTOS. Can you guess any reasons??

    regards,
    Durgesh

    Like

    • Hi Durgesh,
      are you using the SPI *before* starting the RTOS scheduler? If yes, then this is likely your problem, as before starting the RTOS the interrupts are disabled.
      If you do not have an RTOS added, then interrupts will be enabled in main(). So yes, if this is the case, then I recommend that you use the SPI from a task (this is what I do).
      I hope this helps,
      Erich

      Like

      • Hello erich, As you mentioned I have created a task in which I am using the spi. But control is going into Debug_Hault at vTaskStartScheduler()

        void App_Run(void)
        {
        xTaskHandle xHandle;

        if(xTaskCreate( appRun, “Task”, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle)!=pdPASS)
        {
        while(1);
        }

        vTaskStartScheduler();
        for(;;);
        }

        void appRun(void* ptr)
        {
        masterDevData = SM0_Init(&deviceData_SPI0);
        //spi_send_block function
        }

        Like

      • Hello Erich,
        Thanks for your quick reply.
        Now the problem is solved. Previously I have declared local variables in the task with greater size than stack size of the task. Now I have made them as global variables.

        regards,
        Durgesh

        Like

  27. Hi Erich,

    I am currently trying to run FreeRTOS on Kinetis MK21FN1M0. I was able to create two LED blinking tasks according to your tutorial. But when I try to execute my program, it fails with a Hard Fault Exception. Have you ever faced this kind of problem? I also tried to increase Stack and Heap sizes but did not get the issue fixed.

    Best regards,
    Philipp

    Like

  28. Hi Erich,
    I’m trying to get FreeRTOS 8.2.0 working on an already existing project based on Kinetis K20DX256VLH7. I’m using Codewarrior 10.6 and all the latest updates. I stripped down the main to have just the PE_init done and FreeRTOS started, with just two dummy tasks containing a vTaskDelay(1000/portTICK_RATE_MS); in their endless for loop. I can see the RTOS starting fine, I see the two tasks being launched and suspended on the delay. But as soon as the tick interrupt is triggered after the second vTaskDelay, I see the tick count increasing to 1 and then the ISR exits with a call to a null pointer, therefore the application hangs on a hard fault exception.
    I don’t understand why the first time the vPortTickHandler is called it returns with a call to a null address:
    /*———————————————————–*/
    vPortTickHandler:
    /* Compiler optimization level 0 */
    pop {lr,r3} /* remove stacked registers from the caller routine */
    /* If using preemption, also force a context switch. */
    bl vPortYieldFromISR
    bl vPortSetInterruptMask /* disable interrupts */
    bl xTaskIncrementTick /* increment tick count, might schedule a task */
    bl vPortClearInterruptMask /* enable interrupts again */
    /* Compiler optimization level 0 */
    pop {lr,r4} /* start exit sequence from interrupt: r4 and lr where pushed in the ISR */
    bx lr
    nop
    /*———————————————————–*/
    The last bx lr tries to go to a null address.
    Can you please help me in understanding what I did wrong? I tried to follow all the hints and FAQs found online but I cannot understand what I did wrong here.
    Thanks and keep up the good work!

    Like

    • Hi Matteo,
      I don’t see what could be wrong. But could you increase the minimal stack size of each task (stack size in the FreeRTOS properties) to see if this has an impact.
      Otherwise, send me your project at the email address mentioned on the About page of this blog and I try to have a look.

      Erich

      Like

      • Hi Erich,
        thank you for the reply. I have already tried to increase the minimal stack but it is not useful. The task just contain a simple delay so they don’t really use it. There must be a configuration issue that I’m missing or a problem in the code generation since this project was originally created with CW 10.3 and recently ported to V.10.6. I will send you an e-mail with the project I’m working on. If I get it working I can clean it up and set up the RTOS with proper tasks and all.
        Thanks.

        Like

      • Hi Matteo,
        thank you, I have received your project. I did not see anything wrong. I guess to find the problem, I would need the hardware. You might try to nail down from where the hard fault comes from, with a divide and conquer method: try disabling things until it does not happen any more. I suspect that there might be some dangling pointer or similar. Again, to help further I would need to be able to debug it.

        Like

      • Hi Erich,
        thank you for the reply. I already installed the hard fault component to help track down the problem, which I narrowed down to a call to a null pointer in the vPortTickHandler in the very last assembly instruction: bx lr. However I do not see what could be causing this, since it happens on the very first tick interrupt. My project uses the Freescale legacy ARM compiler, therefore I see the FreeRTOS port make use of a vPortTickHandler assembly routine. Was this tested?
        I have disabled everything and it still happens, so it looks indeed like a configuration problem or a bug in the code generation. I have tried to create another project not using the legacy compiler and it runs fine. Looks like I have the problem when the vPortTickHandler assembly routine is used.

        Like

      • Hi Matteo,
        I have not used the Freescale legacy compiler for a very, very long time. So I think really the problem is with that compiler, as it was very hard to work with that one, because depending on the optimization settings, the stack frame was built up completely different. So this had been tested maybe two years ago, and I admit that now there could be something which has broken it 😦
        There is a a setting in the FreeRTOS component for the optimization level (FreeRTOS component > Scheduler > Kinetis > Compiler Optimization Level).
        Can you check if that setting helps you? If not, I need to investigate this issue myself further.

        Like

      • Hi Erich,
        I have checked that setting and it is indeed set to 0. It matches the setting in the FreeRTOS component. I cannot change it because the FreeRTOS component was built with optimization level 0 (this is also mentioned in the assembly ISR tick routine). Changing it from 0 will trigger a #error during code generation.

        Like

  29. Hi again Erich,
    I have studied a bit how the ARM Cortex M4 core deals with interrupts and found out that the return address from the tick ISR was not handled correctly by the generated code. The LR register content was being loaded with other data and the return address from the ISR was not saved. Therefore I corrected the assembly ISR tick routine as follows:

    /*———————————————————–*/
    vPortTickHandler:
    /* Compiler optimization level 0 */
    /*pop {lr,r3} remove stacked registers from the caller routine */
    push {lr}
    /* If using preemption, also force a context switch. */
    bl vPortYieldFromISR
    bl vPortSetInterruptMask /* disable interrupts */
    bl xTaskIncrementTick /* increment tick count, might schedule a task */
    bl vPortClearInterruptMask /* enable interrupts again */
    /* Compiler optimization level 0 */
    /*pop {lr,r4} start exit sequence from interrupt: r4 and lr where pushed in the ISR */
    pop {lr}
    bx lr
    nop
    /*———————————————————–*/

    Now the FreeRTOS runs with no problems in my demo application. I will now adapt the whole application to make use of the FreeRTOS features and APIs. I have new to FreeRTOS so I need sometime to find out its features and APIs. Hope this helps someone else.
    Thanks anyway for your help.

    Like

  30. Hi Erich

    Great work (like always).

    I have some doubt (I did not use cortex core so long..)

    1. Why you have wrote “I just need to keep in mind that there is no separate interrupt stack.” (this is what I remember from using cortexM3, however I am using CortexM0+).
    As far as I remember IRQ use stack what is default after reset what in fact is separate stack from task stack

    2. Does FreeRtos port use t ostack modes: MSP and PSP (CONTROL register)? I follow your guide, debugging and seems not, but I want to be sure is this desired feature? (I do not remember, but I think on Coretex M3 port tasks uses PSP )

    Best Regards
    /Greg

    Like

    • Hi Greg,
      I was wrong in my thinking (not sure why), so I have to correct this. The FreeRTOS port for Cortex-M0+ and Cortex-M4(F) uses the MSP (Main Stack Pointer) during startup and main(). The task stacks are in the ‘heap’ (if they are allocated through the heap manager which is usually the case and are using the PSP (Process Stack Pointer). While the tasks are running, interrupts continue to use the MSP (main stack). That means that the interrupts are *not* using the process/task stack pointer.
      I hope this helps.

      Like

      • Hi Greg,
        hmmmm, looks like what I said is not correct: it is possible that the stack of main() is used for the interrupts, and interrupts are not on the task stack (which are allocated in the heap). I think I need to double check that, sorry for the confusion 😦
        Erich

        Like

      • Hi Greg,
        my initial statement about the stacks was misleading: on ARM Cortex the PSP is used for the tasks, and the MSP (main stack) is used for the interrupts. I have updated the post about this. Sorry for the confusion!

        Like

      • Thanks Erich, looks like I thought.
        Separate stacks, that why we like Cortex 🙂
        /Grzegorz Konopko

        Like

  31. Pingback: Some notes on how to use FreeRTOS with a FRDM-KL25Z (almost) without Processor Expert | Robot Overlord

  32. Hello Erich,
    I tried setting everything up as described in this tutorial. When I add one task the LED blinks, but when I try to add the second one (another blinking LED) nothing happens and neither LED is blinking.
    Also, do you know what could cause CodeWarrior to crash sometimes when setting up PEx components?
    Thanks in advance 🙂

    Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s