我正在尝试从 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, ¤t_message, ¤t_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...
}
你的中断回调函数应该尽可能短,并且绝对不解析和发送数据。它应该只管理缓冲区和返回。如果使用 RTOS,解析和发送应该由主程序或其他任务完成。这是一条一般规则——中断处理程序必须尽可能短且快。不要使用它们来实现程序逻辑。
我鼓励您学习如何使用 RTOS-es,因为它们使类似的任务变得更加容易,并且实现了 IPC 机制。