RTOS passing and returning structures

zukk wrote on Monday, February 05, 2018:

I’m playing around with a Discovery Board and I don’t understand how to pass and return structs from a thread.
The struct is defined in a header file because it is used by many functions. I mainly have to implement a RTOS system instead of a normal main cycle.

void ReadingSPI_Thread(void const *argument);
osThreadId tid_ReadingSPI_Thread;
osThreadDef(ReadingSPI_Thread, osPriorityNormal, 1, 0);

void ReadingSPI_Thread(void const *argument){

Sensor_Data_Struct *Sensor_Data;
osSignalSet(tid_ReadingSPI_Thread, 0x01);

while(1){

code code code

How can I simply pass the structure and return it? i have been looking online for a couple of days but all the code doesn’t work on keil uvision.

Thank you

richard_damon wrote on Monday, February 05, 2018:

First, don’t think of a Task as a function you call and get an answer from. Setting up a thread and later deleting it is a fairly expensive operation compared to a function call.

Generally a Task will be created once, and sent requests via things like queues and semaphores, and possible send back results similarly, while the requesting task when off and did something else. If a driver task is always being used by a task sending a request, then the requesting task waiting for a response, I find that is an indication that the driver task really shouldn’t be a task, but just a function, likely using a mutex internally to serialize the request (this also has the advantage that higher priority requests will happen first).

For your example, ReadSPI is in my mind a driver function, that grabs a mutex serializing access to the SPI Controller (since it can generally only do one transaction at a time), and perhaps there would be a thread for each sensor that is being sampled, which aquire the data at the rates needed and forwards them to a processing Task.

zukk wrote on Monday, February 05, 2018:

Mmm I understand, so you would put ReadSPI as a function that gets called by the thread whenever it needs to be done? Is that correct?

If I do ReadSPI as function it needs some parameters. It’s not a problem passing them without implementing threading. But how can i pass parameters to a function inside a thread?
Also, once i have read the data, how do I return this data to be used by another thread/function inside a thread?
(they are mainly structures)

this is my function in my_header.c

Sensor_Data_Struct Read_SPI(SPI_HandleTypeDef SPI_Params){

returns a sensor data struct that i later analyze with another function and receives as parameter the settings used to define the SPI communication

rtel wrote on Monday, February 05, 2018:

Tasks are autonomous threads of execution. If you call a function the
function executes in the context of the task that called the function.
If you want to send data to a different task then you need to use a
communication primitive/object such as a queue, message buffer, stream
buffer, direct to task notification, etc. You can find information on
all these on the FreeRTOS.org website. Also, although it is a bit out
of date, I recommend reading the FreeRTOS book - it is a free download
here: https://www.freertos.org/Documentation/RTOS_book.html

Note however you are not using the native FreeRTOS API.

zukk wrote on Wednesday, February 07, 2018:

Ok, I think I have understood. I have changed the logic of my software and It works.
I have another question now.
Everytime I switch thread, the thread switched to goes in overflow, after which the RTOS does a restore procedure and everything works fine. But again, thread switched -> overflow. I don’t understand what might be causing it.
Is there anything you would suggest? Particularly the signal of stack overflow happens when this function gets called.
This function is in rt_Task.c file.

void rt_switch_req (P_TCB p_new) {
/* Switch to next task (identified by “p_new”). */
os_tsk.new = p_new;
p_new->state = RUNNING;
DBG_TASK_SWITCH(p_new->task_id);
}

rtel wrote on Wednesday, February 07, 2018:

Do you mean the stack is overflowing? Don’t try continuing to execute
once the stack has overflowed, it should be treated as a hard error.
Did you try just increasing the size of the stack allocated to the task?