本文檔是在AT91SAM9X25平臺上進行SylixOS CAN總線驅動開發時,對CAN總線初始化流程的分析。編程
適用於正在學習CAN總線開發的技術工程師。緩存
CAN總線的初始化流程能夠分紅兩個部分:函數
一部分是CAN總線通道資源初始化,主要工做是對通道相關的管腳和中斷以及總線編程時須要的時鐘等資源的初始化;另外一部分是CAN總線的硬件初始化,主要工做是對總線的波特率的設置、接收和發送數據郵箱(至關於緩存區)的初始化以及接收中斷和錯誤中斷的使能。學習
在AT91SAM9X25平臺上,CAN總線通道資源初始化如圖 21所示。CAN總線的TX管腳、RX管腳和時鐘的使能以及中斷服務函數的綁定是CAN總線在初始化時必須作的工做。CAN總線的通訊須要綁定CAN總線上層回調函數,這些上層回調函數由開發者實現,用作應用層和底層的通訊。時鐘的獲取是總線工做須要用到的數據,咱們在總線初始化時先將其獲取存在全局結構體變量中。ui
圖 21 CAN總線通道資源初始化流程圖atom
具體的代碼實現如程序清單 21所示。spa
程序清單 21 CAN總線通道資源初始化對象
/********************************************************************************************************* ** 函數名稱: __canChanDataInit ** 功能描述: 初始化通道數據(資源)相關 ** 輸 入 : uiChannel :通道號 ** 輸 出 : ERROR_CODE ** 全局變量: ** 調用模塊: *********************************************************************************************************/ static INT __canChanDataInit (UINT uiChannel) { __PCAN_CHANNEL pChannel; ULONG ulVector; UINT uiInputClock; INT iRet; static CPCHAR pcCanIsrName[] = {"can_isr0", "can_isr1"}; /* const char類型的can中斷名稱 */ if (uiChannel >= CAN_CHAN_NUMS) { printk("channel invalid.\n"); return PX_ERROR; } pChannel = &__GCanChannels[uiChannel]; /* 定義一個全局通道類型結構體 */ __canIomuxConfig(uiChannel); /* 管腳複用 */ uiInputClock = __at91sam9X25SysClkGet(MCK); /* 獲取系統時鐘 */ pChannel->CANCH_uiInputClock = uiInputClock; pChannel->CANCH_canchan.pDrvFuncs = &__GCanDrvFuncs; /* 綁定CAN 總線上層回調函數 */ pChannel->CANCH_uiMb0Id = 0x7FF; API_AtomicSet(0, &pChannel->CANCH_atomicRef); /* 原子賦值操做 */ ulVector = pChannel->CANCH_ulVector; /* 中斷號 */ iRet = (INT)API_InterVectorConnect(ulVector, /* 綁定中斷服務函數 */ (PINT_SVR_ROUTINE)__canIrq, (PVOID)pChannel, pcCanIsrName[uiChannel]); if (iRet != ERROR_NONE) { printk("interrupt vector connect error.\n"); return PX_ERROR; } API_InterVectorEnable(pChannel->CANCH_ulVector); /* 使能對應中斷 */ return ERROR_NONE; }
在AT91SAM9X25平臺上,CAN總線硬件初始化如圖 22所示。中斷使能和波特率設置是每一個CAN總線都須要作的工做。CAN總線波特率是根據具體使用狀況和芯片的硬件特性決定的,須要配置相關寄存器來實現。消息郵箱是AT91SAM9X25平臺特有的用來接收和發送消息的一組寄存器,至關於發送和接收緩存區。這些郵箱能夠根據開發者的需求來配置成接收或者發送模式。資源
圖 22 CAN總線硬件初始化流程圖開發
具體代碼實現如程序清單 22所示。
程序清單 22 CAN總線硬件初始化
/********************************************************************************************************* ** 函數名稱: __canChanHwInit ** 功能描述: 硬件初始化 ** 輸 入 : pChannel :通道對象 ** 輸 出 : ERROR_CODE ** 全局變量: ** 調用模塊: *********************************************************************************************************/ static INT __canChanHwInit (__PCAN_CHANNEL pChannel) { UINT uiRegIer; writel(AT91_IRQ_ALL, REG_CAN_IDR(CHANNEL)); /* 禁用全部中斷 */ writel(readl(REG_CAN_MR(CHANNEL)) & ~AT91_MR_CANEN, /* CAN 總線失能 */ REG_CAN_MR(CHANNEL)); __canSetBaudRate(pChannel, CAN_MAX_BAUDRATE); /* 設置CAN波特率 */ __canSetMailboxes(pChannel); /* 配置消息郵箱 */ writel(AT91_MR_CANEN, REG_CAN_MR(CHANNEL)); /* CAN 總線使能 */ uiRegIer = (AT91_MB_MASK(TX_FIRST) & (~AT91_MB_MASK(TX_FIRST))) /* 0-5郵箱中斷位 */ | AT91_IRQ_ERRP /* 被動錯誤中斷使能 */ | AT91_IRQ_ERR_FRAME; /* 幀錯誤中斷使能 */ writel(AT91_IRQ_ALL, REG_CAN_IDR(CHANNEL)); /* 禁用全部中斷 */ writel(uiRegIer, REG_CAN_IER(CHANNEL)); /* 使能錯誤中斷和0-5郵箱中斷 */ return ERROR_NONE; }
內部交流文檔,僅針對AT91SAM9X25相關平臺,若發現相關錯誤或者建議,請及時聯繫文檔建立者進行修訂和更新。