历史上的今天
今天是:2024年10月30日(星期三)
2019年10月30日 | iny6410 简单的LED字符设备驱动 io驱动
2019-10-30 来源:51hei
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 #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(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; case LED_2_ON: tmp = readl(S3C64XX_GPKDAT); tmp &= (0xdf); writel(tmp, S3C64XX_GPKDAT); printk("turn off!n"); break; case LED_2_OFF: tmp = readl(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; case LED_3_ON: tmp = readl(S3C64XX_GPKDAT);
史海拾趣
|
此电路结构简单,取材容易,性能可靠,操作方便。工作原理:假设水箱内没有水,需要进水预热,只要将K1合上(见下图),则绿色指示灯亮,电磁阀经J1-2常闭触点得电而开阀进水,待水箱内水升至平面S1时,BG1、BG2组成的复合管得正向偏压而驱动继电 ...… 查看全部问答> |
|
fopen打开的文件,如何实现当文件达到一定大小后,重头进行覆盖写入 我的那个文件要求记录5000条记录,超过5000条时,重头开始写入,用新的记录覆盖掉旧的记录。fopen就那几种打开方式,我试了下,好像都不支持。如果以“a+“的方式打开,然后用seek去定位,然后再写入也不行,仍然会加到文件尾。各位有没有什么好的 ...… 查看全部问答> |
|
usb驱动问题!!!dispatch_level在callusbdi下不可用!!急急急!! callusbdi windows wdm设备驱动程序开发指南(chris cant) 在dispatch_level调用出现死等,但是在passive_level正常 书上也说只能在Passive_level调用,是什么原因呢,怎样才能在dispatch_level调用呢? 高手快来啊 NTSTATUS CallUSBDI(IN PDEV ...… 查看全部问答> |
|
设计了一种基于Ms P 4 3 0处理器的温控系统, 介绍了系统主要硬件, 重点介绍了温度控制系统及其算法的实现, 这里采用的是史密斯一 模糊自调整 P I D控制系统, 该系统通过对传统的史密斯预估器进行改良, 将该模糊自调整P I D控制器引入史密斯控 ...… 查看全部问答> |
|
YM12864R读函数为什么读不出正确的数据,总是0xff,调了好久都没弄好,网上也有人有同样的问题,但是好像都没有解决,急求帮助uchar LcdRdata(void){ uchar getdata; RS=1; WRD=1; P0=0xff; E=0; E=1; delay(100); getdata=P0; E=0; return getdata ...… 查看全部问答> |
|
我在早上9点半玩易电源拼图游戏,发现电容电感问题,明显是错误的,而且后来更正过来了,那么在之前得100分的朋友们,你们难道没有发现这个简单的错误吗?如果发现了,为什么还跟着错?难道就为了那100分?为了奖品机会? 作为技术人员,发现问题 ...… 查看全部问答> |
|
基于安卓/苹果的物品防盗管家,用于对随身箱包和贵重物品进行管理 利用手机作为监控终端,既简便又易用,同时如果手机被人拿走的话,通讯断开,手机和开发模块都会报警。 1. 通过蓝牙与手机进行数据互联,若发送报警信息或是“心跳同步”时,通讯没有相应,则发送方进行报警 2. 检测光线有强烈变化时,进行报警 ...… 查看全部问答> |
|
晒WEBENCH设计的过程+DC8-16V转5V/1A车载充电器的设计过程 本帖最后由 a736015 于 2014-5-29 17:14 编辑 一、设计要求:输入DC8-16V,输出5V/1A二、应用:车载手机平板电脑充电器三、设计过程根据论坛窗口或进入TI在线设计工具页面 点击后进入到登陆(注册)界面 注册TI账号后进入WEBENCH在线设计工具在 ...… 查看全部问答> |




