2024-12-18 04:10 AM
I have a STM32F411 board connected with a GPS module connected onto USART2
I also have Tim1 and Tim3 configured for PWM generation on their channels respectively.
I am running a list of commands (from an array) to execute line for line.
Most of the execution is in the form of assigning new values to the Timer channels
Eg: __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, motor1_speed); Motor speed is a variable assigned from the list. As the program executes the list (by iterating line for line, these variables get assigned those values.)
The GPS on the other hand is being polled via USART2
The problem is that I need both the execution of the array as well as the GPS to continue running.
However, the array execution is causing a "blocking issue". I have about 15 lines of instructions in the executing array. The GPS will only work AFTER ALL the commands of the array has been executed due to its blocking issue.
I investigated from many sources who advised:
Any assistance here?
2024-12-18 05:13 AM
There is no reason you can't have these in two different tasks in FreeRTOS.
Note that only one thread can run at a time, it will switch back and forth between them at a relatively fast rate.
> However, the array execution is causing a "blocking issue".
Too vague. Step through the code. What is happening? What do you expect to happen instead?
2024-12-18 05:52 AM - last edited on 2024-12-18 06:15 AM by SofLit
Ok, firstly the answer to your question:
"Too vague. Step through the code. What is happening? What do you expect to happen instead?"
Here is the array:
MotorInstruction instructions[] = {
{'F', {900, 900}, 10}, // Move forward at speed 900 for 10 seconds
{'F', {100, 600}, 3}, // Turn with speeds 500 and 600 for 3 seconds
{'F', {600, 600}, 10}, // Move forward at speed 600 for 10 seconds
{'F', {700, 700}, 3},// Move forward at speed 1000 for 3 seconds
{'F', {900, 900}, 3},
// etc etc.....
};
These figures are assigned to the respective timer channels
eg:
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, motor2_speed);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, motor3_speed);
As the execution iterates (after the time in seconds) it assigns the values to motor2 and motor3 respectively.
That said, these executing lines are blocking the GPS which is automatically coming through the USART2.
You mention RTOS.
I spent hours with the RTOS task. Maybe I was not doing things correctly.
Here is the code:
#define UART_QUEUE_SIZE 64 QueueHandle_t uartQueue;
void GPS_Task(void *pvParameters) { uint8_t received_byte; while (1) { // Wait for a byte from the queue if (xQueueReceive(uartQueue, &received_byte, portMAX_DELAY) == pdPASS) { // Process the byte processGPSData(&received_byte, 1); } } }
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART2) { // Send received byte to the queue xQueueSendFromISR(uartQueue, &received_char, NULL); // Re-enable UART interrupt for next byte HAL_UART_Receive_IT(&huart2, &received_char, 1); } }
In the HAL_UART_RxCpltCallback() I have this:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART2) { // Send received byte to the queue xQueueSendFromISR(uartQueue, &received_char, NULL); // Re-enable UART interrupt for next byte HAL_UART_Receive_IT(&huart2, &received_char, 1); } }
Then in my INT Main
I have this:
// Initialize the FreeRTOS queue
uartQueue = xQueueCreate(UART_QUEUE_SIZE, sizeof(uint8_t));
if (uartQueue == NULL) {
// Handle queue creation error
Error_Handler(); }
// Create the GPS task
xTaskCreate(GPS_Task, "GPS_Task", 128, NULL, 2, NULL); // Stack size = 128, priority = 2
// Start the scheduler
vTaskStartScheduler();
Like I said, this code ought to work. But nothing happens
2024-12-18 06:48 AM
The __HAL_TIM_SET_COMPARE statements do not block. Must be some other reason.
In your FreeRTOS code, you're only creating a task for the GPS. You should have another task for the motor control, if you want them to run concurrently.