0

I'm trying to read from a uart port telemetry from a pixhawk 4 device, and forward it to another. I can read it successfully however I am skipping some messages. I've tried using a buffer with size 1 however I believe that was one of my problems.

Thank you for your help

Here's what I have:

My buffers and how I start DMA to get the callback...


/* USER CODE BEGIN 0 */
#define MAX_BUFFER_APS_SIZE 128
uint8_t APS_Buffer[MAX_BUFFER_APS_SIZE];
mavlink_message_t current_message;
mavlink_status_t current_status;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //start DMA buffers
 HAL_UARTEx_ReceiveToIdle_DMA(&huart4, APS_Buffer, MAX_BUFFER_APS_SIZE);
/* USER CODE END 2 */

while loop in main is empty for now. I've commented all so it is just a "continue"

my callback:


/* USER CODE BEGIN 4 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
 if (huart->Instance == UART4) //aps
 {
 for (int i = 0; i < Size; i++)
 {
 uint8_t c = APS_Buffer[i];
 if (mavlink_parse_char(MAVLINK_COMM_1, c, &current_message, &current_status)) {
 ParseMavlinkMessage(current_message);
 last_msg_received_seq_number = current_message.seq;
 // Clear the status for the next iteration
 current_status.packet_rx_drop_count = 0;
 }
 }
 }
}
void ParseMavlinkMessage(mavlink_message_t message)
{
 //sending the message to uart 3
 uint8_t data[MAVLINK_MAX_PACKET_LEN];
 uint16_t len = mavlink_msg_to_send_buffer(data, &message);
 HAL_UART_Transmit(&huart3, data, len, 1000);
 switch(message.msgid)
 {
 case MAVLINK_MSG_ID_OPERATIONAL_STATUS:
 {
 mavlink_msg_operational_status_decode(&message, &operational_status);
 break;
 }
 ... other similar cases...
 }
 //code used to debug that messages are being skipped...
 char msg_to_send[100];
 if(current_message.seq != (last_msg_received_seq_number +1 ) % 256)
 {
 sprintf(msg_to_send, "Autopilot Parsing Thread - Message skipped -> %d | previous message was -> %d\n\r", current_message.seq, last_msg_received_seq_number);
 HAL_UART_Transmit(&huart3, (uint8_t *)msg_to_send, strlen(msg_to_send), 1);
 }
...some other logic...
}
asked Jul 31, 2023 at 11:29

1 Answer 1

2

Your interrupt callback function should be as short as possible and definitely not parse and send the data. It should only manage the buffer and return. The parsing and sending should be done by the main program or another task if you use RTOS. It is a general rule - interrupt handlers have to be as short and fast as possible. Do not use them to implement program logic.

I would encourage you to learn how to use RTOS-es, as they make similar tasks much easier and have IPC mechanisms implemented (so you will not have to reinvent the wheel) or implement complicated state machines in your main loop.

answered Jul 31, 2023 at 11:40
Sign up to request clarification or add additional context in comments.

4 Comments

I've tried FREERTOS, however I was running in many problems. that RTOS-es is not on my list (using stm32f303re in the "middleware and software packs" tab). All I need is basically read mavlink from a uart port and forward it to another port depending on the message. I'm relatively new to STM32, can i install other OS that are not on the list?
@JoãoFerreira DMA requires async programming and your program logic is invalid. For you read blocking in the main loop
What would you do if it was you? Do you think I should use freeRTOS?
@JoãoFerreira it is up to you. I almost always use RTOS

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.