How to run two tasks simultaneously with stm32f750n8h6

In my project, i want to run two tasks simultaneously, for that using RTOS i have tried led blink code to run two tasks simultaneously and it’s worked.
so similar way i added my two ADC’s reading like ADC1 reading in task1 and ADC2 reading in task2 but its not running as expected with the same priority for both if i changed the priority above of one of them higher priority task gets executed .
So without any interruption can I read both ADC’s data simultaneously .??

What do you mean when you say “not running as expected”?

Thanks for the reply, when i tried to run ADC1 / ADC2 in default_task individually its worked fine. so i have created two tasks as default task and task_2 and then i kept my ADC1 reading function in default_task and ADC2 in task2 while running control is not entering to these two tasks. so there is no ADC data in the serial monitor.

Is the ADC reading function thread safe? i.e. is it okay if it is preempted in the middle? Can you break in the debugger and see what the code is doing?

Yes, i did debug now and its stuck in the data_ready_flag a
like this.
this is first_task
Screenshot 2022-11-08 150236

here ADC_READY flag is true then adc read function will call but the control not entering to this loop its self.

similarly second_task

here also the same thing happening.

this is the interrupt call-back function for data ready flag

Screenshot 2022-11-08 150255

so if run individually its working but when i kept it into two tasks its not.

any suggestions regarding this?

Are you using two independent ADC controllers or two channels within a single controller? A single controller normally can only physically read a single channel at a time.

If you do want to read two ADC controllers at the same time you will likely need custom code as the vendor-supplied code likely starts one ADC read and spin waits for it to finish, which will block the ability to do things simultaneously.


Yes, but I just change the naming and SPI port for the same library, and its working individually for both ADC controllers.

and one more thing for each ADC reading i am using the data ready pin as an external interrupt maybe this is the reason when i run TWO ADC reading with different task data ready pin does not go low.

Ok, so your ADC is an external SPI device, not an internal device. A possible issue is that the SPI driver doesn’t handle simultaneous usage (again, possibly because it busy-waits).

Note, ST’s HAL library is NOT really designed for multithreading.

But i am using the ADS1256 ADC library, so this should be work right.??
if you are ok, I will share my ads1256 spi driver please have look and let me know your feedback.

Does the SPI driver start the conversion, block to let another thread start its conversion on another SPI controller or start a second conversion itself, and then when one of the channels is done get the result.

The ONLY way to get two simultaneous conversions is to first start both of them, and THEN wait for both answers. Any driver based on a single read, that isn’t RTOS aware and blocks between starting and reading to allow another task to read the other channel, isn’t going to make that happen.

Based on your words I can’t read two ADC data with two tasks simultaneously.
then what is the use of a controller with RTOS.?? then please let me know any other efficient method to get two ADC controller data simultaneously like for example is there any necessity to change the controller/processor or some other possibilities?

I didn’t say you CAN’T do it, I said you can’t do it unless the program is setup to let it happen.

IF you have two different ADCs and two different SPI buses to talk to them, then it is possible to start the two different requests IF your drivers know how to do that.

One big issue is that often the drivers from the chip manufacturer aren’t set up to do that.

You need an interrupt-driven SPI driver that starts the operation, and blocks, so the other task can run to make its request on the other SPI channel.

Any driver that just does a “spin wait” for the operation to continue just doesn’t work well with an RTOS, so should be rewritten to block for an interrupt, to let other things run.

Sorry for the inconvenience.

Ok, but here is i have a doubt that ADC works in this concept whenever data gets ready it pulls DRDY pin low and I declared it as an external interrupt concept like if drdy pin goes low flag gets high and the data should be read.

So here how can i use the interrupt concept again i am confused.

Sorry, I tried to upload my code but its more than 4mb, and uploading failed. So if you share your email i can share my ADC code, please have look once and let me know your suggestion to make it happen.

Seriously it’s very important for me to happen because already design and everything has been done so i hope you understand my situation.

thank you.

The code for the ADC shouldn’t be 4 MB. I wouldn’t have time to look at that much code either.

The key point is how the ADC gets told to start its conversion. If it is an external signal, then the simultaneous conversion isn’t an issue, and it happens automatically, and it is only important that the answers get read before they get overwritten by the next conversion.

If it is a command sent to the ADC from the computer, then the key is that after sending the command and waiting for the answer, the task blocks and waits for the answer to come, so the other task can make its request (of the first task sends both requests).

The point I am making is often the sample code provided assumes single threading, the code sends the request and busy waits for the answer, then gets the result, and that sort of program does NOT lead to got utilization of the processor or the ability to do multiple things at the same time.

Note, the code you have posted where the ISR sets a flag that your code just loops checking is exactly that sort of “busy wait” which keeps the processor busy, If you are going to wait for a data-ready interrupt, wait on a semaphore, or a direct-to-task notification (possibly with a timeout) so the other tasks can run. Except for the very shortest of delays or when you have other productive work you are doing should code be just checking a flag in a loop.

Yes, that might be how you code it in a non-RTOS environment, but that does NOT work well when you need to be sharing the processor.

i just removed the callback function and now i directly read the drdy pin status and if it goes low start to read the data.
but still its same , i am really tired of this operations and i don’t know what to do .

Which means you are still just burning all your CPU looping on testing if the ADC is ready.

As I said, you need your tasks to BLOCK and give up execution until the interrupt occurs.

if i did like that i am thinking, there is a possibility to loss the data. so i just tried in a different way like when an interrupt occurs making priority HIGH for that ADC and if not making LOW. but still not successful.

My guess is you are doing it wrong, or your system is just too slow. Maybe your ISR code isn’t waking up the needed task (it can’t just set a variable like you old code was doing).