SLCAN 串口转CAN

本文详细介绍了SLCAN协议,包括11位和29位帧类型的描述,以及SLCAN帧的ASCII格式。此外,还解析了SLCAN驱动的实现,包括串口线路规程、注册网络接口和数据的发送与读取。最后,提供了设置CAN工具、串口参数、CAN参数以及数据收发的实际操作步骤。


一、SLCAN协议
     slcan 即serial line CAN interface driver (using tty line discipline)
    通用标准协议参考:http://www.mirrorservice.org/sites/downloads.sourceforge.net/s/so/socketcan.berlios/SLCAN-API.pdf

SLCAN 帧的ASCII 描述如下:

  <type> <id> <dlc> <data>

 type的定义: 

  t => 11 bit data frame 标准帧

  r => 11 bit RTR frame  带RTR的标准帧

  T => 29 bit data frame ID扩展帧

  R => 29 bit RTR frame  带RTR的ID扩展帧


id 为3个字节的ASCII Hex,扩展为8个字节的ASCII Hex。

dlc 一个字节的ASCII 数字 ('0'~'8')

data ASCII的16进制,个数为dlc。


例:

t1230 : can_id 0x123, can_dlc 0, no data

t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33

T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55

r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request





二、SLCAN驱动
     文件路径:linux/drivers/net/can/slcan.c

1. 串口线路规程

驱动初始化函数:slcan_init(void);

线路规程接口:tty_register_ldisc(N_SLCAN, &slc_ldisc);

slc_ldisc can操作定义如下:

static struct tty_ldisc_ops slc_ldisc = {

.owner = THIS_MODULE,

.magic = TTY_LDISC_MAGIC,

.name = "slcan",

.open = slcan_open,

.close = slcan_close,

.hangup = slcan_hangup,

.ioctl = slcan_ioctl,

.receive_buf = slcan_receive_buf,

.write_wakeup = slcan_write_wakeup,

};

2. 注册网络接口

选择空闲的通道,关联对应的tty接口,注册网络接口.

slcan_open(struct tty_struct *tty);

收集悬空的通道。

slc_sync();

/* OK.  Find a free SLCAN channel to use. */

    把tty接口关联到空闲的通道。

sl = slc_alloc(tty_devnum(tty));

sl->tty = tty;

tty->disc_data = sl;

注册网络设备

register_netdevice(sl->dev);


struct slcan {

int magic;

/* Various fields. */

struct tty_struct *tty; /* ptr to TTY structure      */

struct net_device *dev; /* easy for intr handling    */

spinlock_t lock;

/* These are pointers to the malloc()ed frame buffers. */

unsigned char rbuff[SLC_MTU]; /* receiver buffer      */

int rcount;         /* received chars counter    */

unsigned char xbuff[SLC_MTU]; /* transmitter buffer      */

unsigned char *xhead;         /* pointer to next XMIT byte */

int xleft;          /* bytes left in XMIT queue  */

unsigned long flags; /* Flag values/ mode etc     */

#define SLF_INUSE 0 /* Channel in use            */

#define SLF_ERROR 1               /* Parity, etc. error        */

};


3. 发送数据

从串口接收数据并发送到网络层.


static void slcan_receive_buf(struct tty_struct *tty,

      const unsigned char *cp, char *fp, int count)


/* parse tty input stream */

slcan_unesc(sl, *cp++);

发送一个CAN帧到网络层.

slc_bump(struct slcan *sl)

     netif_rx_ni(skb);


-------------------------------------------------------------------


/*

 * Called by the driver when there's room for more data.  If we have

 * more packets to send, we send them here.

 */
4. 读取数据

static void slcan_write_wakeup(struct tty_struct *tty)


actual = tty->ops->write(tty, sl->xhead, sl->xleft);

---------------------------------------------------------------------

三、操作及应用

1. 获取CAN 工具

$git clone https://git.gitorious.org/linux-can/can-utils.git

编译并安装


2. 设置串口参数

$sudo stty -F /dev/ttyS0 921600 -parity -cstopb

3. 设置CAN参数

$sudo slcan_attach -w -o -s6 /dev/ttyS0

4. 发送数据

$sudo ifconfig slcan0 up

$sudo cangen slcan0 –g 100

5. 接收数据

$sudo ifconfig slcan0 up

$sudo candump slcan0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值