Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

New user looking for tips

Posted by dcrocker on January 2, 2018

Hi all, I am about to start converting a project to use FreeRTOS. So I am looking for tips. Here is some background:

  • I have previous experience of RTOS (I used to be a developer of one), but no experience of FreeRTOS yet
  • The project is a successful 3D printer control firmware (RepRapFirmware) and the target for the FreeRTOS version will be ARM Cortex M4 and higher ATSAM processors
  • The project is somewhat object-oriented and mostly written in C++, but avoids dynamic memory allocation except during initialisation and configuration
  • The development tools are Eclipse and gcc
  • RAM is already quite tight, but we can afford around 10K (perhaps more) for FreeRTOS and the tasks and stacks, and most tasks shouldn't need large stacks if we can run them in user mode so that interrupts are handled on a separate stack
  • For several months I have been ensuring that any new developments should be suitable to fit into a task-based model
  • It uses FatFS for SD card access, and some versions use LWIP to provide a TCP/IP stack
  • I was pleased to see that FreeRTOS complies with the MISRA-C coding standard, because I am familiar with it (I am a member of the MISRA-C++ Working Group, and a former member of the MISRA-C Working Group).

My questions:

  1. To get started, I propose to create a single task which executes the existing main loop code. The Idle task will never get a look-in. After this is working, I will split some of the functions currently executed in the main loop into other tasks. Does this sound a reasonable approach?
  2. Many of the functions executed by code that will eventialy be split into different tasks access the same data, mostly read-only, by calling accessor methods of the classes that hold that data. It may not be practical for me to use the MPU to partition the memory between tasks. At the same time, it would be nice if the tasks' own stacks and other working memory could be protected from each other. Any suggestions on the best approach?
  3. Is there already a C++ wrapper for the more complex FreeRTOS data structures, to simplify the interface to message queues etc. from C++? It would need to be one that does not use dynamic memory allocation.
  4. I see that instead of FatFS and LWIP I could use FreeRTOS+FAT and FreeRTOS+TCP. Should I use them, or stick with FatFS and Lwip? I think both include some support for FreeRTOS already.
  5. Some of the existing functions performed by the main loop don't really merit additional tasks, because they are not time-critical and the existing round-robin approach works well. Nevertheless, converting them to tasks or coroutines would avoid the need to use state machines in some cases. Should I use coroutines for them, or should I avoid coroutines because they are end-of-life as far as FreeRTOS development is concerned?
  6. Anything else I should be aware of before I start?

Thanks in advance - David


New user looking for tips

Posted by dcrocker on January 2, 2018

Two more questions:

  1. FreeRTOS needs to take over the systick vector, but my current code uses it to do various short operations at regular intervals. Is there an official way of hooking the systick interrupt, or should I just include a call to my own function near the start of xPortSysTickHandler ? Or can my application keep control of systick, and call xPortSysTickhandler ?
  2. What is the reason for making the systick interrupt have the lowest priority; and can I change it? The existing code has quite a lengthy ISR for generating step pulses, so I rely on the systick being able to interrupt it.

New user looking for tips

Posted by rtel on January 2, 2018

Hi all, I am about to start converting a project to use FreeRTOS.So I am looking for tips. Here is some background:

Although it sounds like you are already experienced with an RTOS, for familiarity it might still be beneficial to read the free book download (although it is predominantly for FreeRTOS V8.x whereas now we are on FreeRTOS V9.x, the FreeRTOS source code download contains links to what's new in V9 and what's new in V10).

  • Memory is already quite tight, but we can afford around 10K (perhaps more) for FreeRTOS and the tasks and stacks, and most tasks shouldn't need large stacks if we can run them in user mode so that interrupts are handled on a separate stack

On that part interrupts will already use their own stack - you don't need to do anything to make that happen.

My questions:

  1. To get started, I propose to create a single task which executes the existing main loop code. The Idle task will never get a look-in. After this is working, I will split some of the functions currently executed in the main loop into other tasks. Does this sound a reasonable approach?

Sounds like a good starting point - but not that, if a task deletes itself (as opposed to getting deleted by another task) then the Idle task must be given some execution time as it cleans up the stack and TCB of the now deleted tasks.

  1. Many of the functions executed by code that will eventialy be split into different tasks access the same data, mostly read-only, by calling accessor methods of the classes that hold that data. I it may not be practical for me to use the MPU to partition the memory between tasks. At the same time, it would be nice if the tasks' own stacks and other working memory could be protected from each other. Any suggestions on the best approach?

For absolute protection you would have to use the MPU, but it can be a pain on a Cortex-M4 due to the size and alignment requirements of the MPU regions. Even without the MPU you do have some stack overflow protection but it will only trigger after an overflow has occurred so it is considered a fatal error - with the MPU version it will trigger before the overflow occurs.

  1. Is there already a C++ wrapper for the more complex FreeRTOS data structures, to simplify the interface to message queues etc. from C++? It would need to be one that does not use dynamic memory allocation.

Yes - but these are third party wrappers rather than something that is directly supported by us. Have a look in the FreeRTOS interactive side ( http://interactive.freertos.org ).

  1. I see that instead of FatFS and LWIP I could use FreeRTOS+FAT and FreeRTOS+TCP. Should I use them, or stick with FatFS and Lwip? I think both include some support for FreeRTOS already.

FatFS has some crude thread safety mechanisms whereby each API function is wrapped by a semaphore take/give if you configure it to do so. Lots of people have issues using lwIP from a mult-threaded environment - it will work fine but you have to get the configuration right and follow its threading rules (don't use the same socket from multiple threads, etc.). Our own stacks are natively thread safe, but if you already have something working with FatFS and lwIP it might be more effort than required to switch.

  1. Some of the existing functions performed by the main loop don't really merit additional tasks, because they are not time-critical and the existing round-robin approach works well. Nevertheless, converting them to tasks or coroutines would avoid the need to use state machines in some cases. Should I use coroutines for them, or should I avoid coroutines because they are end-of-life as far as FreeRTOS development is concerned?

Best to avoid coroutines as they have not been actively maintained for some time.


New user looking for tips

Posted by rtel on January 2, 2018
  1. FreeRTOS needs to take over the systick vector, but my current code uses it to do various short operations at regular intervals. Is there an official way of hooking the systick interrupt, or should I just include a call to my own function near the start of xPortSysTickHandler ?

Yes, see https://www.freertos.org/a00016.html

  1. What is the reason for making the systick interrupt have the lowest priority; and can I change it? The existing code has quite a lengthy ISR for generating step pulses, so I rely on the systick being able to interrupt it.

Yes the systick can (I think?) be made higher priority, but it is not something we would advise non-expert users to do (your experience would seem to make you an expert user, albeit not necessarily with FreeRTOS yet) as it can lead to inefficiencies as the tick count changes within code that is using it. Make sure to leave the PendSV at the lowest priority though.


New user looking for tips

Posted by heinbali01 on January 2, 2018

Richard was just a bit quicker to give you answers, so there will be some overlap here below:

The Idle task will never get a look-in

What do you mean with this phrase? Won't you ever call a blocking function?

... I will split some of the functions currently executed in the main loop into other tasks. Does this sound a reasonable approach?

This sounds very vague to me, I suppose you know what you are doing.

At the same time, it would be nice if the tasks' own stacks and other working memory could be protected from each other. Any suggestions on the best approach?

A memory stack is always private to a task, by definition. So are local data. Static data in a function or module, and global data are accessible by all tasks. You will have to decide who can have access to these data. When the access is read-only, you probably want to have a coherent snapshot of it, and copy a struct while the scheduler is temporarily disabled. When reading variables that have the size of a register ( 32-bits ), you probably don't need any protection, because the access is "atomic".

I like the C++ approach, in which objects have private and public ( and protected ) methods and data.

Is there already a C++ wrapper for the more complex FreeRTOS data structures

Have a look at Richard Damon's work here: https://github.com/richard-damon/FreeRTOScpp

see that instead of FatFS and LWIP I could use FreeRTOS+FAT and FreeRTOS+TCP. Should I use them, or stick with FatFS and Lwip? I think both include some support for FreeRTOS already.

If you already have a project running with FatFS and lwIP, and if you're satisfied with them, I'd keep on using them. But if you plan to do new projects, I'd have a look at the FreeRTOS libraries. The +TCP and +FAT libraries have advantages, mostly because they are tightly coupled to the OS. Other public libraries will offer a "FreeRTOS port".

FreeRTOS needs to take over the systick vector, but my current code uses it to do various short operations at regular intervals. Is there an official way of hooking the systick interrupt, or should I just include a call to my own function near the start of xPortSysTickHandler ? Or can my application keep control of systick, and call xPortSysTickhandler ?

Please google for "FreeRTOS configUSETICKHOOK". Your function will be called during every clock-tick. Be careful because your handler will be called from within an ISR. This means that you can only use FreeRTOS API's that end with ..FromISR().

What is the reason for making the systick interrupt have the lowest priority; and can I change it? The existing code has quite a lengthy ISR for generating step pulses, so I rely on the systick being able to interrupt it.

It sounds like you better use a TC interrupt that has a higher priority. But please read the texts about ARM M4 and the interrupt priorities.


New user looking for tips

Posted by dcrocker on January 2, 2018

Thanks! From those replies and a little research I have done in the meantime, I think I know what to do. I'll use the mechanism provided to hook the tick interrupt. I'll stick with FatFS and Lwip at least for now, but I'll protect them using mutexes or queues. I'll improve the tick interrupt priority but I'll make sure the the PendSV priority is the lowest one. I'm aware of the need to ensure that a task reads a coherent set of shared variables in a preemptive environment. I'll take a look at the C++ wrappers that both of you pointed to me.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

Meet us at Embedded World. Hall 3A-525.

Hear from Richard Barry at Embedded World. Feb 28, 16:00, Hall 4-428.

Video: Watch James Gosling & Richard Barry at re:Invent, Las Vegas 2017.

FreeRTOS kernel V10.0.1 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS