Quality RTOS & Embedded Software

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


Tasks outside main file

Posted by delphes on January 22, 2018


I made an application on cortex M4 (STM32L4), FreeRTOS 9.0 and Keil, it was working like expected until my task, and object create (semaphore, queue etc) was in main.c file, i decided for much clarity to move outside main in another c file and my whole application get hang inside FreeRTOS. I am just wondering if the are any restiction to have task , objects etc outside main file ?


Tasks outside main file

Posted by leroy105 on January 22, 2018

David, I'm not an expert with FreeRTOS. All embedded C programs execute from main. Literally when you provide power to the MCU, all the startup files are prepping the MCU for the big moment when it goes to main to start executing code.

If you executed the FreeRTOS kernel from a seperate file, so the actual functions are in another C source file, I suppose you could.

If you are just getting started, I would just execute FreeRTOS from main as in the examples and go from there.

The intent of the RTOS is that you call it from main, and that it is always running in the background, such that you never EVER will call another function in main again. (That's a simplification, but for getting started a good way to think about it).

Tasks outside main file

Posted by delphes on January 22, 2018

Tim, this does not answer to my question, In some huge program you sometimes need to split into module, to avoid main file with 10000 lines. I am just asking if there are any rules on heap management or whatever to run task outside Main file ?

Tasks outside main file

Posted by rtel on January 22, 2018

It is not clear to me what you mean by run tasks outside of main file.

Do you mean to implement the tasks in the main.c source file? Do you mean to create the tasks in the main.c source file?

Or do you mean something else.

A FreeRTOS application is just a C program. Within the scoping rules of the C language (by which I mean if things are globals), the C compiler doesn't care which file contains which function definitions. Likewise the C compiler doesn't care what you call the source files, there doesn't have to be a main.c. The only thing the compiler cares about, and even then only by convention as you could change the start up code, is that there is a function called main() that it will (by convention) use as the entry point for the application.

Most of the hundreds of examples implement and create tasks both in the main.c file and outside of the main.c file.

Tasks outside main file

Posted by delphes on January 22, 2018

Dear Richard,

The task are declared and implemented in separate unit (called doit.c for exemple), the main.c call an init function (located in doit.c) which create task, semaphore, events etc.. after call this init function main just start scheduler. So physically the tasks in doit.c are not in main.c.

When the initialisation of task and task itself was in main no problem. Problem arises just after moving to doit.c.

anythings related with M4 main stack/heap or whatever ?

I am curious to see example outside main.c file.


Tasks outside main file

Posted by rtel on January 22, 2018

....in which case something very odd is happening. Off the top of my head I would say one of two things could be the culprit:

1) You are running out of main() stack, but that is VERY unlikely as the stack overhead in the fail case is only one additional function call depth to the success case.

2) Your initialisation function (the one in doit.c) is using stack variables as parameters to tasks that, once the function returns, no longer exist.

I am curious to see example outside main.c file. Look at any file in the FreeRTOS/demo/common/minimal directory.

Tasks outside main file

Posted by delphes on January 22, 2018

the declaration of freeRTOS object are here (located in doit.c)

volatile QueueHandlet xRcvQueuexmsg; volatile QueueHandlet xTrmQueuexmsg;

volatile osThreadId xstackxProcess; volatile osThreadId xThreadReceiveCar, x_ThreadTransmitFrame;

TaskHandlet xTaskxReceive = NULL, xTaskxTransmit = NULL, xTaskstackxProcess = NULL;;

my initialization function in doit.c is here :

void stackInit(void) { osThreadDef(xSProcessThread, gsmstackxProcess, osPriorityNormal, 0, 256); gsmstackxProcess = osThreadCreate(osThread(xProcessThread), &xTaskstackxProcess);

osThreadDef(uartrcvTask, vxReiceiveCar, osPriorityNormal, 0, 512);
x_ThreadReceiveCar = osThreadCreate(osThread(uartrcvTask), &xTask_xReceive);

osThreadDef(xTestThread, vxSendxFrame, osPriorityNormal, 0, 512);

xThreadTransmitFrame = osThreadCreate(osThread(xTestThread), &xTaskxTransmit);

xProcess_Queue_x = xQueueCreate(5, sizeof(struct _xFrame_t));
xRcv_Queue_xmsg = xQueueCreate(1024, (unsigned portBASE_TYPE) sizeof(signed portCHAR));
xTrm_Queue_xmsg = xQueueCreate(5, sizeof(struct _x_TX_frame_t));


somethings looks wrong ?

Tasks outside main file

Posted by rtel on January 22, 2018

Doesn't look like it is using stack variables, which would discount (2) above.

Tasks outside main file

Posted by delphes on January 22, 2018

I was dreaming I was wrong since I already spent couple hours finding. any idea where I can investigate search ?

Tasks outside main file

Posted by waveringradiant on January 22, 2018

These are tricky things to debug without having all the code. It essentially leads to speculation and prolonged Q&A. So I should just stay out of the discussion... but just take the facts, and ask yourself "what changed as a result"?

So for example, when everything is in main, "everybody sees everything". But when some of the stuff is moved "over there" but needed "over here", in theory that's fine... if you do it right.

(Warning: speculation) For example, typically a header file is used to make something defined "over there" available to the rest of the world. The header file should be #included both where the objects/code are defined, and also in the files where they are used. But what if the definition & the declaration are subtly different? For example, what the if the volatile-defined objects aren't declared as volatile in the header file. This should give you a compiler warning a) if you have it enabled (not suppressed) and b) if you actually include the header file in the source file where the object (or code) is defined. But sometimes people forget to do this.

My point is this (actually 2 points): (1) without all the code, this is hard to debug, and we can only speculate (which is a fool's errand with no end); (2) it almost certainly pertains to the mechanics of moving code, and what happens when you do so (could also be that things are arranged differently in memory, etc.)

My suggestion: go back to what works ("all in main"). Change one thing at a time. If / when it breaks, it pertains to that one simple change. Still, the root cause might be tricky, but now the universe is much smaller.

Good luck!!

Tasks outside main file

Posted by delphes on January 22, 2018

Panapticon thanks for the tips, I will try to do it line by line and open my eyes again...

[ 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