- Stacks
[see also the uxTaskGetStackHighWaterMark() API function, and the stack overflow detectionoptions]Stack overflow is by far the most common source of support requests. The size of the stack available to a task is set using the usStackDepth parameter of the xTaskCreate() API function. Try increasing the size of the stack allocated to the task that is causing the problem, or reducing the amount of stack that the task utilises. Don't write interrupt service routines that require a lot of stack. Tasks that make calls to any string formatting functions are likely to require a lot of stack - particularly when using the GCC compiler. Such tasks are particularly prone to stack overflow. Each byte of the task stack is set to 0xa5 when the task is created, making it relatively simple to see if a stack overflow has occurred. In addition - the function usTaskCheckFreeStackSpace() in task.c demonstrates how the stack usage can be checked at run time (although this is a somewhat inefficient function so should only be used for debugging). - I added a simple task to a demo, and now the demo crashes!
Creating a task requires memory to be obtained from the kernel heap. Many of the demo application projects dimension the heap to be just big enough to run the demo tasks - so not big enough for any further tasks to be added to the project. The idle task is automatically created when you start the scheduler. If there is insufficient heap available for the idle task to be created then vTaskStartScheduler() will return - causing the application to never even start.To rectify this, increase the heap space, or remove some of the demo application tasks. - Using API functions within interrupts
Do not use API functions within interrupt service routines unless the name of the API function ends with "...FromISR()".Cortex M3 users - please note - this is the cause of 95% of support requests on Cortex M3 devices: API functions must not be called from an interrupt if the interrupt has a priority above the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY. Note carefully the following points when setting an interrupt priority: - configMAX_SYSCALL_INTERRUPT_PRIORITY is defined in FreeRTOSConfig.h. On Cortex M3 devices, a numerically low interrupt priority value represents a logically high interrupt priority. Do not leave an interrupt priority unassigned because it will use priority 0 by default. Priority 0 is the highest possible interrupt priority and will be above configMAX_SYSCALL_INTERRUPT_PRIORITY.
- Take care when specifying a priority as different Cortex M3 implementations use a different number of priority bits.
- Internally the Cortex M3 uses the 'n' most significant bits of a byte to represent an interrupt priority, where 'n' is implementation defined as noted above. ARM and various Cortex M3 licensees provide library functions to allow interrupt priorities to be assigned, but some expect the priority to be shifted into the most significant bits before the library function is called, whereas others will perform the shift internally.
- The bits that define an interrupt priority are split between those that represent the preemption priority, and those that represent the sub priority. For greatest simplicity and compatibility, ensure that all the priority bits are assigned as 'preemption priority' bits.
- The scheduler crashes when attempting to start the first task
If you are using an ARM7 target then the processor must be in Supervisor mode when the scheduler is started. - The interrupt enable flag gets set incorrectly
Do not use any method for disabling and enabling interrupts other than calls to portENTER_CRITICAL() and portEXIT_CRITICAL(). These macros keep a count of the call nesting depth to ensure interrupts only become enabled again when the call nesting has unwound completely to zero. - My application crashes before the scheduler is even started
A context switch cannot occur until after the scheduler has started. Any interrupt service routine that could potentially cause a context switch must therefore not be permitted to execute prior to the scheduler being started. The same is true of any interrupt service routine that attempts to send to or receive from a queue or semaphore.Many API functions cannot be called prior to the scheduler being started. It is best to restrict such usage to the creation of the tasks, queues and semaphores that will be used once the scheduler activity has commenced. - Suspending the scheduler (calling vTaskSuspendAll()) causes me problems
Do not call API functions while the scheduler is suspended. Some functions can be used, but not all. This is not the intended purpose of the suspension mechanism. - I have created a new application - but it will not compile
Base new applications on the provided demo project file for the port you are using. This way you will be sure that the correct files are included and the compiler is correctly configured. - I get stuck on the line that starts for( pxIterator = ( xListItem * ) &( pxList->xListEnd );
Likely causes include: - Stack overflow - see http://www.freertos.org/Stacks-and-stack-overflow-checking.html.
- Incorrect interrupt priority assignment, especially on Cortex M3 parts where numerically high priority values denote low actual interrupt priories, which can seem counter intuitive. See configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html#kernel_priority.
- Calling an API function from within a critical section or when the scheduler is suspended
|