【STM32】基于RTOS的CAN异步接收转发数据

文章目录

前言

现象:全局变量在 CAN 中断中存储数据,并设置同步标志,在主程序中检测标志后,打包并转发 CAN 数据,会出现 CAN 数据错乱

现象分析:CAN 数据打包处理过程中,新的数据到来,导致数据包部分覆盖;

解决方法:1. 在打包过程中,使用中断屏蔽,保护全局 CAN 数据;2. 使用环形缓冲区保存数据;3.使用队列同步数据

方法分析:方法1裸机平台最简单,但会造成中断响应不及时,丢失部分数据,同样会干扰其他中断数据的接收,比如串口中断等;方法2需要对数据结构进行处理,协商存放和取出的规则;方法3利用 RTOS 平台特性,简单高效,数据处理最为安全可靠

实现

数据结构

c 复制代码
#define BSP_CAN_DATA_LEN 8

typedef struct
{
    CAN_RxHeaderTypeDef hdr;
    uint8_t payload[BSP_CAN_DATA_LEN];
} bsp_ecu_can_t;

创建队列

c 复制代码
osMessageQueueId_t canQueueHandle;
const osMessageQueueAttr_t canQueue_attributes = {
    .name = "canQueue"};

canQueueHandle = osMessageQueueNew(50, sizeof(bsp_ecu_can_t), &canQueue_attributes);

中断接收数据

c 复制代码
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcanx)
{
    bsp_ecu_can_t data = {0};
    osStatus_t stat = osOK;

    if (hcanx->Instance == hcan.Instance)
    {
        // 读取接收数据
        if (HAL_CAN_GetRxMessage(hcanx, CAN_RX_FIFO0, &data.hdr, data.payload) == HAL_OK)
        {

            // 推送队列
            stat = osMessageQueuePut(canQueueHandle, &data, 0, 0);
            if (stat != osOK)
            {
                LOG_D("canQueueHandle: %d", osMessageQueueGetCount(canQueueHandle));
                LOG_D("Can inData Put Fail!: %d", stat);
            }

            // 重新开启接收
            HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
        }
    }
}

线程处理数据

c 复制代码
void bsp_ecu_can_data_queue_handle(void)
{
    bsp_ecu_can_t msg = {0};

    // 取数据
    if (osMessageQueueGet(canQueueHandle, &msg, 0, osWaitForever) == osOK)
    {
        // TODO: 数据处理
        // todo_can_process(msg);

        LOG_V("CAN --> CAT1: %d", osMessageQueueGetCount(canQueueHandle));
    }
}
相关推荐
Zw-awa11 分钟前
从 CPU 搬运到自动搬运:DMA、空闲中断和两块缓冲
stm32
无敌贵点大王33 分钟前
从寄存器层面重学STM32(6)——串口USART实战部分
stm32·单片机·嵌入式硬件
庙堂龙吟奈我何37 分钟前
二进制和十六进制
stm32·单片机
国科安芯2 小时前
长期在轨的计算底座:商业空间站与在轨服务飞行器健康管理中的抗辐射MCU—— 面向可维护空间平台的分层容错与安全通信综述
人工智能·单片机·嵌入式硬件·安全·低轨卫星·抗辐射
TST-魚爷2 小时前
小型视频会议室音频踩坑:一体化拾音扩音方案实测分享(易视讯)
stm32·电脑·音视频·钉钉·腾讯会议·zoom会议
不昀4 小时前
RMII切到10Mbps,50MHz参考时钟也要降到5MHz吗?
单片机·嵌入式硬件·硬件设计·以太网接口
路上有只喵5 小时前
认识元器件 · 单片机(MCU/MPU/SOC) · 实战篇6
单片机·嵌入式硬件
国科安芯6 小时前
核电站蒸汽发生器传热管在役无损检测模拟前端的低噪声供电研究
嵌入式硬件·ldo·低压差线性稳压器·无损检测·核电站·蒸汽发生器·传热管
集芯微电科技有限公司7 小时前
40V/24A高频率增强型GaN HEMT功率开关管/高频DC转换/电动工具/GaN充电器 方案首选
人工智能·科技·单片机·嵌入式硬件·深度学习·神经网络·生成对抗网络
十八岁牛爷爷7 小时前
STM32H7 长时间运行后 HTTP 断连:从“串口还活着”到 TX 描述符错账
stm32·单片机·嵌入式硬件