CAN

关于CAN驱动框架的一些问题

发布于 2017-08-24 18:17:54
最近在研究CAN驱动,但是最终还是没有将stm32f10x中的can驱动部分过滤器编号相关代码捋清楚,后改将过滤器编号交由用户层去指定分配,这样绕过了不太明白的过滤器分配相关代码,功能也算跑起来了。

但是还有一些疑问:
1. 在CAN驱动框架文件的readme中写道”如果使用硬件过滤,则开启RT_CAN_USING_HDR, maxhdr 为Can控制器过滤表的数量“,但是不定义RT_CAN_USING_HDR照样可以使用硬件过滤器,反而代码量小了逻辑简单了些。是哪里用的不对吗?

2. 水平有限,所以感觉过滤器计算分配相关逻辑有些难,能否简化。

3. 如下代码为什么会有actived变量,要用过滤器不都是要激活吗,要用但是又不激活是什么场景?

struct rt_can_filter_config
{
rt_uint32_t count;
rt_uint32_t actived;
struct rt_can_filter_item *items;
};

查看更多

关注者
0
被浏览
3k
6 个回答
Aubr.Cool
Aubr.Cool 2017-08-25
RT_CAN_USING_HDR 使用这个宏,可以在驱动层上开启多线程接收,每个线程可以挂在一个hdrno上,这样一旦收到一个hdrno号的消息,就能立即唤醒等待的线程。
如上所说,actived的作用是,过滤器可以开启,也可以关闭,适用于动态开启关闭过滤器的情况。

这个硬件过滤器的程序,逻辑,是有点复杂,也有点乱,主要是为了能在用户层给硬件过滤器实现统一的接口,屏闭底层硬件的细节,这样就能在多种CAN控制器上实现代码统一。

怎么能简化一下逻辑,规范一下接口,大家可以一块讨论一下。
对bxcan的过滤器接口,大概是这样定义的


struct stm_bxcanfiltermap
{
rt_uint32_t id32mask_cnt;//32位标识符屏闭过滤器数量
rt_uint32_t id32bit_cnt; //32位标识符列表过滤器数量
rt_uint32_t id16mask_cnt; //16位标识符屏闭过滤器数量
rt_uint32_t id16bit_cnt; //16位标识符列表过滤器数量
};
struct stm_bxcanfilter_masks
{
rt_uint32_t id32maskm[BX_CAN_FILTER_MAX_ARRAY_SIZE]; // 可用的32位标识符屏闭过滤器掩码
rt_uint32_t id32bitm[BX_CAN_FILTER_MAX_ARRAY_SIZE];//可用的32位标识符列表过滤器掩码
rt_uint32_t id16maskm[BX_CAN_FILTER_MAX_ARRAY_SIZE]; //可用的16位标识符屏闭过滤器掩码
rt_uint32_t id16bitm[BX_CAN_FILTER_MAX_ARRAY_SIZE];// //可用的16位标识符列表过滤器掩码
rt_uint32_t id32maskshift[2];// 32位标识符屏闭过滤器起始偏移 每个对应一个FIFO FIFO0 FIFO1
rt_uint32_t id32bitshift[2];//32位标识符列表过滤器起始偏移
rt_uint32_t id16maskshift[2];// 16位标识符屏闭过滤器起始偏移
rt_uint32_t id16bitshift[2];// 16位标识符列表过滤器起始偏移
};
struct stm_bxcan
{
CAN_TypeDef *reg;
void *mfrbase;
IRQn_Type sndirq;
IRQn_Type rcvirq0;
IRQn_Type rcvirq1;
IRQn_Type errirq;
struct stm_bxcanfilter_masks filtermask;
rt_uint32_t alocmask[BX_CAN_FILTER_MAX_ARRAY_SIZE]; //已分配的过滤器索引的掩码,每一位对应一个过滤器
const rt_uint32_t filtercnt;
const rt_uint32_t fifo1filteroff;
const struct stm_bxcanfiltermap filtermap[2];//每个元素对应一个FIFO0 FIFO1
struct rt_can_hdr *hdrhead;
};


bxcan.c实现了对过滤器的管理简单说明,bxcan共有两个过滤器FIFO, FIFO0 和FIFO1
为了方便管理把两个FIFO在软件上合并成一个,每个过滤器对应一个索引值,FIFO1索引值在原有的基础上统一加上一个偏移,这个偏移值为FIFO0的索引值的最大值。
最终过滤器的排列方式如下:
id32mask0个32位屏闭过滤器 FIFO0
id32bit0个32位列表过滤器
id16mask0个16位屏闭过滤器
id16bit0个16位列表过滤器

id32mask1个32位屏闭过滤器 FIFO1
id32bit1个32位列表过滤器
id16mask1个16位屏闭过滤器
id16bit1个16位列表过滤器
emlslxl
emlslxl 2017-08-28
感谢Aubr.Cool的回复,我会按照你的提示重新理解一下示例代码,有好的想法再一起讨论。
Cold
Cold 2019-07-15
Aubr.Cool 发表于 2017-8-25 08:10
RT_CAN_USING_HDR 使用这个宏,可以在驱动层上开启多线程接收,每个线程可以挂在一个hdrno上,这样一旦收到 ...


不错
xangelwu
xangelwu 2019-08-26
跟了半天代码没太弄明白这里,看了说明终于清楚些了

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览