Skip to main content
Explorer
November 9, 2020
Question

Please help me figure out what happens to some array values in RTOS Queues

  • November 9, 2020
  • 1 reply
  • 1231 views

Hello.

I'm trying to design an RF controller for a drone with STM32F103RBT using FREERTOS CMSIS_V2.

The idea is: I have a hardware with some potentiometers, joysticks etc connected to the ADC channels. I have an NRF24L01 as RF transmitter using SPI communication. Finally I wanted to display the data on an OLED display using I2C.

The ADC is triggered using a Timer with 1ms sampling time and the values are stored using DMA.

I have 3 tasks and 2 queues.

Task1 : filters the 6 ADC values, and puts them in the queues - this is tested, and it's working as intended.

Task2: reads the 6 values from queue 1 serialises the data and pushed it to the RF module using SPI.

Task3: reads the 6 values from queue 2 bulds the strings and pushes the values to the OLED.

The communication is working. The threads are working as expected. The problem is with the queues.

Suppose that I put the array {123, 123, 0, 175, 125, 125} into the queue.

On the receiving ends I have {123, 123, 0, 175, 113, 85} and {123, 123, 0, 165, 165}, meaning the last two values won't go through the queue. Also, these two values will never change.

The size of the queues

#define DATA_T	sizeof(uint8_t)*6

The first thread:

void StartDataProcessing(void *argument)
{
 /* USER CODE BEGIN 5 */
	uint8_t y_n[6], y_n_1[6] = {0};
 /* Infinite loop */
 for(;;)
 {
 	// Get the new data
 
 	// Filter the data
 	y_n[0] = (ADC_Data[0]>> 5) + (y_n_1[0]>>1);
 	y_n[1] = (ADC_Data[1]>> 5) + (y_n_1[1]>>1);
 	y_n[2] = (ADC_Data[2]>> 5) + (y_n_1[2]>>1);
 	y_n[3] = (ADC_Data[3]>> 5) + (y_n_1[3]>>1);
 	y_n[4] = (ADC_Data[4]>> 5) + (y_n_1[4]>>1);
 	y_n[5] = (ADC_Data[5]>> 5) + (y_n_1[5]>>1);
 
 	// Store the data
 	y_n_1[0] = y_n[0];
 	y_n_1[1] = y_n[1];
 	y_n_1[2] = y_n[2];
 	y_n_1[3] = y_n[3];
 	y_n_1[4] = y_n[4];
 	y_n_1[5] = y_n[5];
 
 	// Send the data to the thread-safe queue
 	osMessageQueuePut(smoothDataQueueHandle, y_n, 0U, 0U);
 	osMessageQueuePut(nrfQueueHandle, y_n, 0U, 0U);
 
 osDelay(1);
 }
 /* USER CODE END 5 */
}

The second thread:

void StartSender(void *argument)
{
 /* USER CODE BEGIN StartSender */
	uint8_t y_n[6];
	osStatus_t status;
	struct reference_params p;
	uint8_t tx_buffer[20] = {0};
 /* Infinite loop */
 for(;;)
 {
 	status = osMessageQueueGet(nrfQueueHandle, y_n, NULL, 0);
 	if(status == osOK){
 		HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
 		p.mode = 1;
 		p.alt = y_n[0];
 		p.pitch = y_n[1];
 		p.roll = y_n[2];
 		p.yaw = y_n[3];
 
 		memcpy(tx_buffer, &p, sizeof(p));
 		nrf_send(tx_buffer);
 		HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
 	}
 osDelay(3);
 }
 /* USER CODE END StartSender */
}

And the third thread:

void StartDisplayData(void *argument)
{
 /* USER CODE BEGIN StartDisplayData */
	osStatus_t status;
	uint8_t y_n[6];
	char display_num[4] = "000\0";
 
 /* Infinite loop */
 for(;;)
 {
 	status = osMessageQueueGet(smoothDataQueueHandle, y_n, NULL, 0);
 	if(status == osOK){
 		for(uint16_t i= 0; i < 6; ++i){
 				display_num[0] = (y_n[i]/100) + '0';
 				display_num[1] = (y_n[i]/10)%10 + '0';
 				display_num[2] = y_n[i]%10 + '0';
 				if(i < 3){
 					SSD1306_GotoXY(45, 10*(i+1));
 					SSD1306_Puts(display_num, &Font_7x10, 1);
 				}
 				else{
 					SSD1306_GotoXY(103, 10*(i-2));
 					SSD1306_Puts(display_num, &Font_7x10, 1);
 				}
 		}
 		SSD1306_UpdateScreen();
 
 	}
 
 osDelay(30);
 }

For good measures I've attached the whole main.c file.

Maybe it's something simple, but I can't figure out the problem.

Any help would be appreciated.

    This topic has been closed for replies.

    1 reply

    FeherAronAuthor
    Explorer
    November 10, 2020

    Short update here. I couldn't sleep so I've downloaded the OpenRTOS Viewer and found out that although the size of the queues was defined as sizeof(uint8_t)*6 the size in the queue viewer remained 4. This explains why I had garbage in the memory after the 4th element.

    The solution was to hard-code the byte number as #define DATA_T 6.

    I feel a little bit dumb after this one.