Android系統下CAN總線(xiàn)驅動(dòng)程序的設計與實(shí)現
3.2 Linux中CAN驅動(dòng)程序實(shí)現
針對MCP2515控制器,在Linux kernel設計中采用字符設備驅動(dòng)開(kāi)發(fā)的形式。驅動(dòng)初始化函數staticint_init MCP2515_init(),首先通過(guò)ioremap()函數將S5PV210的SPI寄存器的物理地址映射到內核空間,這樣才可以在驅動(dòng)程序中訪(fǎng)問(wèn)和配置S5PV210的SPI寄存器。在正確配置S5PV210的SPI寄存器后,通過(guò)register_chrdev()函數為MCP2515注冊設備驅動(dòng),分配主設備號,這樣在設備文件目錄中創(chuàng )建對應的設備文件后,就可以用Linux的系統函數操作MCP2515了。而分配內存部分放在probe()函數中完成,分配空間包括為設備數據結構以及其內部的接收發(fā)送緩沖區動(dòng)態(tài)分配空間。同時(shí)在probe()還需要完成申請中斷工作,并初始化中斷處理隊列,在中斷處理隊列中讀取CANINTF寄存器,判斷是接收/發(fā)送中斷的哪一個(gè)緩沖器,或者說(shuō)是錯誤中斷最后通過(guò)enable_irq()函數使能S5PV210相應的中斷引腳。
(1)MCP2515初始化。在實(shí)現了SPI的加載和聲明后,就可以利用SPI寫(xiě)命令對MCP2515進(jìn)行初始化。MCP2515的初始化過(guò)程為:首先將CAN控制寄存器CANCTRL的REQOP2:0>位設置為‘100’進(jìn)入配置模式,所有錯誤計數器被清零,進(jìn)入配置模式后設置波特率,禁止所有中斷,設置濾波器,清除發(fā)送接收緩存,打開(kāi)中斷,完成MCP2515的初始化。MCP2515初始化過(guò)程如圖5所示。本文引用地址:http://dyxdggzs.com/article/148042.htm
(2)MCP2515中斷方式。由于CAN總線(xiàn)接收數據時(shí)必須與系統以中斷方式交換數據,所以必須注冊中斷。使用的中斷函數有request_irq(),free_irq(),enable_irq()和disable_irq(),其中函數request_irq()是給定的中斷源裝載中斷處理程序;enable_irq()調用中斷控制函數使給定的中斷鏈有效;free_irq()釋放分配給已定中斷的內存;disable_irq()使定義中斷鏈失效。具體代碼為request_irq(irq_EINTO mcp2515_int,IRQF_DISABLED,device_name,NULL);其中函數request_irq()的第1個(gè)參數是設備申請的中斷號;第2個(gè)參數是向系統注冊的中斷處理函數;第3個(gè)參數是中斷處理的屬性,IRQF_DISABLED表示中斷處理程序是一個(gè)快速中斷處理程序,被調用時(shí)屏蔽所有中斷;第4個(gè)參數是中斷的設備名稱(chēng);第5個(gè)參數是申請時(shí)通知系統的設備標志,該函數返回值為0表示申請成功,返回負數表示失敗,這樣當中斷發(fā)生時(shí),在中斷處理函數mcp2515_int()中讀取CAN狀態(tài)寄存器CANSTAT,判斷RXB0是否裝入報文,如果是則把報文通過(guò)SPI接收數據寄存器讀取到buff er中,等待系統函數CAN_Read()讀取。
(3)MCP2515驅動(dòng)程序的核心文件結構file_operations。CAN總線(xiàn)應用程序通過(guò)file_operations數據結構訪(fǎng)問(wèn)CAN設備驅動(dòng)函數,/kem el/linux/fs.h>對file_operations數據結構中的各個(gè)變量做了詳解。內核可以通過(guò)文件結構來(lái)訪(fǎng)問(wèn)驅動(dòng)程序的函數,實(shí)現系統調用。
CAN應用程序可以通過(guò)系統函數read()和write()實(shí)現讀取和寫(xiě)入相應的數據,open()函數中完成設備的打開(kāi),close()函數中完成注銷(xiāo)設備的工作,ioctl()函數中需要完成MCP2515控制器的初始化工作:設置控制器的工作模式、設置控制總線(xiàn)的波特率、清空發(fā)送緩沖區和接收緩沖區等。
3.3 CAN驅動(dòng)編譯
(1)將寫(xiě)好的驅動(dòng)源文件拷貝到/kernel/drivers/char/下,并打開(kāi)Kconfig添加如下代碼:
config S5pv210_CAN
tristate“S5pv210 can controller driver”
depends on ARCH_S5pv210
help
This option enable support for CAN
(2)在/kernel/drivers/char/Makefile文件的適當位置添加如下代碼:
obj-$(CONFIG_S5pv210_CAN)+=S5pv210-can.o
(3)添加can功能。在/kernel/下make menuconfig DeviceDrivers→Characterdevices→M>S5pv210 cancontroller driver動(dòng)態(tài)加載CAN驅動(dòng)并保存退出。
(4)重新編譯內核。在終端進(jìn)入/kernel/目錄,執行make命令后在/kernel/drivers/char/下找到S5pv210_can.o,此為L(cháng)inux kernel層生成的CAN設備驅動(dòng)文件,kernel層驅動(dòng)向下直接操作硬件,向上層也就是HAL層,提供/dev/can設備節點(diǎn)文件,提供驅動(dòng)接口unclocked_ioctl()函數。
4 Android HAL層的調用
CAN驅動(dòng)程序在Android系統下的實(shí)現,硬件抽象層(HAL)的調用是關(guān)鍵。將Android系統移植到其他硬件平臺或在A(yíng)ndroid系統中添加新硬件支持時(shí),都需要對Android HAL層進(jìn)行移植或實(shí)現在libhardware接口的頭文件hardware.h中,定義了HAL實(shí)現過(guò)程中的3個(gè)通用結構體struct hw_module_t、struct hw_module_methods_t和struct hw_device_tostruct hw modules_methods_t用來(lái)表示一個(gè)模塊表示方法,結構體中只包含了打開(kāi)模塊的函數指針。struethw_module_t用來(lái)定義一個(gè)硬件模塊的信息,具體的硬件模塊中,需要“繼承”這個(gè)結構體。st ruct hw_device_t用來(lái)表示一個(gè)硬件設備,在一個(gè)硬件模塊中可以同時(shí)包含多個(gè)硬件設備。在一個(gè)模塊的HAL層開(kāi)發(fā)中,具體的硬件調用流程為:(1)通過(guò)ID得到硬件模塊。(2)從硬件模塊得到hw_modules_t,打開(kāi)得到硬件設備hw_device_t。(3)調用hw_device_t中的各個(gè)方法。(4)通過(guò)hw_device_t的close關(guān)閉設備。
Android系統下CAN模塊的實(shí)現在完成SPI總線(xiàn)和:MCP2515控制器的驅動(dòng)后必須實(shí)現Android HAL層的調用。CAN總線(xiàn)的HAL層調用流程如圖6所示。
編寫(xiě)HAL層使用struet hw_module_t、struct hw_module_methods_t和struct hw_device_t 3個(gè)結構體來(lái)設置對CAN模塊的操作方法;JNI層主要完成對HAL層提供的硬件操作方法的注冊,JNI通過(guò)CAN_HARDWARE_MODULE_ID找到對應的stub,使Framework層可以使用這些方法;Setv ice層主要聲明了JNI可以提供的方法,加載libcan_runtime.so,加載時(shí)會(huì )調用JNI層的JNI_OnLoad,這樣JNI中的方法可以被 Service調用;編寫(xiě)App應用程序,使App直接調用service,完成Android HAL層的調用。之后將can文件夾放到系統development目錄下。
配置環(huán)境變量執行../build/envsetup.sh。然后執行mmm development/can編譯文件。最后,重新編譯內核,生成鏡像文件,下載并運行操作系統。此時(shí),CAN總線(xiàn)驅動(dòng)程序將會(huì )加載,這樣就實(shí)現了Android系統下CAN控制器MCP2515驅動(dòng)程序的開(kāi)發(fā)。
5 結束語(yǔ)
在分析Android驅動(dòng)原理的基礎上,介紹了CAN總線(xiàn)在A(yíng)ndroid下的實(shí)現流程,并添加了CAN驅動(dòng)程序在嵌入式操作系統Android中,對其他Android平臺非標準設備驅動(dòng)程序的開(kāi)發(fā)有一定的借鑒作用。
評論