日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux can编程,linux CAN编程(二)----------- can_frame中can_id的数据组织形式及处理

發布時間:2024/9/19 linux 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的数据组织形式及处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。