Step1:驱动加载函数: ***_init;
该函数内容为驱动硬件时仅执行一次的函数,其作用是硬件初始化。如配置IO端口输出方向,配置IO上拉等;该函数传入在module_init(***_init);函数中以使得在加载驱动时自动执行;
Step2:写open,read,write,release函数;
这三个函数的作用是为了传入file_operations结构体;在应用程序调用驱动时这三个函数作为借口被调用。
其中open的作用是在编写应用程序时加载驱动程序;其原型为pen(strpath, authority )如:fd = open("/dev/led",O_RDWR);//open函数加载驱动,返回值为描述符,返回值为0时则成功加载驱动。
Write函数的原型为: (structfile *filp, const char __user *buf, size_t count,loff_t *f_pos)
Step3:将step2中的函数赋给operations结构体
struct file_operations led_fops =
{
.owner= THIS_MODULE,
.open= led_open,
.read= led_read,
.write= led_write,
.release= led_release,
};
Step4:在***_init函数中注册字符型设备驱动模块;如以下为注册led驱动函数:
register_chrdev(LED_MAJOR,"led",&led_fops);
int register_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);
其中参数major如果等于0,则表示采用系统动态分配的主设备号;不为0,则表示静态注册。
注销字符设备可以使用unregister_chrdev函数。
Step5:注销字符型设备驱动模块:
在led_exit(可以任意名字,最后把函数名传给module_exit即可)使用unregister_chrdev(LED_MAJOR,"led"); 函数注销驱动。并赋给module_exit(led_exit);
·一个活生生的例子
1.查看用户手册
led1、led2、led3、led4 连接的分别是 GPK4、GPK5、GPK6、GPK7
2、查询6410芯片手册
下面还需要3个步骤:
1、设置GPIO为OUTPUT。
将GPK4、GPK5、GPK6、GPK7设置为输出output=0001
即GPKCON0的19:28都配置为0001
2、设置GPIO的数据。
将GPKDATA的4:7位赋值为0
3、设置GPKUP为上拉。
将GPKUP的4:7位设置为10
3、代码
led_driver.cStep1:驱动加载函数: ***_init;
该函数内容为驱动硬件时仅执行一次的函数,其作用是硬件初始化。如配置IO端口输出方向,配置IO上拉等;该函数传入在module_init(***_init);函数中以使得在加载驱动时自动执行;
Step2:写open,read,write,release函数;
这三个函数的作用是为了传入file_operations结构体;在应用程序调用驱动时这三个函数作为借口被调用。
其中open的作用是在编写应用程序时加载驱动程序;其原型为pen(strpath, authority )如:fd = open("/dev/led",O_RDWR);//open函数加载驱动,返回值为描述符,返回值为0时则成功加载驱动。
Write函数的原型为: (structfile *filp, const char __user *buf, size_t count,loff_t *f_pos)
Step3:将step2中的函数赋给operations结构体
struct file_operations led_fops =
{
.owner= THIS_MODULE,
.open= led_open,
.read= led_read,
.write= led_write,
.release= led_release,
};
Step4:在***_init函数中注册字符型设备驱动模块;如以下为注册led驱动函数:
register_chrdev(LED_MAJOR,"led",&led_fops);
int register_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);
其中参数major如果等于0,则表示采用系统动态分配的主设备号;不为0,则表示静态注册。
注销字符设备可以使用unregister_chrdev函数。
Step5:注销字符型设备驱动模块:
在led_exit(可以任意名字,最后把函数名传给module_exit即可)使用unregister_chrdev(LED_MAJOR,"led"); 函数注销驱动。并赋给module_exit(led_exit);
·一个活生生的例子
1.查看用户手册
led1、led2、led3、led4 连接的分别是 GPK4、GPK5、GPK6、GPK7
2、查询6410芯片手册
下面还需要3个步骤:
1、设置GPIO为OUTPUT。
将GPK4、GPK5、GPK6、GPK7设置为输出output=0001
即GPKCON0的19:28都配置为0001
2、设置GPIO的数据。
将GPKDATA的4:7位赋值为0
3、设置GPKUP为上拉。
将GPKUP的4:7位设置为10
3、代码
led_driver.c
#include
#include
#include
#include /* copy_to_user,copy_from_user */
#include
#include
#include
#include
#define LED_MAJOR 243
#define LED_ON 1
#define LED_OFF 0
#define LED_1_ON 2
#define LED_1_OFF 3
#define LED_2_ON 4
#define LED_2_OFF 5
#define LED_3_ON 6
#define LED_3_OFF 7
#define LED_4_ON 8
#define LED_4_OFF 9
static int led_open (struct inode *inode,struct file *filp)
{
unsigned tmp;
tmp = readl(S3C64XX_GPKCON);
tmp = (tmp&0x0000ffff)| 0x1111ffff;
writel(tmp, S3C64XX_GPKCON);
printk("#########open######n");
return 0;
}
static int led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
return count;
}
static int led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
{
char wbuf[10];
unsigned tmp;
if(copy_from_user(wbuf,buf,count))
return -EFAULT;
switch(wbuf[0])
{
case LED_ON:
tmp = readl(S3C64XX_GPKDAT);
tmp &= (0x0f);
writel(tmp, S3C64XX_GPKDAT);
printk("turn on!n");
break;
case LED_OFF:
tmp = readl(S3C64XX_GPKDAT);
tmp |= (0xf0);
writel(tmp, S3C64XX_GPKDAT);
printk("turn off!n");
break;
case LED_1_ON:
tmp = readl(S3C64XX_GPKDAT);
tmp &= (0xef);
writel(tmp, S3C64XX_GPKDAT);
printk("turn off!n");
break;
case LED_1_OFF:
tmp = readl(S3C64X
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』