新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 嵌入式uClinux下的CAN總線設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

嵌入式uClinux下的CAN總線設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

作者: 時(shí)間:2013-03-30 來(lái)源:網(wǎng)絡(luò) 收藏

3)定義驅(qū)動(dòng)程序的文件結(jié)構(gòu)

  在LINUX系統(tǒng)中,對(duì)硬件設(shè)備的訪問(wèn)也是被當(dāng)作文件來(lái)操作的。這里定義的文件接口將可以在外部的應(yīng)用程序中被調(diào)用。在CAN驅(qū)動(dòng)程序中,只定義了讀CAN信息(CAN接收)、向CAN節(jié)點(diǎn)寫(xiě)信息(CAN發(fā)送)、打開(kāi)CAN設(shè)備、關(guān)閉CAN設(shè)備等4個(gè)文件接口。定義信息如下面的程序所示。在sja1000_fops中所定義的函數(shù)都必須在驅(qū)動(dòng)程序中編寫(xiě)。

  static struct file_operations sja1000_fops = {

  read: sja1000_read, //CAN接收數(shù)據(jù)

  write: sja1000_write,//CAN發(fā)送

  open: sja1000_open, //打開(kāi)設(shè)備S3C2410 開(kāi)發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏

  release: sja1000_release, };//關(guān)閉設(shè)備

4)定義sja1000_write :CAN發(fā)送函數(shù)(寫(xiě)函數(shù))

  static int sja1000_write(struct file *filp, const char *buf, size_t size,

  loff_t *offp){ }

  在控制器Sja1000初始化完成后,即可設(shè)置CAN發(fā)送,具體對(duì)sja1000寄存器的相關(guān)操作的相關(guān)程序可參閱SJA1000器件的數(shù)據(jù)手冊(cè)。

5)定義sja1000_read :CAN接收函數(shù)(讀函數(shù))

  static int sja1000_read(struct file *filp, char *buf, size_t size,

  loff_t *offp) { }

  該函數(shù)完成對(duì)網(wǎng)絡(luò)上相應(yīng)信息的接收。在本系統(tǒng)中CAN接收采用的是查詢方式。

6)編寫(xiě)sja1000_open:文件打開(kāi)函數(shù)

  static int sja1000_open(struct inode *inode,struct file *file) { }S3C2410 開(kāi)發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏

  進(jìn)程調(diào)用該函數(shù)表示對(duì)設(shè)備的占用。如果返回為-1,表示設(shè)備已被其他進(jìn)程占用,打開(kāi)非法。如果采用中斷方式,對(duì)中斷的注冊(cè)也可放在本函數(shù)中。

7)編寫(xiě)sja1000_release:文件關(guān)閉函數(shù)

  static int sja1000_release(struct inode *inode, struct file *file) { }

  該函數(shù)進(jìn)程完成對(duì)設(shè)備占有權(quán)的釋放,釋放后,其他的進(jìn)程就可以訪問(wèn)這個(gè)設(shè)備了。

8)編寫(xiě)sja1000_init(void):void sja1000_init(void) { } CAN設(shè)備初始化函數(shù)

  該函數(shù)完成設(shè)備在LINUX內(nèi)核中的登記。并完成對(duì)sja1000初始化。

  Sja1000寄存器配置通過(guò)調(diào)用上面已寫(xiě)好的sja_write()函數(shù)完成。驅(qū)動(dòng)函數(shù)登記我們采用的是靜態(tài)加載的方式,通過(guò)調(diào)用register_chrdev()完成,程序如下:

  if(result = register_chrdev(254,"sja1000",sja1000_fops)) S3C2410 開(kāi)發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏

  printk("S3C4510-sja1000: Error %d registering device sja1000", result);

  其中,254是為sja1000設(shè)備分配的主設(shè)備號(hào),“sja1000”是顯示在/dev中的設(shè)備名,sja1000_fops為對(duì)應(yīng)的文件系統(tǒng)指針。返回值小于0表示失敗,大于或等于0表示成功。

9)將驅(qū)動(dòng)程序加到內(nèi)核中

  當(dāng)驅(qū)動(dòng)程序sja1000.c編寫(xiě)完成后,下面的工作就是將它加到內(nèi)核中了。這需要修改的源代碼,然后重新編譯uClinux內(nèi)核。

  ①將程序文件sja1000.c復(fù)制到/uClinux-dist/linux/drivers/char目錄下。該目錄保存了uClinux字符設(shè)備的程序。修改該目錄下mem.c文件,在Init chrdev_init()函數(shù)中增加如下代碼:

  #ifdef CONFIG_SJA1000_DRIVER device_init() #endifS3C2410 開(kāi)發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏

  其中CONFIG_SJA1000_DRIVER是在配置uClinux內(nèi)核時(shí)賦值的。

 ?、谠趗Clinux/linux/drivers/char目錄下 Makefile中增加如下代碼:

  ifeq($(CONFIG_SJA1000_DRIVER,y) L_OBJS+=sja1000.c endif

  如果在配置uClinux內(nèi)核的時(shí)候選擇了支持我們定義的設(shè)備,則在編譯內(nèi)核的時(shí)候會(huì)編譯sja1000.c,生成 sja1000.o文件。

  ③修改 /uClinux-dist/linux/arch/m68knonunu目錄下 config.in文件,在 comment' Character devices’語(yǔ)句下面加上

  bool 'support for sja1000 driver'CONFIG_SJA1000_DRIVERS3C2410 開(kāi)發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏

  這樣,在編譯內(nèi)核,運(yùn)行make menuconfig的時(shí)候,且在配置字符設(shè)備時(shí)就會(huì)有選項(xiàng):

  support for sja1000 driver 當(dāng)選中這個(gè)選項(xiàng)的時(shí)候,就加到內(nèi)核中了。

  ④在romfs中加上設(shè)備驅(qū)動(dòng)程序?qū)?yīng)的設(shè)備文件。設(shè)備文件都被包含在/dev目錄下。uClinux中使用的根文件系統(tǒng)是romfs文件系統(tǒng)。這個(gè)文件系統(tǒng)是一個(gè)只讀文件系統(tǒng),所以設(shè)備文件必須在編譯內(nèi)核的時(shí)候加到romfs文件系統(tǒng)的image中。

  不同的硬件系統(tǒng)對(duì)應(yīng)不同的設(shè)備文件,在/uClinux-dist/vendors目錄下,分別定義了它們的Makefile文件。在uClinux-dist/Vendors里S3C4510對(duì)應(yīng)的目錄下找到它的Makefile文件,并找到區(qū)域DEVICES= tty,c,5,0 console,c,5,1 cua0,c,5,64 cual,c,5,65,在后面再加上設(shè)備項(xiàng) sja1000,c,254,1就行了。

 ?、壑匦戮幾g內(nèi)核;在shell中將當(dāng)前目錄cd到uClinux-dist目錄下,然后:S3C2410 開(kāi)發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏

  #make menuconfig #make dep #make

  當(dāng)驅(qū)動(dòng)程序和uClinux內(nèi)核一起編譯鏈接并生成映像下載到目標(biāo)板運(yùn)行以后,可以通過(guò)查看/proc/devices,如果已經(jīng)顯示有sja1000,則表明設(shè)備加載成功。如果使用了中斷,也可以查看/proc/interrupts,該文件記錄了當(dāng)時(shí)已經(jīng)完成的所有系統(tǒng)中斷情況。

4、結(jié)束語(yǔ)

  實(shí)時(shí)性方面,可以使用進(jìn)程間通信如管道、消息隊(duì)列、共享內(nèi)存等方法將的接收中斷與應(yīng)用程序直接關(guān)聯(lián),加快系統(tǒng)對(duì)CAN總線事件的響應(yīng)速度。進(jìn)一步可以通過(guò)RTLinux和RTAI(Real Time Application Interface)這兩種方案增強(qiáng)uClinux的實(shí)時(shí)性。

  本文作者創(chuàng)新點(diǎn):有效地解決了在沒(méi)有MMU的CPU之上開(kāi)發(fā)一些簡(jiǎn)單任務(wù)操作系統(tǒng)或控制程序效率低、程序簡(jiǎn)單的缺點(diǎn)。通過(guò)使用嵌入式uClinux,它既保存了原先Linux操作系統(tǒng)穩(wěn)定性、功能強(qiáng)大等優(yōu)點(diǎn),又對(duì)內(nèi)核的代碼重新編寫(xiě),減少了內(nèi)核容量,提高了效率。同時(shí)也提出了在CAN總線設(shè)備下設(shè)計(jì)驅(qū)動(dòng)程序的方法。


上一頁(yè) 1 2 下一頁(yè)

評(píng)論


相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉