LINUX驱动学习之2-Hello world驱动--点亮LED--感性认识,无实操

操作GPIO的本质:实际上就是操作IC的“配置寄存器”和“数据寄存器”。

配置寄存器:配置GPIO口输入输出模式,推挽输出还是开漏,上下拉配置
数据寄存器:配置GPIO的输出电平高低,或读取输入电平高低

一、无操作系统的hello world
对于无操作系统,通常代码如下

1#define reg_gpio_ctrl GPIO_REG_CTRL
2#define reg_gpio_data GPIO_REG_DATA
3/* 初始化LED */
4void LightInit(void)
5{
6 reg_gpio_ctrl |= (1 << n); /* 设置GPIO为输出 */
7}
8
9/* 点亮LED */
10void LightOn(void)
11{
12 reg_gpio_data |= (1 << n); /* 在GPIO上输出高电平 */
13}
14
15/* 熄灭LED */
16void LightOff(void)
17{
18 reg_gpio_data &=(1 << n); /* 在GPIO上输出低电平 */
19}

其中
GPIO_REG_CTRL是GPIO口的控制寄存器address
GPIO_REG_DATA是GPIO口的数据寄存器address

二、有操作系统的时候

1#include .../* 包含内核中的多个头文件 */

2/* 设备结构体 */
3struct light_dev {
4 struct cdev cdev; /* 字符设备cdev结构体 */
5 unsigned char vaule; /* LED亮时为1,熄灭时为0,用户可读写此值 */
6};

7struct light_dev *light_devp;
8int light_major = LIGHT_MAJOR;

//驱动的许可协议
9MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
10MODULE_LICENSE("Dual BSD/GPL");

11/* 打开和关闭函数 */
12int light_open(struct inode *inode, struct file *filp)
13{。。。。。}

34ssize_t light_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
36{。。。。}

47/* ioctl函数 */
48int light_ioctl(struct file *filp, unsigned int cmd,49 unsigned long arg)
50{。。。。。}

67struct file_operations light_fops = {
68 .owner = THIS_MODULE,
69 .read = light_read,
70 .write = light_write,
71 .unlocked_ioct1 = light_ioctl,
72 .open = light_open,
73 .release = light_release,
74};

75/* 设置字符设备cdev结构体 */
76static void light_setup_cdev(struct light_dev *dev, int index)
77{
78 int err, devno = MKDEV(light_major, index);
79 cdev_init(&dev->cdev, &light_fops);
80 dev->cdev.owner = THIS_MODULE;
81 dev->cdev.ops = &light_fops;
82 err = cdev_add(&dev->cdev, devno, 1);
83 if (err)
84 printk(KERN_NOTICE "Error %d adding LED%d", err, index);
85}

86/* 模块加载函数 */
87int light_init(void)
88{。。。。}

114/* 模块卸载函数 */
115void light_cleanup(void)
116{。。。。。}

121module_init(light_init);
122module_exit(light_cleanup);

上面代码只给出了关键的函数名,目的在于看到字符驱动的编写框架。
1.因为驱动也是需要调用到内核的一些参数,所以需要包含内核的头文件
2.设备结构体,是一种面向对象的编程思路。把设备的属性封装到结构体中。
3.驱动许可协议,这个很重要,如果不加许可协议,在加载到内核的时候,就会报错。LINUX很讲究软件版权。
4.light_open、light_write、light_ioctl都是用户自定义编写的,实际操作硬件寄存器的函数。
5.file_operations这个是linux规定好的,字符设备的驱动结构体。
6.light_init、light_cleanup用户自定义的初始化和卸载模块的函数
7.module_init、module_exit。系统在调用加载(卸载)模块命令的时候,自动去执行的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值