linux can编程,linux CAN编程(二)----------- can_frame中can_id的数据组织形式及处理
转载自:https://blog.csdn.net/qwaszx523/article/details/54984544
/**
* struct can_frame - basic CAN frame structure
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
* @can_dlc: frame payload length in byte (0 .. 8) aka data length code
* N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
* mapping of the 'data length code' to the real payload length
* @data: CAN frame payload (up to 8 byte)
*/
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
can_id定义如下所示,是一个无符号的32位整形数
typedef __u32 canid_t;
can_id数据组织形式如下
/*
* Controller Area Network Identifier structure
*
* bit 0-28 : CAN identifier (11/29 bit)
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
* bit 30 : remote transmission request flag (1 = rtr frame)
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/
0-28位为标识符,如果是扩展帧,则高11位为标准ID
29位标识是数据帧还是错误消息
30位说明是否是远程帧
31位说明是标准帧还是扩展帧。
以下是在处理can_frame时用到的掩码和标识符:
/* special address description flags for the CAN_ID */
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */
/* valid bits in CAN ID for frame formats */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
对can_frame的处理是在mcp251x_hw_tx中进行的,如下:
static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
int tx_buf_idx)
{
struct mcp251x_priv *priv = spi_get_drvdata(spi);
u32 sid, eid, exide, rtr;
u8 buf[SPI_TRANSFER_BUF_LEN];
exide = (frame->can_id & CAN_EFF_FLAG) ? 1 : 0; //取can_id的31位,判断是标准帧还是扩展帧
if (exide)
sid = (frame->can_id & CAN_EFF_MASK) >> 18;//如果是扩展帧,can_id的0-28位为ID,其中高11位为标准ID
else
sid = frame->can_id & CAN_SFF_MASK; /* Standard ID */
eid = frame->can_id & CAN_EFF_MASK; /* Extended ID */
rtr = (frame->can_id & CAN_RTR_FLAG) ? 1 : 0; /* 是否是远程帧*/
buf[TXBCTRL_OFF] = INSTRUCTION_LOAD_TXB(tx_buf_idx); //发送缓冲器控制寄存器地址
buf[TXBSIDH_OFF] = sid >> SIDH_SHIFT; //发送缓冲器标准ID高8位
//5-7位存放发送缓冲器低3位,3位存放帧格式,0-1位存放扩展标识符低18位的高两位(16-17)
buf[TXBSIDL_OFF] = ((sid & SIDL_SID_MASK) << SIDL_SID_SHIFT) | (exide << SIDL_EXIDE_SHIFT) | ((eid >> SIDL_EID_SHIFT) & SIDL_EID_MASK);
buf[TXBEID8_OFF] = GET_BYTE(eid, 1); //存放扩展标识符低18位的8-15位
buf[TXBEID0_OFF] = GET_BYTE(eid, 0); //扩展标识符低18位的低8位(0-7)
buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; //6位存放远程帧标识符,0-3存放数据长度码
memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);//拷贝要发送的数据
mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
/* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
mcp251x_spi_trans(priv->spi, 1);
}
static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
int buf_idx)
{
struct mcp251x_priv *priv = spi_get_drvdata(spi);
if (mcp251x_is_2510(spi)) {
int i, len;
for (i = 1; i < RXBDAT_OFF; i++)
buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
len = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
for (; i < (RXBDAT_OFF + len); i++)
buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
} else {
priv->spi_tx_buf[RXBCTRL_OFF] = INSTRUCTION_READ_RXB(buf_idx);
mcp251x_spi_trans(spi, SPI_TRANSFER_BUF_LEN);
memcpy(buf, priv->spi_rx_buf, SPI_TRANSFER_BUF_LEN);
}
}
---------------------
作者:qwaszx523
来源:CSDN
原文:https://blog.csdn.net/qwaszx523/article/details/54984544
版权声明:本文为博主原创文章,转载请附上博文链接!
linux can编程,linux CAN编程(二)----------- can_frame中can_id的数据组织形式及处理相关推荐
- (二)Linux设备驱动的模块化编程
本系列导航 (一)初识Linux驱动 (二)Linux设备驱动的模块化编程 (三)写一个完整的Linux驱动程序访问硬件并写应用程序进行测试 (四)Linux设备驱动之多个同类设备共用一套驱动 (五) ...
- Linux shell 脚本编程-实战篇(二)
继: Linux shell 脚本编程-实战篇(一) 2. 创建与数据库.Web及电子邮件相关的脚本 2.1 MySQL 数据库 2.1.1 MySQL 数据库安装 到 http://repo.mys ...
- 进程返回linux系统编程之管道(二):管道读写规则和Pipe Capacity、PIPE_BUF
题记:写这篇博客要主是加深自己对进程返回的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. 一. 当没有数据可读时 O_NONBLOCK disable:read调用阻塞,即进程暂停 ...
- linux系统编程之管道(二):管道读写规则和Pipe Capacity、PIPE_BUF
一. 当没有数据可读时 O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止. O_NONBLOCK enable:read调用返回-1,errno值为EAG ...
- 6、linux网络编程--UDP协议编程
一.概述: UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一个简单的面向数据报的运输层协议,在网络中用于处理数据包,是一种无连接的协议.UDP 不提供可 ...
- linux Shell(脚本)编程入门实例讲解详解
linux Shell(脚本)编程入门实例讲解详解 为什么要进行shell编程 在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具.Shell不仅仅是命令的收集, ...
- linux c语言 ppt,linux操作系统下c语言编程入门.ppt
linux操作系统下c语言编程入门.ppt Linux操作系统下C语言编程入门 CNT Linux操作系统简介基础知识进程介绍文件操作时间概念消息管理线程操作网络编程Linux下C开发工具介绍 一 L ...
- step1.day12 Linux下使用C语言编程基础总结
一:系统准备 1.VMware软件安装,用来在现在操作系统下模拟Linux系统而不必重装系统 2.Linux系统安装,推荐使用Ubuntu14.02版本,较为稳定 注意:安装步骤,选择稍后安装虚拟机, ...
- Linux与C++11多线程编程(学习笔记)
多线程编程与资源同步 在Windows下,主线程退出后,子线程也会被关闭; 在Linux下,主线程退出后,系统不会关闭子线程,这样就产生了僵尸进程 3.2.1创建线程 Linux 线程的创建 #inc ...
最新文章
- 最新!2020中国高校毕业生薪资报告出炉
- java中定义score方法_elasticsearch 自定义 script score JavaAPI查询详解
- 剑指_数组中出现次数超过一半的数字
- POJ 3522 Slim Span (Kruskal枚举最小边)
- 【OpenGL】十四、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_STRIP 三角形 | GL_TRIANGLE_STRIP 三角形绘制分析 )
- rtx3090能组成超级计算机吗,「必看分析」技嘉rtx3090超级雕评测?功能真的不好吗...
- [SCOI2014]方伯伯的OJ
- iOS 6 的5个新特性创建杀手级应用
- 又被野外利用了!新曝光Office产品多个远程命令执行漏洞分析
- L1-040 最佳情侣身高差-PAT团体程序设计天梯赛GPLT
- 如何使用 @ OutputCache 指令的 VaryByCustom 属性来缓存不同版本的页面(二)
- 2017CodeM复赛
- ps 毛发 边缘_【常用抠图小技巧】PS调整边缘扣毛发
- c语言关键字c11,_Generic关键字及其语法和应用(C11标准),C语言_Generic详解
- Linux 编译安装 ghostscript 最新版
- php命名空间的设计思想和缺点
- JVM 运行机制及其原理
- 解决数据库高并发的常见方案
- 番外篇:韩国网游兴起
- 容器编排之战——kubernetes
热门文章
- 《LINUX3.0内核源代码分析》第二章:中断和异常 【转】
- PhpStorm 配置Xdebug
- Iperf源代码分析(八)
- sysbench对数据库的性能测试
- MVC 自定义分面控件
- C#完美任意设置webBrowser框架默认的IE内核版本
- 使用uploadify上传图片时返回“Cannot read property 'queueData' of undefined”
- ASP.NET配置错误页面浅析
- 算法代码_Python进化算法之多目标优化与代码实战
- MySQL 存储引擎(MyISAM、InnoDB、NDBCluster)