RT-thread 设备驱动组件之PIN设备
在RT-thread 2.0.0正式版中引入了pin设备作为杂类设备,其设备驱动文件pin.c在rt-thread-2.0.1\components\drivers\misc中,主要用于操作芯片GPIO, 如点亮led,按键等。同时对于相应的芯片平台,需要自行编写底层gpio驱动,如gpio.c。本文主要涉及的pin设备文件有:驱动框架文件(pin.c,pin.h),底层硬件驱动文件(gpio.c,gpio.h)。在应用用PIN设备时,需要在rtconfig.h中宏定义#define RT_USING_PIN。
一、PIN设备驱动框架
在pin.c中定义了一个静态的pin设备对象static struct rt_device_pin _hw_pin,其中结构体类型struct rt_device_pin在pin.h中定义为:
/* pin device and operations for RT-Thread */
struct rt_device_pin
{
struct rt_device parent;
const struct rt_pin_ops *ops;
};
struct rt_device_pin_mode
{
rt_uint16_t pin; //pin index in pins[] of gpio.c
rt_uint16_t mode;
};
struct rt_device_pin_status
{
rt_uint16_t pin; //pin index in pins[] of gpio.c
rt_uint16_t status;
}; struct rt_pin_ops
{
void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
int (*pin_read)(struct rt_device *device, rt_base_t pin); /* TODO: add GPIO interrupt */
};
在pin.c中主要实现了_pin_read,_pin_write,_pin_control三个函数,同时将这三个函数注册为_hw_pin设备的统一接口函数:
int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data)
{
_hw_pin.parent.type = RT_Device_Class_Miscellaneous;
_hw_pin.parent.rx_indicate = RT_NULL;
_hw_pin.parent.tx_complete = RT_NULL; _hw_pin.parent.init = RT_NULL;
_hw_pin.parent.open = RT_NULL;
_hw_pin.parent.close = RT_NULL;
_hw_pin.parent.read = _pin_read;
_hw_pin.parent.write = _pin_write;
_hw_pin.parent.control = _pin_control; _hw_pin.ops = ops;
_hw_pin.parent.user_data = user_data; /* register a character device */
rt_device_register(&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR); return ;
}
最后,在pin.c文件中将rt_pin_mode,rt_pin_write,rt_pin_read三个函数加入到finsh的函数列表中,用于调试。
二、底层硬件驱动
在gpio.c中主要实现struct rt_pin_ops中的三个接口函数:stm32_pin_mode,stm32_pin_write,stm32_pin_read:
const static struct rt_pin_ops _stm32_pin_ops =
{
stm32_pin_mode,
stm32_pin_write,
stm32_pin_read,
};
同时注册 _hw_pin设备,其设备名称为“pin”,PIN设备硬件初始化:
int stm32_hw_pin_init(void)
{
rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
return ;
}
INIT_BOARD_EXPORT(stm32_hw_pin_init);//stm32_hw_pin_init will be called in rt_components_board_init()
三、PIN设备初始化
在gpio.c中修改使用的IO口数组:
/* STM32 GPIO driver */
struct pin_index
{
int index;
uint32_t rcc;
GPIO_TypeDef *gpio;
uint32_t pin;
}; /* LED ->PD12,PD13,PD14,PD15; USER Button->PA0 */
static const struct pin_index pins[] =
{
{ , RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_12}, //green
{ , RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_13}, //orange
{ , RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_14}, //red
{ , RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_15}, //blue
{ , RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_0}, //user button
};
此外在gpio_pin.c的外设初始化函数中,需要先调用rt_device_open函数(尽管该函数没有在底层实现),保证pin设备对象类的设备引用计数值ref_count不为0,这样才可正常使用rt_device_control,rt_device_write,rt_device_read函数操作GPIO口:
static struct rt_device_pin_mode led_mode[]=
{
{,PIN_MODE_OUTPUT},
{,PIN_MODE_OUTPUT},
{,PIN_MODE_OUTPUT},
{,PIN_MODE_OUTPUT},
}; static struct rt_device_pin_status led_status[]=
{
{,PIN_HIGH}, /* 0:green on */
{,PIN_HIGH}, /* 1:orange on */
{,PIN_HIGH}, /* 2:red on */
{,PIN_HIGH}, /* 3:blue on */ {,PIN_LOW}, /* 4:green off */
{,PIN_LOW}, /* 5:orange off */
{,PIN_LOW}, /* 6:red off */
{,PIN_LOW}, /* 7:blue off */
}; /* it can't be PIN_MODE_INPUT_PULLUP, or the key always will keep PIN_HIGH status */
static struct rt_device_pin_mode key_mode = {,PIN_MODE_INPUT};
static struct rt_device_pin_status key_status = {,PIN_LOW}; static struct rt_device_pin * pin_device;
static rt_err_t gpio_pin_init(const char * pin_device_name)
{
pin_device = (struct rt_device_pin *)rt_device_find(pin_device_name);
if(pin_device == RT_NULL)
{
rt_kprintf("pin device for gpio %s not found!\r\n", pin_device_name);
return -RT_ENOSYS;
} /* oflag has no meaning for pin device , so set to RT_NULL */
if(rt_device_open(&pin_device->parent, RT_NULL) == RT_EOK)
{
/* init led */
for(int i=; i<(sizeof(led_mode)/sizeof(led_mode[])); i++)
{
rt_device_control(&pin_device->parent, RT_NULL, &led_mode[i]);
rt_device_write(&pin_device->parent, RT_NULL, &led_status[i], sizeof(led_status[i]));//init all led PIN_HIGH
} /* init key */
rt_device_control(&pin_device->parent, RT_NULL, &key_mode);
} return ;
} int rt_gpio_pin_init(void)
{
gpio_pin_init("pin"); return ;
}
INIT_APP_EXPORT(rt_gpio_pin_init);
RT-thread 设备驱动组件之PIN设备的更多相关文章
- RT thread 设备驱动组件之USART设备
本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...
- RT-thread 设备驱动组件之SPI设备
本文主要介绍RT-thread中的SPI设备驱动,涉及到的文件主要有:驱动框架文件(spi_dev.c,spi_core.c,spi.h),底层硬件驱动文件(spi_hard.c,spi_hard.h ...
- 【Linux高级驱动】linux设备驱动模型之平台设备驱动机制
[1:引言: linux字符设备驱动的基本编程流程] 1.实现模块加载函数 a.申请主设备号 register_chrdev(major,name,file_operations); b.创 ...
- Linux 驱动框架---cdev字符设备驱动和misc杂项设备驱动
字符设备 Linux中设备常见分类是字符设备,块设备.网络设备,其中字符设备也是Linux驱动中最常用的设备类型.因此开发Linux设备驱动肯定是要先学习一下字符设备的抽象的.在内核中使用struct ...
- RT-thread 设备驱动组件之IIC总线设备
本文主要介绍RT-thread中IIC总线设备驱动,涉及到的主要文件有:驱动框架文件(i2c_core.c,i2c_dev.c,i2c-bit-ops.c,i2c_dev.h,i2c.h):底层硬件驱 ...
- Linux中总线设备驱动模型及平台设备驱动实例
本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...
- Linux设备驱动编程之复杂设备驱动
这里所说的复杂设备驱动涉及到PCI.USB.网络设备.块设备等(严格意义而言,这些设备在概念上并不并列,例如与块设备并列的是字符设备,而PCI.USB设备等都可能属于字符设备),这些设备的驱动中又涉及 ...
- Linux 设备驱动--- 阻塞型字符设备驱动 --- O_NONBLOCK --- 非阻塞标志【转】
转自:http://blog.csdn.net/yikai2009/article/details/8653697 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 阻塞 阻 ...
- linux设备驱动第一篇:设备驱动程序简介
首先,我们知道驱动是内核的一部分,那么驱动在内核中到底扮演了什么角色呢? 设备驱动程序在内核中的角色:他们是一个个独立的“黑盒子”,使某个特定的硬件响应一个定义良好的内部编程接口,这些接口完全隐藏了设 ...
随机推荐
- 16-oauth2-oidc-Client实现
1-新建.net core2.1 mvc网站 2-在Startup.config文件增加相关代码, 下面代码已经配置好oidc客户端了,并设置本mvc启动ip为5009 public void Con ...
- Java设计模式(5)——创建型模式之建造者模式(Builder)
一.概述 概念 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.(与工厂类不同的是它用于创建复合对象) UML图 主要角色 抽象建造者(Builder)——规范建造方法与结果 ...
- 北京Uber优步司机奖励政策(4月2日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 优步UBER司机高峰小时保底奖励
高峰小时保底奖励 (此奖励仅针对6月1日及以后激活的优步车主): 得到“高峰小时保底”的前提为: 1. 在规定高峰时间段内(不得跨段计算),任意一小时内至少完成一单: 2. 在规定高峰时间段内,任 ...
- day 4 集合
1.集合 In [1]: a = (11,22,33,11,22,33) In [2]: a Out[2]: (11, 22, 33, 11, 22, 33) #元组 In [3]: b = [11, ...
- protected修饰符详解
protected这个修饰符,各大参考书都会这样说:访问权限为类内,包内和子类,因此在父类中定义的方法和成员变量如果为protected修饰的,是可以在不同包中的子类进行访问的,示例代码如下: pac ...
- vs找不到lib以及编译的link过程中出现的问题
1.#pragma comment 程序中已经通过该语句完成lib库的引入,如果再在input里面添加lib库就会报错: 2.要在general的“导入外部库”的设置选项的目录下面添加引用到的lib库 ...
- <cfloat> (float.h)
头文件: <cfloat> (float.h) 浮点类型的特性 这个头文件为特殊系统和编译器的实现描述了浮点类型的特征. 一个浮点数包含四个元素: 一个标志(a sign):正或负; 一个 ...
- js屏蔽/过滤 特殊字符,输入就删除掉,实时删除
1.替换方法: <input type="text" class="domain" onkeyup="this.value=this.value ...
- Java反射篇学习笔记
今天重新学习了java中的反射,写一篇学习笔记总结一下.代码基本都是照着两篇博客敲的: 参考一: https://blog.csdn.net/sinat_38259539/article/deta ...