Led驱动程序的设计

之前的字符设备驱动程序的例子是虚拟的一个内存现在以以一个实际的硬件的设计来为例子

首先LED的程序是一种字符设备程序

字符设备方法open ioctrl

 

本文博客地址:http://blog.csdn.net/b2997215859/article/details/47183419

转载请注明来源:http://blog.csdn.net/b2997215859/article/details/47183419


然后以下是源代码

 

首先是模块的初始化函数

static intled_init()

{        

cdev_init(&cdev,&led_fops);

allo_chrdev_region(&devno, 0 , 1 ,'myled');

cdev_add(&cdev, devno , 1);

return0 ;

}        

我们把硬件的初始化后放到open里来做,openioctl均定义在file_operations里面

static structfile_operations led_fops =

{

.open = led_open ,

.unlocked_ioctl = led_ioctl

}

分好要加上不然会报错;并且之间是用逗号隔开不是用分号

 

 

--------------------

然后顺手完成对设备的注销

static voidled_exit()

{

cdev_del(&cdev);

unregister_chrdev_region(&devno,1);

}

第一个语句是对设备的注销

第二个语句是对设备号的注销

-------------------

添加#inlcude<linux/cdev.h>来包括cdev等初始化注销等操作

添加##include<linux/fs.h>来包括struct file_operation等相关东东

-------------------

然后就开始实现设备函数

首先是open,open里实现硬件的初始化

#define GPBCON 0x56000010   //定义控制寄存器的宏

unsigned int *led_config ;      //定义存放GPBCON的虚拟地址

led_config = ioremap(GPBCON , 4); //物理地址转化为虚拟地址

#define GPBDAT 0x56000014   //定义数据寄存器的宏

unsigned int *led_data;        定义存放GPBDAT的虚拟地址

writel(0x400 , led_config); // l表示写入32位的值

led_data = ioremap(GPBDAT , 4)//同时将led_data初始化

--------------------

然后是led_ioctl的实现

首先在此之前分析led_ioctl的功能有俩个关闭和点亮故建立led.h来定义命令

#define LED_MAGIC 'L'    //定义该设备的幻数

#define LED_ON _IO(LED_MAGIC , 0);   //_Io的作用见之前页面对字符设备的介绍,led没有参数传入故使用__IO

#define LED_OFF _IO(LED_MAGIC ,1);  //第一个参数是设备的幻数第二是命令的区分符而已

定义好命令之后便可以通过switch语句进行判别了

如果是LED_ON,则赋值0x00,如果是LED_OFF,则赋值0x11

longled_ioctl(struct file *filp, unsigned int cmd , unsigned long arg)

{

switch(cmd)

{

caseLED_ON:

writel(0x00 ,led_data);

return0;

caseLED_OFF:        

writel(0xff , led_data);

return0;

default:

return-EINVAL;

}        

}

关闭led的时候赋值是0xff而不是0x11

-----------------------

#include<linux/io.h>  //writel的使用

#include    "led.h"      //包含头文件“led.h”

 

 

 

在编译的时候会出现很多问题需要细心去调bug<,比如说这次我在led.h的后面的define语句加了分号然后在led.c的驱动程序中就会报错和符号什么有关led.c中报错233333

 

然后编写驱动程序即可

贴出源码如下

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<sys/ioctl.h>

#include"led.h"

 

int main(int argc,char *argv[])

{

     int fd;

     int cmd;

    

     if (argc <2 )

     {

         printf("please enter the secondpara!\n");

         return0;        

     }

    

     cmd = atoi(argv[1]);

    

     fd = open("/dev/myled",O_RDWR);

    

     if (cmd == 1)

         ioctl(fd,LED_ON);

     else

        ioctl(fd,LED_OFF);        

        

        

     return 0;

}



----------------------------------------------------------------

Led驱动程序的源代码如下

#include<linux/module.h>
#include<linux/init.h>
#include<linux/cdev.h>
#include<linux/fs.h>
#include<linux/io.h>
#include "led.h"




#define GPBCON 0x56000010
#define GPBDAT 0x56000014
unsigned int *led_config ;
unsigned int *led_data;


struct cdev cdev ;
dev_t devno;
int led_open(struct inode *node, struct file *filp)
{
led_config = ioremap(GPBCON,4);
writel(0x400,led_config);//l表示写入的是32位的值
led_data = ioremap(GPBDAT,4);


    return 0;
//mov r1, #0x0

}
long led_ioctl(struct file *filp, unsigned int cmd , unsigned long arg)
{
switch(cmd)
{
case LED_ON:
     writel(0x00,led_data);
     return 0;
case LED_OFF:
             writel(0xff,led_data);
             return 0;
default:
     return -EINVAL;
}
}


static struct file_operations led_fops = 
{
.open = led_open ,
.unlocked_ioctl = led_ioctl,
};
static int led_init()
{
cdev_init(&cdev,&led_fops);
alloc_chrdev_region(&devno , 0 , 1 ,"myled");
cdev_add(&cdev , devno , 1);
return 0 ;
}
static void led_exit()
{
cdev_del(&cdev);
unregister_chrdev_region(devno,1);
}


module_init(led_init);
module_exit(led_exit);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值