Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The third of SylixOS SylixOS CAN bus drivers

2025-04-07 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

SylixOS CAN message transfer flow CAN message transfer flow chart

The transmission block diagram of the CAN message in SylixOS is shown in figure 11.

Fig. 11 Block diagram of SylixOS CAN message transmission

(note: this document continues the writing of the previous document, the message described in detail in the previous document, and the transmission structure is not described in detail in this document. )

SylixOS CAN message caching mechanism

The transmission of CAN messages in SylixOS is not the direct transmission of the underlying and upper applications. Instead, a layer of system cache queue is added between the underlying layer and the application layer. All CAN messages sent and received must first be transmitted through a system cache mechanism to the place where it is actually called.

System CAN send message cache

The CAN message in SylixOS is cached in the way of message queue. Listing 21 is the concrete implementation of writing a frame of CAN message to the message queue.

Listing 21 reads a CAN message from the cache

/ * function name: _ _ canITx** Function description: read a data from the send buffer * * input: * * pcanDev CAN device * * pcanframe points to the data to be read * * output: ERROR_NONE or PX_ERROR** global variable: * * call module: * * / static INT _ _ canITx (_ _ CAN_DEV * pcanDev PCAN_FRAME pcanframe) {INTREG iregInterLevel INT iTemp = 0; if (! pcanDev | |! pcanframe) {return (PX_ERROR);} iTemp = _ _ canReadQueue (pcanDev, pcanDev- > CAN_pcanqSendQueue, pcanframe, 1) / * read a frame of data from the send queue * / LW_SPIN_LOCK_QUICK (& pcanDev- > CAN_slLock, & iregInterLevel); if (iTemp CAN_canstatWriteState.CANSTAT_bBufEmpty = LW_TRUE; / * send queue empty * /} LW_SPIN_UNLOCK_QUICK (& pcanDev- > CAN_slLock, iregInterLevel); API_SemaphoreBPost (pcanDev- > CAN_ulSendSemB) / * release semaphore * / SEL_WAKE_UP_ALL (& pcanDev- > CAN_selwulList, SELWRITE); / * release all threads waiting to write * / return ((iTemp)? (ERROR_NONE): (PX_ERROR);}

System CAN receive message cache

When the upper layer application transmits a frame of CAN message to the bottom layer, it is also through the system cache to write a frame of CAN message to the system cache, as shown in listing 22.

Listing 22 writes a CAN message to the cache

/ * function name: _ _ canIRx** Function description: write a data to the receive buffer * * input: * * pcanDev CAN device * * pcanframe points to the data to be written * * output: ERROR_NONE or PX_ERROR** global variable: * * call module: * * / static INT _ _ canIRx (_ _ CAN_DEV * pcanDev PCAN_FRAME pcanframe) {INT iTemp = 0 If (! pcanDev | |! pcanframe) {return (PX_ERROR);} iTemp = _ _ canWriteQueue (pcanDev, pcanDev- > CAN_pcanqRecvQueue, pcanframe, 1); / * write a frame of data to the receive queue * / API_SemaphoreBPost (pcanDev- > CAN_ulRcvSemB) / * release semaphore * / SEL_WAKE_UP_ALL (& pcanDev- > CAN_selwulList, SELREAD); / * select () activate * / return ((iTemp)? (ERROR_NONE): (PX_ERROR);}

Specific call to realize the transfer from the application layer to the driver layer

Step 1: create a thread in the application layer and open a CAN device, as shown in listing 31.

Listing 31 opens the CAN device

IFd = open (devname, O_RDWR, 0666); if (iFd

< 0) { printf("failed to open %s!\n", devname); return (LW_NULL); } 第二步:如程序清单 32所示,填充一个CAN报文结构体。 程序清单 32填充CAN报文 CAN_FRAME canframe;canframe.CAN_bExtId = LW_FALSE;canframe.CAN_bRtr = LW_FALSE;canframe.CAN_ucLen = CAN_MAX_DATA;lib_memcpy((CHAR *)canframe.CAN_ucData, "01234567", CAN_MAX_DATA);canframe.CAN_uiId = 0; 第三步:如程序清单 33所示,调用write函数向系统TX缓存队列中写入一帧CAN报文,再调用ioctl函数实现底层传输。 程序清单 33填充发送缓存 stLen = write(iFd, &canframe, sizeof(CAN_FRAME));ioctl(iFd, CAN_DEV_STARTUP, 0);case CAN_DEV_STARTUP: __flexcanStartup(pCanchan); break; 第四步:如程序清单 34所示,最终调用到底层传输函数。从系统队列中读取一帧CAN报文后对设备寄存器进行相关操作将消息传输到总线上。 程序清单 34底层starup函数 /*********************************************************************************************************** 函数名称: __flexcanStartup** 功能描述: 启动数据发送** 输 入 : pCanchan 通道对象** 输 出 : NONE** 全局变量:** 调用模块:*********************************************************************************************************/static INT __flexcanStartup (CAN_CHAN *pCanchan){ FLEXCAN_CHAN *pChannel = container_of(pCanchan, FLEXCAN_CHAN, CANCH_canchan); CAN_FRAME canFrame; INT iCount; if (!pChannel->

CANCH_pcbGetTx) {return (PX_ERROR);} while (pChannel- > CANCH_pcbGetTx (pChannel- > CANCH_pvGetTxArg, / * read data from the send buffer * / & canFrame) = = ERROR_NONE) {_ _ flexcanSend (pChannel, & canFrame);} return (ERROR_NONE);}

Note: if you want to send multiple frames of CAN messages, you need to wait after the write operation to ensure that all CAN messages are successfully written to the system cache queue.

The driver layer is transferred to the application layer

Step 1: if the underlying layer receives the CAN message, it will trigger an interrupt. What you do in the interrupt service function is to determine the position of the status flag. If it is a received interrupt, the received CAN message is written through the callback function, and the system caches the queue, as shown in listing 35 of the program.

Listing 35 CAN underlying interrupt service function

/ * function name: _ _ flexcanIrq** Function description: can interrupt service program * * input: pChannel channel object * * ulVector interrupt vector number * * output: ERROR CODE** global variable: * * call module: * * * / static irqreturn_t _ _ flexcanIrq (PVOID pvArg ULONG ulVector) {FLEXCAN_CHAN * pChannel UINT32 uiIflag1, uiEsr, uiValue; CAN_FRAME canframe; can_debug ("[CAN] irq\ r\ n"); pChannel = (FLEXCAN_CHAN *) pvArg; uiIflag1 = CAN_READ (FLEXCAN_IFLAG1); uiEsr = CAN_READ (FLEXCAN_ESR1); uiValue = CAN_READ (FLEXCAN_CTRL1); uiValue & = ~ (FLEXCAN_CTRL1_ERR_ALL); CAN_WRITE (FLEXCAN_CTRL1, uiValue) CAN_WRITE (FLEXCAN_IMASK1, 0); if (uiEsr & FLEXCAN_ESR1_ERR_ALL) {can_debug ("There is something wrong!\ n"); CAN_READ (FLEXCAN_ESR1); CAN_WRITE (FLEXCAN_ESR1, FLEXCAN_ESR1_ERR_ALL) } if (uiEsr & FLEXCAN_ESR1_RX) {if (uiIflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) {CAN_WRITE (FLEXCAN_IMASK1, FLEXCAN_IFLAG_DEFAULT & ~ FLEXCAN_IFLAG_RX_FIFO_AVAILABLE); memset (& canframe, 0, sizeof (CAN_FRAME)); _ flexcanRecv (pChannel, & canframe) If (pChannel- > CANCH_pcbPutRcv (pChannel- > CANCH_pvPutRcvArg, & canframe)! = ERROR_NONE) {pChannel- > CANCH_pcbSetBusState (pChannel- > CANCH_pvSetBusStateArg, CAN_DEV_BUS_RXBUFF_OVERRUN) } if (uiIflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {can_debug ("FIFO overflow\ n"); CAN_WRITE (FLEXCAN_IFLAG1, FLEXCAN_IFLAG_RX_FIFO_OVERFLOW);} CAN_WRITE (FLEXCAN_IMASK1, FLEXCAN_IFLAG_DEFAULT); return (LW_IRQ_HANDLED);}

Step 2: create a thread in the application, and what you do in the thread is to continuously read the message queue cached by the system. If the cache is not empty, read the CAN message inside and print it, as shown in listing 36.

Listing 36 CAN application layer read cache

While (1) {stLen = read (iFd, & canframe, sizeof (STR_CANMSG_T)); stFrameNum = stLen / sizeof (STR_CANMSG_T); if (stFrameNum! = 1) {printf ("failed to recv canframe, abort recving!\ n"); break } else {sprintf (cFramInfo, "id=%d, len=%d, data=x x x x x x x x\ n", canframe.Id, (INT) canframe.DLC, canframe.Data [0], canframe.Data [1], canframe.Data [2], canframe.Data [3] Canframe.Data [4], canframe.Data [5], canframe.Data [6], canframe.Data [7]) Printf (cFramInfo);}}

CAN message transmission process, which ends here.

Disclaimer

Internal communication documents, if you find relevant errors or suggestions, please contact the document creator for revision and update.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report