国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

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

發(fā)布時(shí)間:2010-8-6 10:22    發(fā)布者:lavida
1、uClinux操作系統(tǒng)概述  

uClinux是Linux2.0的一個(gè)分支,它被設(shè)計(jì)用于沒有MMU的微控制器領(lǐng)域,即被廣泛應(yīng)用于嵌入式Linux領(lǐng)域。uClinux的最大特征就是沒有MMU(內(nèi)存管理單元模塊)。它很適合那些沒有MMU的處理器,如ARM7TDMI,m68ez328等。  

uClinux具有完全的TCP/IP協(xié)議棧,同時(shí)對(duì)其他許多的網(wǎng)絡(luò)協(xié)議都提供支持。這些網(wǎng)絡(luò)協(xié)議都在uClinux上得到了很好的實(shí)現(xiàn)。uClinux可以稱作是一個(gè)針對(duì)嵌入式系統(tǒng)的優(yōu)秀網(wǎng)絡(luò)操作系統(tǒng)。  

2、Linux驅(qū)動(dòng)程序設(shè)計(jì)概述  

Linux系統(tǒng)內(nèi)核通過設(shè)備驅(qū)動(dòng)程序與外圍設(shè)備交互,設(shè)備驅(qū)動(dòng)程序是Linux內(nèi)核的一部分,它是一組數(shù)據(jù)結(jié)構(gòu)和函數(shù),這些數(shù)據(jù)結(jié)構(gòu)和函數(shù)通過定義的接口控制一個(gè)或多個(gè)設(shè)備。  

和UNIX一樣,Linux中所有的設(shè)備均作為文件來對(duì)待,這些文件一般稱為特殊文件,這樣做的一個(gè)好處是使用戶或應(yīng)用程序可按操縱普通文件的方式進(jìn)行訪問控制硬件設(shè)備。  

Linux內(nèi)核有三種類型的設(shè)備驅(qū)動(dòng)程序:字符設(shè)備驅(qū)動(dòng)程序、塊設(shè)備驅(qū)動(dòng)程序和網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序。Linux的設(shè)備由一個(gè)主設(shè)備號(hào)(major)和一個(gè)次設(shè)備號(hào)(minor)標(biāo)識(shí)。主設(shè)備號(hào)唯一標(biāo)識(shí)了設(shè)備類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表的索引。次設(shè)備號(hào)僅由設(shè)備驅(qū)動(dòng)程序解釋,用于識(shí)別同類設(shè)備中,I/O請(qǐng)求所涉及到的那個(gè)設(shè)備。設(shè)備驅(qū)動(dòng)程序可以分為3個(gè)主要組成部分:  

(1)自動(dòng)配置和初始化子程序,負(fù)責(zé)檢測(cè)所要驅(qū)動(dòng)的硬件設(shè)備是否能正常工作。  
(2)服務(wù)于I/O請(qǐng)求的子程序,又稱為驅(qū)動(dòng)程序的上半部分。  
(3)中斷服務(wù)子程序,又稱為驅(qū)動(dòng)程序的下半部分。  

3、uClinux下CAN設(shè)備的驅(qū)動(dòng)程序編寫  

根據(jù)上文對(duì)LINUX下設(shè)備驅(qū)動(dòng)程序的描述,以及參考相關(guān)的實(shí)例分析,下面對(duì)CAN總線設(shè)備SJA1000的驅(qū)動(dòng)程序進(jìn)行編寫。  

CAN設(shè)備驅(qū)動(dòng)程序?qū)嶋H上是linux內(nèi)核直接對(duì)sja1000器件的初始化與讀寫操作。經(jīng)分析,Sja1000 CAN驅(qū)動(dòng)程序構(gòu)成包括如下幾個(gè)部分:

1)定義sja1000芯片內(nèi)所有寄存器的訪問地址,用于完成對(duì)其內(nèi)部寄存器以及緩沖區(qū)的讀寫訪問。例如:  

#define IO_PMOD (*(volatile unsigned *)0x3ff5000)  
#define IO_PDATA (*(volatile unsigned *)0x3ff5008)  
#define IO_PCON (*(volatile unsigned *)0x3ff5004)  
#define SJA_MOD (0x2700000) #define SJA_CMR (0x2700004)  
…………………  
#define SJA_CANRXB7 (0x270006c) #define SJA_CANRXB8 (0x2700070)  

因?yàn)樵谖覀兊南到y(tǒng)中,對(duì)sja1000的讀寫是采用的部分模擬時(shí)序的方式,所以用到了S3C4510的IO端口。下面對(duì)sja1000地址的定義進(jìn)行分析。因?yàn)閡Clinux運(yùn)行的時(shí)候,采用的是32位方式,即兩個(gè)相鄰地址間相隔4個(gè)字節(jié),而在sja1000內(nèi)部的地址間的間隔只有1個(gè)字節(jié)。雖然可以對(duì)S3C4510的內(nèi)部寄存器定義為在訪問sja1000的時(shí)候,將位寬度定義為8位,但這樣會(huì)與linux系統(tǒng)運(yùn)行不匹配,經(jīng)測(cè)試發(fā)現(xiàn)讀寫不正常。所以將sja1000的地址定義為32位寬度。于是各個(gè)寄存器地址為(基址+sja1000內(nèi)部地址×4)。這里將sja1000的基址定義為0x2700000。  

2)編寫對(duì)SJA1000內(nèi)部寄存器訪問的讀寫函數(shù)  

因?yàn)镾3C4510B處理器的地址和數(shù)據(jù)總線是分開的,而SJA1000的地址與數(shù)據(jù)總線是8位分時(shí)復(fù)用的。所以我們只有采用先向sja1000的8位地址數(shù)據(jù)總線上送出地址,然后再送數(shù)據(jù)或者讀數(shù)據(jù)的方式。片選信號(hào)/CS,讀信號(hào)/RD,寫信號(hào)/WR仍由S3C4510B自己產(chǎn)生。需要模擬的是鎖存信號(hào)ALE、地址數(shù)據(jù)總線AD0-AD7。參照sja1000時(shí)序圖,具體的操作步驟見下面程序和注釋。  

寫子程序如下:  
void sja_write(unsigned int data, unsigned int addr)  
{ unsigned char tmp;  
tmp=(addr)>>2;//將32位地址右移2位,tmp的低8位即為sja1000實(shí)際地址。  
outl(tmp,addr);//將地址信息作為數(shù)據(jù)送往SJA1000數(shù)據(jù)總線  
IO_PDATA=0x32;//ALE=0,讓SJA1000將該地址鎖存  
outl(data,addr);//將數(shù)據(jù)信息送往SJA1000數(shù)據(jù)總線  
O_PDATA=0x33; } //將ALE置高電平,74HC245的/OE置高位  

讀子程序如下:  
unsigned char sja_read(unsigned int addr)  
{ unsigned char data;  
volatile unsigned int data1;  
unsigned char tmp;  
tmp=(addr)>>2; //將32位地址右移2位,tmp的低8位即為sja1000實(shí)際地址S3C2410  
outl(tmp,addr); //將地址信息作為數(shù)據(jù)送往SJA1000數(shù)據(jù)總線  
IO_PDATA=0x32; //p0-ALE=0,鎖存地址信息  
IO_PDATA=0x12; //p5-245dir=0,將74HC245的方向置為CPU輸入方向  
data1=inl(addr); //讀出所需的數(shù)據(jù)  
IO_PDATA=0x33; //ALE置高,74HC245置為不工作狀態(tài)  
data=data1; return(data); }//返回?cái)?shù)據(jù)  
后面對(duì)sja1000的初始化、CAN發(fā)送與CAN接收函數(shù)中需要對(duì)寄存器操作均調(diào)用sja_write()和sja_read()函數(shù)進(jìn)行。  

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

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

static struct file_operations sja1000_fops = {  
read: sja1000_read, //CAN接收數(shù)據(jù)  
write: sja1000_write,//CAN發(fā)送  
open: sja1000_open, //打開設(shè)備S3C2410 開發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏  
release: sja1000_release, };//關(guān)閉設(shè)備  

4)定義sja1000_write :CAN發(fā)送函數(shù)(寫函數(shù))  
static int sja1000_write(struct file *filp, const char *buf, size_t size,  
loff_t *offp){ }  
CAN總線控制器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ì)CAN總線網(wǎng)絡(luò)上相應(yīng)信息的接收。在本系統(tǒng)中CAN接收采用的是查詢方式。  

6)編寫sja1000_open:文件打開函數(shù)  
static int sja1000_open(struct inode *inode,struct file *file) { }S3C2410 開發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏  
進(jìn)程調(diào)用該函數(shù)表示對(duì)設(shè)備的占用。如果返回為-1,表示設(shè)備已被其他進(jìn)程占用,打開非法。如果采用中斷方式,對(duì)中斷的注冊(cè)也可放在本函數(shù)中。  

7)編寫sja1000_release:文件關(guān)閉函數(shù)  
static int sja1000_release(struct inode *inode, struct file *file) { }  
該函數(shù)進(jìn)程完成對(duì)設(shè)備占有權(quán)的釋放,釋放后,其他的進(jìn)程就可以訪問這個(gè)設(shè)備了。  

8)編寫sja1000_init(void):void sja1000_init(void) { } CAN設(shè)備初始化函數(shù)  
該函數(shù)完成設(shè)備在LINUX內(nèi)核中的登記。并完成對(duì)sja1000初始化。  
Sja1000寄存器配置通過調(diào)用上面已寫好的sja_write()函數(shù)完成。驅(qū)動(dòng)函數(shù)登記我們采用的是靜態(tài)加載的方式,通過調(diào)用register_chrdev()完成,程序如下:  
if(result = register_chrdev(254,"sja1000",&sja1000_fops)) S3C2410 開發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏  
printk("S3C4510-sja1000: Error %d registering device sja1000\n", result);  
其中,254是為sja1000設(shè)備分配的主設(shè)備號(hào),“sja1000”是顯示在/dev中的設(shè)備名,sja1000_fops為對(duì)應(yīng)的文件系統(tǒng)指針。返回值小于0表示失敗,大于或等于0表示成功。  

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

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

①將設(shè)備驅(qū)動(dòng)程序文件sja1000.c復(fù)制到/uClinux-dist/linux/drivers/char目錄下。該目錄保存了uClinux字符設(shè)備的設(shè)備驅(qū)動(dòng)程序。修改該目錄下mem.c文件,在Init chrdev_init()函數(shù)中增加如下代碼:  
#ifdef CONFIG_SJA1000_DRIVER device_init() #endifS3C2410 開發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏  
其中CONFIG_SJA1000_DRIVER是在配置uClinux內(nèi)核時(shí)賦值的。  

②在uClinux/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’語句下面加上  
bool 'support for sja1000 driver'CONFIG_SJA1000_DRIVERS3C2410 開發(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í)候,設(shè)備驅(qū)動(dòng)就加到內(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\就行了。  

③重新編譯內(nèi)核;在shell中將當(dāng)前目錄cd到uClinux-dist目錄下,然后:S3C2410 開發(fā)板II(B)+3.5寸帶觸摸TFT液晶屏  
#make menuconfig #make dep #make  
當(dāng)驅(qū)動(dòng)程序和uClinux內(nèi)核一起編譯鏈接并生成映像下載到目標(biāo)板運(yùn)行以后,可以通過查看/proc/devices,如果已經(jīng)顯示有sja1000,則表明設(shè)備加載成功。如果使用了中斷,也可以查看/proc/interrupts,該文件記錄了當(dāng)時(shí)已經(jīng)完成的所有系統(tǒng)中斷情況。  

4、結(jié)束語  

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

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

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

廠商推薦

  • Microchip視頻專區(qū)
  • 更佳設(shè)計(jì)的解決方案——Microchip模擬開發(fā)生態(tài)系統(tǒng)
  • 利用模擬開發(fā)工具生態(tài)系統(tǒng)進(jìn)行安全電路設(shè)計(jì)
  • 深度體驗(yàn)Microchip自動(dòng)輔助駕駛應(yīng)用方案——2025巡展開啟報(bào)名!
  • 想要避免發(fā)生災(zāi)難,就用MPLAB SiC電源仿真器!
  • 貿(mào)澤電子(Mouser)專區(qū)

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲视频重口味 | 日本综合在线 | 在线亚洲日产一区二区 | 麻豆视频成人 | 看a级毛片| www.av色| 免费人成网 | 日韩一区二区在线免费观看 | 黄网站色年片在线观看 | 亚洲毛片在线看 | 久久亚洲国产中v天仙www | 成年人视频免费在线观看 | 亚欧视频在线观看 | 免费在线观看一级毛片 | www.欧美在线 | 女人毛片a毛片久久人人 | 欧美日韩精品在线观看 | 警察tk视频vk | 日韩一区国产二区欧美三区 | 亚洲综合网在线观看首页 | 久久精品99香蕉国产 | 中文字幕在线日本 | 手机成人免费视频 | 超清国产粉嫩456在线免播放 | 欧美成人 一区二区三区 | 久久久精品免费观看 | 国产在线观看午夜不卡 | 操啊操| 亚洲91精品麻豆国产系列在线 | 日韩亚射 | 久插视频| 成年网站视频在线观看 | 久久综合丁香激情久久 | h成年同人动漫在线观看网站 | 99热精品久久 | 日韩国产欧美在线观看 | 亚洲小色网 | 免费观看精品视频999 | 91麻豆国产福利精品 | 日韩毛片高清免费 | 三级精品 |