I am running an application which reads ADC data through DMA at a frequency of 12kHz and transfers the captured data in a queue as soon as I get an interrupt.
Following is the configuration
- STM32L496
- CMSIS RTOS 2
Following are the problems I am facing:
- Higher priority task gets initialized and running before other tasks are initialized.
- Getting different errors when queue size is changed
osThreadId_t main_task_id;
osThreadId_t acquisition_task_id;
const osThreadAttr_t main_thread_attr = {
.stack_size = 1024U,
.priority = osPriorityAboveNormal3,
};
const osThreadAttr_t acq_thread_attr = {
.stack_size = 1024U,
.priority = osPriorityAboveNormal2,
};
osMessageQueueId_t main_queue_id = NULL;
osMessageQueueId_t acquisition_queue_id = NULL;
main(void)
{
osKernelInitialize();
main_task_init();
acquisition_task_init();
osKernelStart();
}
void main_task(void *argument)
{
osStatus_t status;
message_t msg;
switch_state swt_state;
swt_state = get_switch_state();
if(swt_state == SWITCH_ON)
{
msg.type = START_ADC_CAPTURE;
status = osMessageQueuePut(main_queue_id, &msg, 0U, 0U);
if (status != osOK)
{
// Handle error
}
}
memset(msg, 0x00, sizeof(msg));
while(1)
{
status = osMessageQueueGet(main_queue_id, &msg, NULL, osWaitForever);
if (status != osOK)
{
// Handle error
}
if (msg.type == START_ADC_CAPTURE)
{
// start capturing ADC data
}
}
}
void main_task_init(void)
{
main_queue_id = osMessageQueueNew(10, sizeof(message_t), NULL);
if (main_queue_id == NULL)
{
// Handle error
}
main_task_id = osThreadNew(main_task, NULL, &main_thread_attr);
if (main_task_id == NULL)
{
// Handle error
}
}
void acquisition_task(void *argument)
{
message_t msg;
osStatus_t status;
while(1)
{
status = osMessageQueueGet(acquisition_queue_id, &msg, NULL, osWaitForever);
if (status != osOK)
{
// Handle error
}
}
}
void acquisition_task_init(void)
{
acquisition_queue_id = osMessageQueueNew(10, sizeof(message_t), NULL);
if (acquisition_queue_id == NULL)
{
// Handle error
}
acquisition_task_id = osThreadNew(acquisition_task, NULL, &acq_thread_attr);
if (acquisition_task_id == NULL)
{
// Handle error
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
osStatus_t status;
message_t msg;
memcpy(msg.buff, l_buff, l_buff_size * sizeof(uint16_t));
msg.type = ADC_DATA;
status = osMessageQueuePut(acquisition_queue_id, &msg, 0U, 0U);
if (status != osOK)
{
// Handle error
}
}
When I set acquisition_queue msg_count to 10, osMessageQueueGet(acquisition_queue_id, &msg, NULL, osWaitForever); in acquisition_task is never called and queue becomes full resulting in osErrorResource error.
If I set msg_count to 20, osMessageQueueGet(acquisition_queue_id, &msg, NULL, osWaitForever); gets called but it keeps on waiting and immediately get osRtxErrorISRQueueOverflow error.
How to resolve this issue?
I tried adding random delay before starting capture to see what happens, no change is observed.
ISR FIFO Queue. Currently ISR FIFO Queue is set to 16 and queue length is 10. osMessageQueueGet from acquisition_task is never getting called if ADC with DMA is enabled.