基于mini2440的led驱动编写的总结
更新时间:2024-05-17 15:41:01 阅读量: 综合文库 文档下载
基于mini2440的led驱动编写的总结(可以成为模板) 该驱动用到I/O常见的端口操作函数:
s3c2410_gpio_cfgpin和s3c2410_gpio_setpin。前一函数实现了设置端口的状态为输入/输出/其他,后一函数实现了端口输出高/低电平。主要谈一下前一个函数的一些重要语句。首先是原型:
s3c2410_gpio_cfgpin(unsigned int pin,unsigned int function),那么我们在驱动中怎么运用呢?比如:s3c2410_gpio_cfgpin
(S3C2410_GPB(5),S3C2410_GPB_OUTPUT),那么里面两个函数是怎么操作的?请看下面的这几个定义:
1、#define S3C2410_GPB(_nr)
(S3C2410_GPIO_B_START+(_nr)) //定义在arch/arm/mach-s3c2410/include/mach/gpio-nrs.h 2、enum s3c_gpio_number{
S3C2410_GPIO_A_START = 0,
S3C2410_GPIO_B_START
=S3C2410_GPIO_NEXT(S3C2410_GPIO_A), ......
}//定义同上
3、#define S3C2410_GPIO_NEXT(__gpio) \\ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0) //定义同上
4、CONFIG_S3C_GPIO_SPACE的定义在.config文件中,见下面: ...... #
#power managment #
CONFIG_S3C_LOWLEVEL_UART_PORT=0 CONFIG_S3C_GPIO_SPACE=0
......
5、#define S3C2410_GPIO_A_NR (32) #define S3C2410_GPIO_B_NR (32) ......
由以上所有定义可以得知以下结论:
S3C2410_GPB(5)-->(S3C2410_GPIO_B_START+5)-->S3C2410_GPIO_NEXT(S3C2410_GPIO_A)+5-->((S3C2410_GPIO_A_START) + S3C2410_GPIO_A_NR) +
CONFIG_S3C_GPIO_SPACE + 0)+5,
这就表示从GPA首地址+GPA个数+GPB的偏移个数是当前GPB的I/O的偏移量。即GPB(5)等于32+0+5=37,即pin=37。至于这怎么和GPB端口的寄存器扯上关系的有待进一步深入内核。
另外在/arch/arm/mach-s3c2410/include/mach/regs-gpio.h的第45行有如下定义:
#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
#define S3C2410_GPIO_INPUT (0xFFFFFFF0) //最后两位01表示输出
#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1) 这时我们开始讲编写整个驱动的流程,其中分为两种方法。
方法一、(将LED注册为混杂设备)
a:首先确定file_operation中要填写几个操作函数,这里因为注册为混杂设备所以只有ioctl操作。 b:其次编写ioctl的实现。 c:注册LED为misc设备: static struct miscdevice misc={
.minor=MISC_DYNAMIC_MINOR, .name=DEVICE_NAME, .fops=&mini2440_leds_fops, }
d:编写初始化函数与退出函数。 具体程序如下:
#include
#include
#define DEVICE_NAME \ static unsigned long led_table [] = { S3C2410_GPB(5), S3C2410_GPB(6), S3C2410_GPB(7), S3C2410_GPB(8), };
static unsigned int led_cfg_table [] = { S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, };
static int sbc2440_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { if (arg > 4) {
return -EINVAL; }
switch(cmd) {
case LED_ON:
s3c2410_gpio_setpin(led_table[arg], 0); return 0; case LED_OFF:
s3c2410_gpio_setpin(led_table[arg],1); return 0; default: return -EINVAL; } }
static struct file_operations dev_fops = { .owner = THIS_MODULE, .ioctl = mini2440_leds_ioctl, };
static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME, .fops = &dev_fops, };
static int __init mini2440_leds_init(void) { int ret; int i;
for (i = 0; i < 4; i++) {
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]); }
ret = misc_register(&misc);
printk (DEVICE_NAME\ return ret; }
static void __exit mini2440_leds_exit(void) {
misc_deregister(&misc); }
module_init(mini2440_leds_init); module_exit(mini2440_leds_exit);
方法二:(将LED注册为普通字符设备)
步骤与上面类似除还得编写open函数,但不用加上注册那个misc设备。具体程序如下: #include
#include
#define DEVICE_NAME \这一行在每一个设备驱动中都必须有的,体现在/dev目录下 //将端口做成数组,以便于编写
static unsigned long led_table [] = { S3C2410_GPB(5), S3C2410_GPB(6), S3C2410_GPB(7), S3C2410_GPB(8), };
static unsigned int led_cfg_table [] = { S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, };
//open函数的实现,其形参不能改变,这是模板
stativ int mini2440_leds_open(struct inode *inode,struct file *file) { int i;
for (i = 0; i < 4; i++) {
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]); }
return 0; }
//ioctl函数的实现,里面的形参是固定格式,不需更改
static int mini2440_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
if (arg > 4) { return -EINVAL; }
switch(cmd) {
case LED_ON:
s3c2410_gpio_setpin(led_table[arg], 0); return 0; case LED_OFF:
s3c2410_gpio_setpin(led_table[arg],1); return 0; default: return -EINVAL; } }
//最重要的结构体之一
static struct file_operations mini2440_leds_fops = { .owner = THIS_MODULE, .ioctl = mini2440_leds_ioctl,
.open =mini2440_leds_open, };
//初始化函数以及退出函数的写法,记住他们的格式 static int __init mini2440_leds__init(void) { int ret;
ret =
register_chrdev(0,DEVICE_NAME,&mini2440_leds_fops);
printk (DEVICE_NAME\ if(ret<0) {
printk(DEVICE_NAME\ return ret; }
printk(DEVICE_NAME\ return 0; }
static void __exit mini2440_leds_exit(void) {
unregister_chrdev(0,DEVICE_NAME); }
module_init(mini2440_leds_init); module_exit(mini2440_leds_exit);
printk(DEVICE_NAME\ return 0; }
static void __exit mini2440_leds_exit(void) {
unregister_chrdev(0,DEVICE_NAME); }
module_init(mini2440_leds_init); module_exit(mini2440_leds_exit);
正在阅读:
河北省黄骅中学2017-2018学年高二上学期第三次月考数学(文)试02-26
牛顿第一定律、牛顿第三定律01-01
11-044 水电自动装置检修(中级)04-04
学游泳作文300字07-01
怀念童年的时光作文700字06-26
荷叶 母亲09-22
行政法第一~第五次央大考核测验题及答案03-08
综合行政执法局关于2022年最新工作总结和工作计划04-28
MASK操作手册(销售单位简化版)cz04-30
- 《江苏省环境水质(地表水)自动监测预警系统运行管理办法(试行)》
- 安乐死合法化辩论赛立论稿(浙大新生赛)
- 公共科目模拟试卷公务员考试资料
- 我国固定资产投资FAI对GDP的影响
- 大学生创新创业训练计划项目申请书大创项目申报表
- 完美版—单片机控制步进电机
- 2013资阳中考化学试题
- 18.两位数减一位数退位(397道)
- 工程量计算规则
- 二年级操行评语(下)
- 第3章 流程控制语句
- 浅基桥墩加固技术
- 课题研究的主要方法
- 5100软件说明书 - 图文
- 车间技术员年终总结
- 关于印发《中铁建工集团开展项目管理实验室活动方案》的通知
- 经典诵读结题报告
- 地下水动力学习题答案
- 2018年全国各地高考数学模拟试题平面解析几何试题汇编(含答案解
- 街道办事处主任2018年度述职述廉报告
- 编写
- mini2440
- 基于
- 驱动
- 总结
- led
- 学生常见问题
- 2018年棕刚玉微粉行业市场调研行情及投资前景预测分析报告(目录
- 2019年双鸭山市中考英语作文万能写作模板
- 宾馆管理制度条例大全
- 格雷母线技术详解 - 图文
- 浅谈企业合理避税
- 音乐教师德育工作总结4篇一
- 氯乙烯共聚树脂市场分析调查及投资前景行业报告2018目录
- 高中数学复习学(教)案(第3讲)简易逻辑
- “互联网+”大学生创新创业商业计划书word
- 智能灌溉系统的设计论文
- 沪教版数学七年级上 第九章整式课课练及单元测试卷一和参考答案
- 高考真题 - 文综政治(天津卷)解析版 Word版含解析
- 坪山新区丹锦西路市政工程勘察报告
- 包装世界第二章题库
- 一阶RC电路的暂态响应实验报告
- 电桥2实验报告 - 图文
- 最新冀教版数学一年级下册5.4《100以内数的大小比较》优秀教学设
- 函授英语试卷及答案
- 小米公司的促销策略分析