目前我使用rt_thread版本为v4.1.1,目前使用了两路can,想要对两路can的数据进行硬件过滤处理,降低CPU负荷。
过滤的ID为:
#define STEER_STA_FEEDBACK_MSG_ID 0x203
#define BRAKE_STA_FEEDBACK_MSG_ID 0x202
#define DRIVE_STA_FEEDBACK_MSG_ID 0x201
#define BMS_STA_FEEDBACK_MSG_ID 0x1884EFF3
#define MCU_STA_FEEDBACK_MSG_ID 0x0C0221E
#define WHEEL_ROTATE_FEEDBACK_MSG_ID 0x18FEF115
初始化代码如下:
#ifdef RT_CAN_USING_HDR
CanDevRecFilterCfg can1_dev_filter;
CanDevRecFilterCfg can2_dev_filter;
#endif
#ifdef RT_CAN_USING_HDR
CanDevRecFilterCfg * GetFilterCfgPtr(CanCfgEnum _type)
{
CanDevRecFilterCfg * _cfg = RT_NULL;
switch (_type)
{
case CAN1_DEV_CFG:
_cfg = &can1_dev_filter;
break;
case CAN2_DEV_CFG:
#ifndef APP_USING_CAN2_DEV
LOG_E("Pls config switch the app using can2 dev");
break;
#endif
_cfg = &can2_dev_filter;
break;
default:
break;
}
return _cfg;
}
/**
* @brief Set the Can Dev I D Filter object
* @param _type CAN设备索引
* @param match_id 需要过滤的ID
* @return rt_err_t RT_EOK 成功 -RT_ERROR失败
*/
rt_err_t SetCanDevIDFilter(CanCfgEnum _type,rt_uint32_t match_id)
{
struct rt_can_filter_item _temp_filter = RT_CAN_FILTER_EXT_INIT(match_id,RT_NULL, RT_NULL);
struct can_app_struct *_can_dev_cfg = RT_NULL;
CanDevRecFilterCfg * _cfg = GetFilterCfgPtr(_type);
RT_ASSERT(_cfg != RT_NULL);
if((_cfg->used_filter_num+1) > 27)
{
LOG_E("Beyond the max filter num!!");
return RT_ERROR;
}
if(match_id > 0x7FF)
{
//过滤的是扩展帧
_temp_filter.ide = 1;
_cfg->filter[_cfg->used_filter_num] = _temp_filter;
}
else
{
_temp_filter.ide = 0;
_cfg->filter[_cfg->used_filter_num] = _temp_filter;
}
//执行配置操作
_cfg->filter_cfg.items = _cfg->filter;
_cfg->filter_cfg.count = _cfg->used_filter_num+1;
_cfg->filter_cfg.actived = 1;
//更新配置
_can_dev_cfg = GetCanCfg(_type);
RT_ASSERT(_cfg != RT_NULL);
if(rt_device_control(_can_dev_cfg->dev, RT_CAN_CMD_SET_FILTER, &_cfg->filter_cfg) != RT_EOK)
{
return -RT_ERROR;
}
_cfg->used_filter_num++;
return RT_EOK;
}
#endif
我分别对can1 和can2进行了3组hdr配置,最终的表现结果为在接收部分只能收到ID为0x18FEF115或者ID为0x0C0221E的数据,其余的都收不到。
我这样的需求应该怎么样配置HDR才能正确进行接收呢?我使用官网的例程也存在这个问题。
问题已经得到解决了。在4.1.1的drv_can.c的339行处,代码有问题
if (filter_cfg->items[i].hdr == -1)
{
/* use default filter bank settings */
if (drv_can->name == "can1")
{
/* can1 banks 0~13 */
drv_can->FilterConfig.FilterBank = i;
}
else if (drv_can->name == "can2")
{
/* can1 banks 14~27 */
drv_can->FilterConfig.FilterBank = i + 14;
}
}
else
{
/* use user-defined filter bank settings */
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
}
将这个部分修改为
if (filter_cfg->items[i].hdr == -1)
{
/* use default filter bank settings */
if(rt_memcmp(drv_can->name,"can1",sizeof("can1")) == 0)
{
/* can1 banks 0~13 */
drv_can->FilterConfig.FilterBank = i;
}
else if(rt_memcmp(drv_can->name,"can2",sizeof("can2")) == 0)
{
/* can1 banks 14~27 */
drv_can->FilterConfig.FilterBank = i + 14;
}
}
else
{
/* use user-defined filter bank settings */
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
}
就可以了。
最新版中已经修改了这个问题了