STM32 - 使用 DMA + 循环缓冲区解析 mavlink 2 时出现问题

问题描述 投票:0回答:1

我正在尝试从 pixhawk 4 设备的 uart 端口遥测数据中读取数据,并将其转发到另一个设备。 我可以成功阅读它,但我跳过了一些消息。 我尝试过使用大小为 1 的缓冲区,但我相信这是我的问题之一。

谢谢您的帮助

这是我所拥有的:

我的缓冲区以及如何启动 DMA 来获取回调...


/* 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 */

main 中的 while 循环目前为空。我已经全部评论了,所以这只是“继续”

我的回电:


/* 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...

}

c stm32 dma mavlink
1个回答
0
投票

你的中断回调函数应该尽可能短,并且绝对不解析和发送数据。它应该只管理缓冲区和返回。如果使用 RTOS,解析和发送应该由主程序或其他任务完成。这是一条一般规则——中断处理程序必须尽可能短且快。不要使用它们来实现程序逻辑。

我鼓励您学习如何使用 RTOS-es,因为它们使类似的任务变得更加容易,并且实现了 IPC 机制。

© www.soinside.com 2019 - 2024. All rights reserved.