Quality RTOS & Embedded Software

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




Loading

FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 25, 2012
Hello,

I'm trying to port FreeRTOS onto an EnergyMicro board using the CMSIS 3 API. It is technically working but there is a little problem I'm running into that needs to be fixed. The function prvCheckTasksWaitingTermination() is called in the idle task and I understand why, but when I have it in there, my board will throw a Hard Fault Exception with an odd trace. If I comment it out (I'm running a simple application right now that doesn't delete tasks), it runs perfectly fine. The odd thing is that it doesn't run the code in the if statement that is in that function because I never delete any tasks. Therefor, when that function is called, all it does is compaire and return. I've tried checking for stack overflow, but I can't find any indication of that (except for the odd trace). Does anyone have any idea what is going on or any method I could use to try to figure out this problem. I'll post the trace below, but it just looks like garabage to me.

1 0x20000f2c
2 0x2001ffb0
3 () 0xfffffffd
4 HardFault_Handler() port.c:300 0x00006f24

Any help or thoughts would be appreciated.

Thank you,
Micheal

RE: FreeRTOS EnergyMicro Port

Posted by Richard on July 25, 2012
It does not sound like prvCheckTasksWaitingTermination() is the cause of your problem if it is not being called, and I would suspect that removing the task is just masking the problem (temporarily) because code has moved around in RAM.

What exactly is the trace you have shown? It looks like the fault handler stack trace - is that correct?

Have you determined the instruction that is actually causing the hard fault? Here is a page to help if you are not sure how:

http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

In addition, there are the normal pages to check, but I suspect you have been through these already:

http://www.freertos.org/FAQHelp.html
http://www.freertos.org/RTOS-Cortex-M3-M4.html

Regards.

RE: FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 25, 2012
Thank you for the quick reply. I implimented the prvGetRegistersFromStack and the pc was 0xa5a5a5a4. That means there's is a stack overflow right? Also, if I use a for loop as a delay instead of calling vTaskDelay, there aren't any problems (the Idle task never runs).

The trace I gave is when the code stops in the fault handler and that's the trace Eclipse gives me. When I look at the assembly of the first two locations, it just looks like garbage. How can I trace the stack overflow (if that's what it is) if the built in functions don't pick it up?

And I can't find the specific instruction. The idle task will run for a bit before it messes up. I'd have to step through tons of cycles to find it (seeing as the trace has been no help).

RE: FreeRTOS EnergyMicro Port

Posted by Richard on July 25, 2012
Ok - that means the program counter was executing instructions at that (invalid) address. That is genuine as the least significant bit has been lost as the program counter only deals with even addresses. Trying to execute an instruction at that address will be the cause of the fault, but unfortunately that doesn't help us as we need to see why the program counter was loaded with that value. The value is the stack fill byte, so it looks like stack corruption.

In your original post you said the application runs fine if you comment the line out, can you provide more information on the application.

Did you create it yourself, or is it based on an existing official demo?
What are the simple tasks doing? Just flashing LEDs, or something more complex?
Does it run indefinitely when you have the offending line commented out of the idle task?
Do you have any interrupts executing (other than the RTOS interrupts, naturally)?
Is the interrupt vector table populated with the FreeRTOS interrupt handlers (either directly, or by #defining the FreeRTOS handlers to their CMSIS equivalents)?

Regards.

RE: FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 25, 2012
It started out as one of the demos, but I think I've modified it enough to call it my own, it just blinks the LEDs. The board I'm using had 8 LEDs on it and it uses a different task to toggle each one at a different frequency. The tasks call functions from the board driver (to toggle LEDs) and CMSIS's osDelay function (which just changes the arguement from ms to ticks and calls vTaskDelay). All this happens in an infinite for loop. I have a second board that's been running with the line commented out for hours now and I haven't noticed anything strange. Everything on the board is disabled (interrupts and peripherals) except for what FreeRTOS uses. I'm using the SVC_Handler, PendSV_Handler, and SysTick_Handler that came with FreeRTOS and I made some small handlers for the faults that just switch on some LEDs and sit in a loop. If you'd like to know the chip, it's the EM32GG230F1024.

Thanks again for your help.

RE: FreeRTOS EnergyMicro Port

Posted by Richard on July 25, 2012
Ok, struggling for suggestions now, but:

Do you have an idle task hook function defined? (is configUSE_IDLE_HOOK set to 1 or 0 in FreeRTOSConfig.h?)

When you say all interrupts are disabled, I presume you don't mean globally disabled, otherwise nothing would work.

Can you post the code for osDelay (is that something Energy Micro are shipping themselves, ported to FreeRTOS?)

Are the functions that toggle the LEDs implemented with any sort of critical section? If so, is it a FreeRTOS critical section?

Could you modifying the tasks to not call any driver functions (i.e. call vTaskDelay() directly, and try to simplify the LED setting/clearing if it is being done in any way other than a very simple way). If it still does not work, please post the code.

What priority are your tasks running at?

Do you have any other hook functions defined?

Regards.

RE: FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 25, 2012
I have the idle hook disabled (I originally thought it might have been that, it's set to 0 in FreeRTOSconfig.h).

I don't mean interrupts are globally disabled, just all the ones not used by RTOS (If I remember correctly, only SysTick interrupt is on).

osDelay:

osStatus osDelay (uint32_t millisec)
{
#if INCLUDE_vTaskDelay
portTickType ticks = (millisec / portTICK_RATE_MS);

vTaskDelay(ticks ? ticks : 1); /* Minimum delay = 1 tick */

return osOK;
#else
(void) millisec;

return osErrorResource;
#endif
}

EnergyMicro just provided the header file and API for RTOS, all the function have to be written (these were written by someone else). But it's pretty simple.

I actually disabled all my tasks and just started the scheduler to see what that would do, it still does the same thing.

I'm not sure the exact prioty they're running at, but I know it's higher than the idle task (the function in the CMSIS code sets it relative to the idle and it sets it to a lower number which is higher priority on EneryMicro chips).

There are no other hooks.

I've been trying to figure this thing out for a few days now, it's getting frustrating. But I feel like I'm so close and this is (hopefully) something that's easy to fix. I think there must be something I'm missing.

RE: FreeRTOS EnergyMicro Port

Posted by Richard on July 25, 2012
Do you have compiler optimisation on? (should work with it on, but best to start with it off).

From the sound of it, you are using the kernel through an abstraction layer, which I cannot replicate and I have no idea how the abstraction layer is implemented. I suggest removing the abstraction layer to start with to remove that unknown. You don't have to remove it from your project, just call the native RTOS API directly. You can set up something very simple very quickly as per (something like):

void vTask1( void * pvParameters )
{
for( ;; )
{
toggle_led( 0 );
vTaskDelay( 500 / portTICK_RATE_MS );
}
}

void vTask2( void * pvParameters )
{
for( ;; )
{
toggle_led( 0 );
vTaskDelay( 500 / portTICK_RATE_MS );
}
}

void main( void )
{
setup_hardware();
xTaskCreate( vTask1, "task1", configMINIMAL_STACK_SIZE, NULL, 1, NULL );
xTaskCreate( vTask2, "task2", configMINIMAL_STACK_SIZE, NULL, 1, NULL );
vTaskStartScheduler();
}



Regards.

RE: FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 25, 2012
I commented out anything have to do with the CMSIS code and created functions that delt directly with FreeRTOS functions and replaced the LED toggles with just for loops. Nothing has changed. This is all being built in debug mode, therefor there is no optimization.

RE: FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 25, 2012
Here's what I'm going to try, I'm going to start a new project with just the FreeRTOS Kernel, drivers, and a small application and I'll use a fresh copy of FreeRTOS and see if I can get it to run. I might have messed with something in the project that made it messed up. I'll let you know how that goes.

RE: FreeRTOS EnergyMicro Port

Posted by Richard on July 25, 2012
Can you zip up your project and send it to me at r dot barry ___at___ freertos.org.

Regards.

RE: FreeRTOS EnergyMicro Port

Posted by Richard on July 27, 2012
From a first quick look, there does not appear to be anything wrong with your simple blinky demo, however, there have been some edits to port.c which look potentially dangerous. I'm not sure if you made those before or after you had the issue, or if in fact they were already in the code when you received it, but I'm going to request you take them out to see if it fixes the simply blinky application.

There are in fact several edits made that are not necessary (addition of include files that would not be necessary if FreeRTOS.h was included in the application c file first, added paths to portable.h that would not be necessary if the path to portmacro.h was in the compilers include path) but I don't think those are harmful (until you come to try and update your FreeRTOS code that is!). Generally, try not to edit the RTOS code at all. If you want to use the CMSIS names for the RTOS interrupt handlers this can be done by adding the following three lines to FreeRTOSConfig.h, rather than editing the RTOS source directly:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler


So specifically, the problem I see is the addition of the __attribute__((interrupt)) qualifier on the interrupt handlers. This is not necessary. It is probably harmless for the systick handler, but the other handlers need to be naked functions, and the combination of changing the name and adding the additional attribute could be very harmful - instead of entering the function and immediately executing the RTOS assembly code it is going to enter the function and execute the compilers own interrupt entry code first.

Generally on Cortex-M microcontrollers, interrupts should just be standard C functions, with no attributes required.

Please revert the file to exactly as it appears in the main FreeRTOS distribution in FreeRTOS/Source/portable/GCC/ARM_CM3, then add the three code lines above to FreeRTOSConfig.h. You should then be able to compile (move the other handlers you added to port.c to a separate source file).

Regards.

RE: FreeRTOS EnergyMicro Port

Posted by Micheal Shoemaker on July 27, 2012
Changing those interrupts worked like a charm! Thank you so much. I'm going to let it sit and run for a bit and make sure it doesn't mess up, but it looks like it's running way better than before.


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




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

Latest News

FreeRTOS kernel V10 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