sja1000-CAN控制器socket驱动移植

在徐老师的指导下移植了一个通过Plx9030 PCI-localbus桥片扩展的两片sja1000 CAN控制器的驱动。现整理如下:

首先,内核drivers/net/can/sja1000/plx_pci.c是移植的初始文件,适当修改该文件即可为我所用。

<1>首先把各个声明换成自己公司板卡的相关信息,不换也可以,这点无关紧要。主要先看代码开头部分的各种宏

       定义,里边有关于最大支持设备,CAN时钟等关键信息,根据自身情况修改。

<2> 重点来了,在   static struct plx_pci_card_info  plx_pci_card_info_tews  __devinitdata={

"esd CAN-PCI/CPCI/PCI104/200",2 ,

PLX_PCI_CAN_CLOCK,PLX_PCI_OCR, PLX_PCI_CDR,

{0, 0x00,0x00},{{2, 0x00, 0x80},{2, 0x100,0x80}},

&plx_pci_reset_common

/*based on PLX9030/9050*/

注意,在代码里有数个类似的结构体,主要是为了支持不同的设备,一个结构体就是一个对应的设备的描述。

该结构体定义如下:

struct plx_pci_card_info {
const char *name;
int channel_count;
u32 can_clock;
u8 ocr; /* output control register */
u8 cdr; /* clock divider register */

/* Parameters for mapping local configuration space */
struct plx_pci_channel_map conf_map;

/* Parameters for mapping the SJA1000 chips */
struct plx_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CHAN];

/* Pointer to device-dependent reset function */
void (*reset_func)(struct pci_dev *pdev);
};

上述结构体定义可知,主要是最后三个元素,conf_map这个元素对应配置寄存器信息,

即plx9030的配置控制寄存器的位置大小描述,chan_map_tbl[PLX_PCI_MAX_CHAN]该结构体对应各个sja1000寄存器地址。

若想真正了解需要再看下一个结构体定义:

struct plx_pci_channel_map {
u32 bar;
u32 offset;
u32 size; /* 0x00 - auto, e.g. length of entire bar */
};

看到这明白了吧,第一个是对应的bar,第二个是你自己的旗舰寄存器在该bar上对应的偏移,第三个是映射空间的大小。

这样就可以理解最初的那个填写的结构体{0, 0x00,0x00},{{2, 0x00, 0x80},{2, 0x100,0x80}}的具体意义了,既该plx9030配置

寄存器对应该PCI设备的bar0,偏移0,大小为0,大小无关紧要,主要是通过前两个参数获得配置寄存器的地址,而后两个

参数意思是在bar2上有两个SJA1000,一个偏移0,一个偏移0x100,映射大小都为0x80.

<3>上边都修改完了就该修改

static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = {
{
0xebed, 0xc303,
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
(kernel_ulong_t)&plx_pci_card_info_tews
},
{ 0,}
};
MODULE_DEVICE_TABLE(pci, plx_pci_tbl);

自己的PCI的厂商ID和设备ID填写上,主要红色代码的结构体变量要和上边你修改的那个对应上。

这基本上就可以了。


当然对于你的设备可能还不够,看上述代码之后,还有两个读写的包装函数

static u8 plx_pci_read_reg(const struct sja1000_priv *priv, int port)
{
return ioread8(priv->reg_base + port);
}


static void plx_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
{
iowrite8(val, priv->reg_base + port);
}

可以根据自己板子的实际情况更改读写方式。

最后,把自己板卡的一些初始化配置放进函数

/*
  * Probe PLX90xx based device for the SJA1000 chips and register each
  * available CAN channel to SJA1000 Socket-CAN subsystem.
  */
static int __devinit plx_pci_add_card(struct pci_dev *pdev,
      const struct pci_device_id *ent)

即可。









  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值