Chinaunix首页 | 论坛 | 博客
  • 博客访问: 144101
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 265
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-04 13:11
文章分类

全部博文(29)

文章存档

2015年(2)

2014年(27)

我的朋友

分类: 嵌入式

2014-07-07 16:28:08

mini2440的LED驱动编写与测试
一,编写驱动程序
在drivers/char目录下,建立一个驱动程序文件mini2440_leds.c
内容如下:
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#define DEVICE_NAME "leds"//设备名(/dev/leds) 
//LED对应的GPIO端口列表
static unsigned long led_table [] = { 
        S3C2410_GPB(5), 
        S3C2410_GPB(6), 
        S3C2410_GPB(7), 
        S3C2410_GPB(8), 
}; 
//LED对应端口将要输出的状态列表
static unsigned int led_cfg_table [] = { 
        S3C2410_GPIO_OUTPUT, 
        S3C2410_GPIO_OUTPUT, 
        S3C2410_GPIO_OUTPUT, 
        S3C2410_GPIO_OUTPUT, 
}; 
/*ioctl函数的实现
* 在应用/用户层将通过ioctl函数向内核传递参数,以控制LED的输出状态
*/ 
static int sbc2440_leds_ioctl( struct inode *inode, struct file *file,  unsigned int cmd,  unsigned long arg) 

        switch(cmd)
        { 

            case 0: 
            case 1: 
                    if (arg > 4) { 
                            return -EINVAL; 
                    } 
                    //根据应用/用户层传递来的参数(取反),通过s3c2410_gpio_setpin函数设置LED对应的端口寄存器,
                    s3c2410_gpio_setpin(led_table[arg], !cmd); 
                    return 0; 
            default: 
                    return -EINVAL; 
        } 

/* 
* 设备函数操作集,在此只有ioctl函数,通常还有read, write, open, close等,因为本LED驱动在下面已经
* 注册为misc设备,因此也可以不用open/close 
*/ 
static struct file_operations dev_fops = { 
        .owner = THIS_MODULE, //一个宏,指向编译模块时自动创建的__this_module变量,无需关注
        .ioctl = sbc2440_leds_ioctl, //用来传输参数
}; 
/* 
* 把LED驱动注册为MISC设备
*/ 
static struct miscdevice misc = { 
         .minor = MISC_DYNAMIC_MINOR, //动态设备号
         .name = DEVICE_NAME, //设备名字
         .fops = &dev_fops, //file_operations结构
}; 
/* 
* 设备初始化
*/ 
static int __init dev_init(void) 

        int ret; 
        int i; 
        for (i = 0; i < 4; i++) { 
            //设置LED对应的端口寄存器为输出(OUTPUT) 
            s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]); 
            //设置LED对应的端口寄存器为低电平输出,在模块加载结束后,四个LED应该是全部都是发光状态
            s3c2410_gpio_setpin(led_table[i], 0); 
        } 
        ret = misc_register(&misc); //自动注册设备函数 
        printk (DEVICE_NAME"\tinitialized\n"); //打印初始化信息
        return ret; 

static void __exit dev_exit(void) 

        misc_deregister(&misc); //卸载驱动程序

module_init(dev_init); //模块初始化
module_exit(dev_exit);//卸载模块
MODULE_LICENSE("GPL"); //版权信息
MODULE_AUTHOR("FriendlyARM Inc.");//开发者信息
二,打开drivers/char/Kconfig文件,添加如下红色部分内容:
config LEDS_MINI2440 
        tristate "LED Support for Mini2440 GPIO LEDs" 
        depends on MACH_MINI2440 
        default y if MACH_MINI2440 
        help 
              This option enables support for LEDs connected to GPIO lines on Mini2440 boards. 
三,再根据该驱动的配置定义,把对应的驱动目标文件加入内核中,打开linux-2.6.32.2/drivers/char/Makefile文件,
        obj-$(CONFIG_LEDS_MINI2440) += mini2440_leds.o
四,在内核源代码目录下执行:make menuconfig重新配置内核在此按空格键选择> LED Support for Mini2440 GPIO LEDs (NEW)”选项,并退出保存内核配置。在内核源代码根目录下执行;make zImage,把生成的新内核烧写到开发板中。执行make modules 就可以生成内核模块文件drivers/char/mini2440_leds.ko,通过网络tftp下载到开发板中
五,编写测试程序,新建一个leds-test.c文件,在命令行下执行:#arm-linux-gcc –o leds-test leds-test.c 将生成可执行目标文件leds-test,通过网络tftp下载到开发板中,比如放在/home/plg 目录下

#include  
#include  
#include  
#include  
int main(int argc, char **argv) 

        int on;   //0或者1
        int led_no;   //
        int fd; 
        if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || on < 0 || on > 1 || led_no < 0 || led_no > 3)  //当出现参数格式不正确时,输出使用方法
         { 

                fprintf(stderr, "Usage: leds led_no 0|1\n"); 
                exit(1); 
        } 
        fd = open("/dev/leds0", 0); 
        if (fd < 0)
        { 

            fd = open("/dev/leds", 0); 
        
        if (fd < 0)
        { 

                perror("open device leds"); 
                exit(1); 
        
        ioctl(fd, on, led_no); //传递参数,与驱动程序中对应
        close(fd); 
        return 0; 
}

六,在此使用 ftp 命令把编译出的mini6410_hello_module.ko 下载到板子中,并把它移动/lib/modules/2.6.38-FriendlyARM 目录然后在板子中现在执行
insmod mini2440_leds.ko


出现如下结果:

leds initialized

可以看到该模块已经被装载了(注意:使用modprobe 命令加载模块不需要加“ko”尾缀)


再执行以下命令,可以看到该模块被卸载

#rmmod mini6410_hello_module

注意: 要能够正常卸载模块, 必须把模块放入开发板的/lib/modules/2.6.38-FriendlyARM 目录


七,在单板根文件系统中建立设备文件
#mknod    /dev/leds  c  231  0
八,测试
#leds-test    3  0




阅读(1689) | 评论(0) | 转发(0) |
0

上一篇:ubuntu安装tftp服务

下一篇:Linux内核移植

给主人留下些什么吧!~~