TQ2440在linux下的LED驅動程式

來源:互聯網
上載者:User

        學習驅動程式不久,看LDD3大概有4章吧,最開始寫了個hello world驅動,後來是個面向記憶體的字元裝置驅動,後者讓我清楚了量子和量子集的使用,但是沒有個真正的,肉眼看得見的裝置真是有點不爽,查了些資料,參考了下其他書,打算自己寫個LED的linux驅動,學了字元裝置驅動的話寫這個其實挺簡單的。

        帶系統的驅動跟裸機的驅動可不一樣啊,裸機的驅動像單片機那種,你只要把連接埠設0或者設1就可以控制那些裝置,多簡單,與帶作業系統的驅動程式不同。第一,單片機驅動控制的地址是物理地址,而帶作業系統的驅動控制的是虛擬位址,這個在linux上可以很方便的用ioremap函數把物理地址映射為虛擬位址,這個函數在<asm/io.h>聲明;第二,帶作業系統的驅動,是在核心空間工作的,你要提供API給使用者,使用者用這些介面來寫他們的應用程式,他們不會關心底層是怎麼啟動並執行,好比餐廳裡的,作業系統的驅動是廚師,應用程式是顧客,這樣說可能明白很多。

        看,是linux的應用程式調用的基本架構,上部黃色的是使用者空間,下部藍色的是核心空間。從上往下,程式員在最上層寫程式,操作一些檔案,這些檔案可以是普通的檔案,也可能是裝置檔案等等,這些操作例如open、read、write、ioctl等,這些操作,到了C庫這一層,C庫會產生一個swi val中斷或者說異常,這個異常就會使應用程式從使用者空間進入到核心空間,下面一層叫System all interface,系統調用介面,這一層會調用下面的虛擬檔案系統VFS(Virtual File System)的sys_open、sys_write這些函數,這些函數就會根據不同的檔案不同的屬性,裝置檔案中還會根據裝置號,來尋找特定的驅動程式,這些驅動程式就是我們要寫的,裡面帶led_open、led_write這些函數。

       

這些虛擬檔案系統函數sys_open等是怎麼找到我們的驅動程式裡的led_open等的呢?其實在虛擬檔案系統中有我們的很多種類的檔案,普通檔案、目錄檔案、裝置檔案等,就裝置檔案中的字元裝置舉例,它會建立一個字元裝置的數組,這些數組以主裝置號為下標,貌似從0到255,這些數組裡面裝的是一些file_operations結構指標,這些file_operations是在驅動程式裡面定義的,而file_operations結構裡面就包含了我們的驅動的操作函數led_open、led_write等,數群組成員不同,file_operations結構就不同,驅動程式就不同,操作的裝置就不同......大概是這樣

上面是為了協助大家理清思路,大牛無視就行了,

下面正題了,簡單的在linux下的led驅動程式。

開發平台:

ubuntu10.04

測試平台:

TQ2440,作業系統為linux,核心版本linux-2.6.30.4

//leds.c#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/kdev_t.h>#include <linux/kernel.h>#include <asm/io.h>#define GPBOUT  (1<<(5*2)) |(1<<(6*2)) | (1<<(7*2)) | (1<<(8*2));               //設定GPB5/6/7/8為輸出int major = 0;struct cdev* leds_cdev;volatile unsigned long *GPBCON = NULL;volatile unsigned long *GPBDAT = NULL;static int  leds_open(struct inode *inode, struct file *filp){    *GPBCON = 0;                                        //控制連接埠清零    *GPBCON = GPBOUT;    return 0;}static int leds_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg){    if (arg > 4)    {        printk("deyond the led no\n");    }        switch (cmd)    {        case 1:            *GPBDAT |= (1<<(arg + 4));                      //滅燈            break;        case 0:            *GPBDAT &= ~(1<<(arg + 4));                 //亮燈                break;        default:            printk("cmd error\n");            break;    }    return 0;}struct file_operations leds_fops = {    .owner = THIS_MODULE,    .open = leds_open,    .ioctl = leds_ioctl,};static int __init leds_init(void){    dev_t dev;    leds_cdev = cdev_alloc();        alloc_chrdev_region(&dev, 0, 1, "leds");    major = MAJOR(dev);    leds_cdev->ops = &leds_fops;    cdev_init(&leds_cdev, &leds_fops);    cdev_add(&leds_cdev, dev, 1);    GPBCON = (volatile unsigned int *)ioremap(0x56000010, 16);                  //將物理地址映射到虛擬位址,GPBCON物理地址為0x56000010    GPBDAT = GPBCON + 1;                                                                          //GPBDAT物理地址為0x56000014    return 0;}static void __exit leds_exit(void){    dev_t dev;    dev = MKDEV(major, 0);    cdev_del(&leds_cdev);    unregister_chrdev_region(dev, 1);}module_init(leds_init);module_exit(leds_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("不做超哥已多年");MODULE_DESCRIPTION("leds");

測試程式:

//leds_test.c#include <stdio.h>#include <linux/types.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#define ON 0#define OFF 1int main(int argc, char* argv[]){    int led_no;    if (argc != 3)    {        printf("Usage: %s <led_no> <ON/OFF>\n", argv[0]);        exit(0);    }    int fd;    fd = open("/dev/leds", O_RDWR);    if (fd < 0)    {        printf("open error\n");        exit(0);    }    led_no = strtoul(argv[1], 0, 0);          //將字串轉換成無符號長整型數        if (!strcmp(argv[2], "ON"))        ioctl(fd, ON, led_no);    else if (!strcmp(argv[2], "OFF"))        ioctl(fd, OFF, led_no);    else         exit(0);            return 0;}

編譯驅動模組,在arm板上載入,交叉編譯測試程式,在板子上運行成功

命令是./leds_test led_no ON/OFF 如 ./led_test 1 ON就是點亮led1燈

點亮四個燈後效果:

看到可以控制燈亮滅了,你是否想起了當初玩單片機時點led燈時的興奮呢......哈哈哈哈,好興奮啊

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.