2021-03-05 02:54 AM
Hello,
I'm a beginner in FreRTOSS but I've already made basics codes and tutorials.
Actually, I'm trying to do two different tasks. The first one is an ADC acquisition and the second one is a printf of the ADC value.
But my issue is that the ADC function run only one time.
So me thinks I need to make an interruption in the infinite loop, but I don't know how doing that.
Can you help me?
Thank you in advance
Respectfully
Bastien
Solved! Go to Solution.
2021-03-05 06:41 AM
Hi,
first of all, let me suggest to move the function
saradc_lld_start(&SARADC12D2, &saradc_config_saradcconf);
from the task2 into main, just after the function sd_lld_start. If you do not change the driver configuration, it is not necessary to start the driver each time a new conversion must be issued. Then, could you share the ADC driver configuration?
Regards,
Luigi
2021-03-05 03:42 AM
Hi Bastien,
if you download from the st web site SPC5Studio and install it, you can find a lot of examples that show you how to play with the FreeRTOS tasks. I don't know which core are you using, but, for example you can find for the SPC584Bxx an example that shows you how to use 2 tasks, one that prints on the serial the message "Task1...", and another one that prints the message "Task2...". The 2 tasks have the same priority and will be alternatively run by the FreeRTOS scheduler. Below you can find the main code.
Regards,
Luigi
#include "components.h"
#include "FreeRTOS.h"
#include "task.h"
uint8_t message_task1[]= "Task1...\r\n";
uint8_t message_task2[]= "Task2...\r\n";
/* Demo tasks */
portTASK_FUNCTION( vTaskOne, pvParameters )
{
( void ) pvParameters;
TickType_t xLastWakeTime = xTaskGetTickCount();
for ( ;; ) {
vTaskSuspendAll();
sd_lld_write(&SD2,message_task1,(uint16_t)(sizeof(message_task1)/sizeof(message_task1[0])));
xTaskResumeAll();
pal_lld_togglepad(PORT_E, LED_4);
vTaskDelayUntil( &xLastWakeTime, 200 );
}
}
/* Demo tasks */
portTASK_FUNCTION( vTaskTwo, pvParameters )
{
( void ) pvParameters;
TickType_t xLastWakeTime = xTaskGetTickCount();
for ( ;; ) {
vTaskSuspendAll();
sd_lld_write(&SD2,message_task2,(uint16_t)(sizeof(message_task2)/sizeof(message_task2[0])));
xTaskResumeAll();
vTaskDelayUntil( &xLastWakeTime, 200 );
pal_lld_togglepad(PORT_D, LED_5);
}
}
/*
* Application entry point.
*/
int main(void) {
/* Initialization of all the imported components in the order specified in
the application wizard. The function is generated automatically.*/
componentsInit();
/* Enable Interrupts */
irqIsrEnable();
/*
* Activates the serial driver 1 using the driver default configuration.
*/
sd_lld_start(&SD2, NULL);
/* Creating first task to blink LED0 */
xTaskCreate( vTaskOne,
(const char * const)"task #1",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 1,
NULL );
/* Creating second task to blink LED1 */
xTaskCreate( vTaskTwo,
(const char * const)"task #2",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 1,
NULL );
/* Start the FreeRTOS scheduler */
vTaskStartScheduler();
return 0;
}
2021-03-05 06:22 AM
Hi Luigi,
First of all thank you for your answer.
I already did that on SPC5 Studio but the problem happens when I try to get the ADC to work.
I start ADC in the main and in the second task i try to start the conversion but it doesn't work.
Here is my code if it can help you :
#include "components.h"
#include "saradc_lld_cfg.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
extern uint8_t anp;
extern float value;
float tension =3.3;
uint8_t anp = 5U;
float value = 0U;
xQueueHandle queue;
portTASK_FUNCTION(vTaskOne, pvParameters) {
( void ) pvParameters;
uint32_t TickDelay = pdMS_TO_TICKS(2000);
for ( ;; ){
if(xQueueReceive(queue, &value, portMAX_DELAY) == pdPASS) {
printf("channel %d: value: %f V \r\n", anp,value);
}
else {
printf("Failed to receive a message \n");
}
vTaskDelay(TickDelay);
}
}
portTASK_FUNCTION(vTaskTwo, pvParameters) {
( void ) pvParameters;
uint32_t TickDelay = pdMS_TO_TICKS(2000);
saradc_lld_start(&SARADC12D2, &saradc_config_saradcconf);
for ( ;; ){
saradc_lld_start_conversion(&SARADC12D2);
value = (tension * saradc_lld_readchannel(&SARADC12D2, anp))/4095;
saradc_lld_stop_conversion(&SARADC12D2);
if (!xQueueSend(queue, &value, portMAX_DELAY)) {
printf("failed to send to queue \n");
}
vTaskDelay(TickDelay);
taskYIELD();
}
}
/*
* Application entry point.
*/
int main(void) {
/* Initialization of all the imported components in the order specified in
the application wizard. The function is generated automatically.*/
componentsInit();
/* Enable Interrupts */
irqIsrEnable();
sd_lld_start(&SD2, NULL);
queue = xQueueCreate(10, sizeof(value));
if (queue != NULL) {
xTaskCreate( vTaskOne,
(const char * const)"task1",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY,
NULL);
xTaskCreate(vTaskTwo,
(const char * const)"task2",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY+1,
NULL);
}
vTaskStartScheduler();
return 0;
}
I use Queue to send data between tasks but the real probleme is that the ADC doesn't run more than 1 time.
i don't know wich interruption I need to use or if I need to send data thanks to semaphore...
Thank you Luigi
2021-03-05 06:41 AM
Hi,
first of all, let me suggest to move the function
saradc_lld_start(&SARADC12D2, &saradc_config_saradcconf);
from the task2 into main, just after the function sd_lld_start. If you do not change the driver configuration, it is not necessary to start the driver each time a new conversion must be issued. Then, could you share the ADC driver configuration?
Regards,
Luigi
2021-03-08 12:50 AM
Hello,
thanks for your answer it helped me a lot. My function works now.
After having made your suggestion, I switched functions, the one became the second etc..
So i create ADC function before PRINTF function, and now my program works perfectly.
Thank you Luigi
Bastien