Chinaunix首页 | 论坛 | 博客
  • 博客访问: 40977
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 22
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-05 23:29
文章分类
文章存档

2016年(10)

我的朋友

分类: LINUX

2016-07-12 08:50:26

 
附相关代码和可执行文件:
                     mini2440led.rar   
 
开发环境:VMware 下的fedora9
开发板:mini2440(64M FLASH)
内核:linux-2.6.32.2(FriendlyARM光盘中所带,将其解压到/opt/FriendlyARM/mini2440/目录下)
 
(一)编写编译及加载LED模块驱动程序
(1) 编写LED模块驱动程序mini2440led.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
static unsigned long led_table[]=
{
S3C2410_GPB(5),
S3C2410_GPB(6),
S3C2410_GPB(7),
S3C2410_GPB(8),
};
dev_t devno;//1.0 分配设备号变量
struct cdev dev;   //2.0 分配dev结构体
static int mini2440_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
if(arg<4)  //因为开发板上只有四个LED(0.1.2.3)所以限制一下操作LED的数量
    {
     switch(cmd)
        {
         case 0:
                 s3c2410_gpio_setpin(led_table[arg],!cmd);
                 return 0;
         case 1:
                 s3c2410_gpio_setpin(led_table[arg],!cmd);
                 return 0;
         default:
                 return -EINVAL;
        }
    }
else
    {
     printk("<0>""the led number is faile!\n");
     return -EINVAL;
    }
}
struct file_operations fops={  //2.0 分配file_operations结构体
.owner = THIS_MODULE,
.ioctl = mini2440_ioctl,
};
static int __init led_init(void)
{
int i;
printk("<0>""the led function startup!\n");
for(i=0;i<4;i++)  //配置相应的LED脚为输出
    {
     s3c2410_gpio_cfgpin(led_table[i],S3C2410_GPIO_OUTPUT);
    }
for(i=0;i<4;i++)  //配置相应的LED输出高电平全部熄灭
    {
     s3c2410_gpio_setpin(led_table[i],1);
    }
alloc_chrdev_region(&devno,0,1,"luciensong-led");//1.1 动态申请设备号
cdev_init(&dev,&fops);  //2.1 初始化dev,并建立dev与fops间的连接
dev.owner=THIS_MODULE;  //2.1 指定dev模块所属
cdev_add(&dev,devno,1); //2.2 添加dev
return (0);
}
static void __exit led_exit(void)
{
int i;
printk("<0>""the led function end!\n");
for(i=0;i<4;i++)  //
    {
    s3c2410_gpio_setpin(led_table[i],1);
    }
cdev_del(&dev);//3.0注销设备dev
unregister_chrdev_region(devno,1);//3.1注销设备号
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lucien Song");
MODULE_VERSION("V0.1");
 
(2)将其放入/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char/目录下,修改此目录下的Makefile.(添加obj-m += mini2440led.o)
        
(3) 因为这个内核源代码是经FriendlyARM公司修改过的,所以有些东西我们不需要再去修改,比如ARCH=arm, CORSS_COMPILE=arm-linux-都已为ARM平台修改好,这里我们复制config_mini2440_n35并重新命令为.config.
         cp config_mini2440_n35 .config
(4) 编译模块.
         make modules
    编译结束后,在/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char/目录下会生成相应的mini2440led.ko文件.
(5) 通过串口将其下载到开发板的/lib/modules/2.6.32.2-FriendlyARM/目录下.
(6) 加载LED驱动模块
    cd /lib/modules/2.6.32.2-FriendlyARM/
    insomd ./mini2440led.ko
(7) 获取设备号,因为这里的LED驱动模块简单的编写成了动态申请设备号,获取设备号是为了下一步在/dev目录下创建一个设备.
    cat /proc/devices
           
luciensong-led这个设备就是我编写的LED模块设备名称.
(8) 创建设备.   mknod /dev/设备名  类型(字符设备c,块设备b) 主设备号 次设备号
    mknod /dev/luciensong-led c 253 0
    然后ls /dev就可以查看到创建的这个设备.
   
 
(二)编写LED应用程序并编译下载.
(1) 编写LED应用程序mini2440led_aps.c
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int num;
int statue;
int fd;
sscanf(argv[1],"%d",&num);
sscanf(argv[2],"%d",&statue);
fd = open("/dev/luciensong-led",O_RDWR);
if(fd<0)
    {
     perror("open dev/luciensong-led faile!\n");
     return (-1);
    }
printf("open /dev/luciensong-led success!\n");
ioctl(fd,statue,num);
printf("statue=%d,num=%d\n",statue,num);
close(fd);
return (0);
}
 
(2) 编译
    # arm-linux-gcc mini2440led_aps.c -o mini2440led_aps
    之后会生成相应的mini2440led_aps可执行文件
(3) 通过串口下载到开发板上的/lib/modules/2.6.32.2-FriendlyARM/目录下(也可以下载到别的目录,这里和驱动模块下载到了同目录下,方便查看)
(4) 修改权限 
     # chmod +X mini2440led_aps
(5) 运行(运行LED模块之前应把内核本身加载的LED卸载,具体可参考开发板的使用手册)
    ./mini2440led_aps 2 1
    这时开发板上的第三个灯会被点亮
       
                      
阅读(1974) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~