【Linux驅動】TQ2440 LED驅動程式

來源:互聯網
上載者:User

標籤:des   class   blog   code   http   tar   

★總體介紹

LED驅動程式主要實現了TQ2440開發板上的4個LED燈的硬體驅動,實現了對引腳GPIOB5、GPIOB6、GPIOB7、GPIOB8的高低電平設定(common-smdk.c中已經實現了對引腳的配置),利用測試程式調用該驅動程式,通過命令控制LED燈的亮滅。

★詳細介紹1、驅動程式代碼:My_led.c

#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/irq.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <linux/device.h>#define DEVICE_NAME  "My_led" /**載入模組後執行cat/proc/devices中看到的裝置名稱**/#define Led_MAJOR         103         /**主裝置號**/#define LED_ON        1#define LED_OFF       0 /**Led的控制引腳**/static unsigned long led_table[ ] ={    S3C2410_GPB5,    S3C2410_GPB6,S3C2410_GPB7,S3C2410_GPB8,};static int My_led_open(struct inode *inode,struct file *file){    printk("My_led  open\n");    return 0;}static int My_led_ioctl(struct inode * inode, struct file * file,unsigned int cmd,unsigned long arg){if(arg > 4){return -1;                    }switch(cmd){     case LED_ON:s3c2410_gpio_setpin(led_table[arg], 0);//設定指定引腳為輸出電平為0  return 0;        case LED_OFF:            s3c2410_gpio_setpin(led_table[arg], 1);//設定指定引腳為輸出電平為1            return 0;   default:return  -1;}}static struct file_operations My_led_fops ={.owner = THIS_MODULE,.open = My_led_open,.ioctl = My_led_ioctl,};static struct class *led_class;static int __init My_led_init(void){int ret;printk("My_led start\n"); /**註冊字元裝置驅動程式**/ /**參數為主裝置號、裝置名稱字、file_operations結構**/ /**這樣主裝置號就與file_operations聯絡起來**/ ret = register_chrdev(Led_MAJOR, DEVICE_NAME, &My_led_fops); if(ret < 0) {printk("can't register major number\n");return ret; }//註冊一個類,使mdev可以在"/dev/目錄下建立裝置節點"led_class = class_create(THIS_MODULE, DEVICE_NAME);if(IS_ERR(led_class)){printk("failed in My_led class.\n");return -1;}device_create(led_class, NULL, MKDEV(Led_MAJOR,0), NULL, DEVICE_NAME);printk(DEVICE_NAME "initialized\n");return 0;}static void __exit My_led_exit(void){    unregister_chrdev(Led_MAJOR, DEVICE_NAME);    device_destroy(led_class, MKDEV(Led_MAJOR,0));//登出裝置節點   class_destroy(led_class);//登出類}module_init(My_led_init);module_exit(My_led_exit);MODULE_LICENSE("GPL");

2、宏定義

#define DEVICE_NAME  "My_led" //載入模組後執行cat/proc/devices中看到的裝置名稱
#define Led_MAJOR         103         //主裝置號
#define LED_ON        1
#define LED_OFF       0 My_led_ioctl函數中要輸入的參數命令,LED_ON會執行開啟燈的命令、LED_OFF執行關閉燈的命令

3、Led燈的引腳控制

定義一個led_table[ ] 數組,在後面調用時要方便些。

詳細說明一下S3C2410_GPB5是什麼意思:




如所示,是關於S3C2410_GPB5相關的所有代碼。通過上面的代碼可以得出S3C2410_GPB5為37。實際上S3C2410_GPB5就是連接埠的編號,bank是分組的基號碼,offset是組內的位移量。TQ2440開發板的GPIOB的第五個引腳為37。

4、My_led_ioctl()函數

此函數主要負責響應應用程式的相關命令,然後根據命令執行相關的代碼。cmd命令包括宏定義的LED_ON、LED_OFF。

s3c2410_gpio_setpin()函數

自認為這是本驅動程式最重要的一個函數,它的作用是:將指定的引腳設定為低電平或者高電平。本驅動程式中只是用了核心提供的這一個介面來實現對引腳的控制,但是肯定會研究一下這個函數。

5、註冊一個類

如果不註冊這個類,那麼當在開發板上掛載驅動之後,還要做的一件事是手動“產生裝置節點”,就是利用mknod命令。但是驅動程式都是隨作業系統的運行而開始工作的,因此產生裝置節點要讓它自動產生,而並非手動。所以才會註冊這樣一個類,在掛載驅動之後,自動將裝置節點產生。註冊類的核心代碼:

led_class = class_create(THIS_MODULE, DEVICE_NAME);if(IS_ERR(led_class)){printk("failed in My_led class.\n");return -1;}device_create(led_class, NULL, MKDEV(Led_MAJOR,0), NULL, DEVICE_NAME);

6、測試程式

#include <stdio.h>   #include <stdlib.h>   #include <unistd.h>      #include <sys/types.h>     #include <sys/stat.h>   #include <fcntl.h>       int main()  {      int fd,i,cmd;          fd=open("/dev/My_led",0);     if (fd<0)      {          printf("open led_driver error");          exit(1);      }    while(1)    {    scanf("%d",&cmd);    switch(cmd)    {case 0:    printf("All off\n");    for(i = 0;i < 4;i ++)    ioctl(fd,0,i);     break;case 1:    printf("light first led\n");    ioctl(fd,1,0);     break;case 2:    printf("light second led\n");                    ioctl(fd,0,0);    ioctl(fd,1,1);     break;case 3:    printf("light third led\n");                    ioctl(fd,0,1);    ioctl(fd,1,2);     break;case 4:    printf("light fourth led\n");                    ioctl(fd,0,2);    ioctl(fd,1,3);     break;case 5:    printf("All light \n");    for(i = 0;i < 4;i ++)    ioctl(fd,1,i);     break;default:                     i = 10;    break;        }            if (i == 10)                break;    }        return 0;   }  

★遇到的錯誤

1、找不到檔案

這個錯誤的主要原因很可能是核心的版本不同,不同核心的標頭檔存放的路徑不相同。因此,當編譯驅動程式報錯“找不到檔案”時,檢查標頭檔的路徑是否正確

2、Makefile檔案指定交叉編譯器

下面是驅動程式的Makefile檔案

#LED_makefileKERNELDIR := /home/xg/linux_arm/linux-2.6.30.4/PWD :=$(shell pwd)all:make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=/opt/opt/EmbedSky/4.3.3/bin/arm-linux-test:/opt/opt/EmbedSky/4.3.3/bin/arm-linux-gcc -o test test.cclean:rm -rf *.o *koobj-m :=My_led.o
當時出的錯誤就是編譯器的路徑沒有搞清楚。



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.