cancel
Showing results for 
Search instead for 
Did you mean: 

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

FeherAron
Associate

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.

1 REPLY 1
FeherAron
Associate

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.