【RT-Thread笔记】IO设备模型及GPIO设备

RTT内核对象——设备

RT-Thread有多种内核对象,其中设备device就是其中一种。

内核继承关系图如下:

【RT-Thread笔记】IO设备模型及GPIO设备_第1张图片

设备继承关系图如下:

【RT-Thread笔记】IO设备模型及GPIO设备_第2张图片

device对象对应的结构体如下:

【RT-Thread笔记】IO设备模型及GPIO设备_第3张图片

其中,设备类型type有如下几类:

【RT-Thread笔记】IO设备模型及GPIO设备_第4张图片

设备的操作方法结构体:

【RT-Thread笔记】IO设备模型及GPIO设备_第5张图片

I/O设备模型框架

RT-Thread 提供了一套简单的 I/O 设备模型框架 :

【RT-Thread笔记】IO设备模型及GPIO设备_第6张图片

应用程序通过 I/O 设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。

I/O 设备管理层:实现了对设备驱动程序的封装。 设备驱动程序的升级、更替不会对上层应用产生影响, 从而降低了代码的耦合性、复杂性,提高了系统的可靠性。

设备驱动框架层: 对同类硬件设备驱动的抽象, 将不同厂家的同类硬件设备驱动中相同的部分抽取出来。

设备驱动层: 是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。 这一层是与硬件有关的,不同的芯片的同种外设驱动是不同的,STM32的GPIO驱动与NXP的GPIO驱动是不同的。这一层负责创建与注册I/O设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层。

设备的两种注册方式

1、 对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中:

【RT-Thread笔记】IO设备模型及GPIO设备_第7张图片

2、 对于另一些设备,如看门狗等,则会将创建的设备实例先注册到对应的设备驱动框架中,再由设备驱动框架向 I/O 设备管理器进行注册 :

【RT-Thread笔记】IO设备模型及GPIO设备_第8张图片

I/O设备接口

1、创建及注册I/O设备

设备创建:

【RT-Thread笔记】IO设备模型及GPIO设备_第9张图片

设备注册:

【RT-Thread笔记】IO设备模型及GPIO设备_第10张图片

2、访问I/O设备

应用程序通过 I/O 设备管理接口来访问硬件设备,当设备驱动实现后,应用程序就可以访问该硬件。
I/O 设备管理接口与 I/O 设备的操作方法的映射关系下图所示:

【RT-Thread笔记】IO设备模型及GPIO设备_第11张图片

查找设备:

【RT-Thread笔记】IO设备模型及GPIO设备_第12张图片

初始化设备:

【RT-Thread笔记】IO设备模型及GPIO设备_第13张图片

打开和关闭设备:

【RT-Thread笔记】IO设备模型及GPIO设备_第14张图片

【RT-Thread笔记】IO设备模型及GPIO设备_第15张图片

控制设备:

【RT-Thread笔记】IO设备模型及GPIO设备_第16张图片

读写设备:

【RT-Thread笔记】IO设备模型及GPIO设备_第17张图片

【RT-Thread笔记】IO设备模型及GPIO设备_第18张图片

数据收发回调:

【RT-Thread笔记】IO设备模型及GPIO设备_第19张图片

【RT-Thread笔记】IO设备模型及GPIO设备_第20张图片

GPIO(PIN)设备模型

上面说的设备驱动层有两种注册设备的方式,对应的应用程序也有两种访问设备的方式。一种是通过设备操作接口访问,另一种是通过通用的设备驱动来访问。这里我们使用通用的GPIO设备驱动(对应源码:pin.c)来访问GPIO设备。其中通用的设备驱动在RT-Thread代码中作为一个组件,对应的路径为:

rt-thread\components\drivers

这个文件夹下有很多驱动框架:

【RT-Thread笔记】IO设备模型及GPIO设备_第21张图片

我们用的GPIO(PIN)设备驱动pin.c存在于文件夹misc下。

GPIO输入输出实验(按键点灯):

创建一个pin线程:

按键按下LED被点亮,按键松开LED熄灭。

static void pin_thread_entry(void *parameter)
{
    unsigned int count = 1;
    
    /* 设置LED引脚为输出模式 */
    rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
    
    /* 设置KEY0引脚为输入模式 */
    rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT);
    
    while (count > 0)
    {
        /* 读取KEY0引脚状态 */
        if (rt_pin_read(PIN_KEY0) == PIN_LOW)
        {
            rt_thread_mdelay(50);
            if (rt_pin_read(PIN_KEY0) == PIN_LOW)
            {
                count++;
                rt_kprintf("KEY0 pressed!  LED ON! count = %d\n", count);
                rt_pin_write(PIN_LED_R, PIN_LOW);
            }
        }
        else
        {
            rt_pin_write(PIN_LED_R, PIN_HIGH);
        }
        rt_thread_mdelay(10);
    }
}

int main(void)
{
    /* 线程句柄定义 */
    rt_thread_t tid;  
    
    /* 创建动态pin线程 :优先级 25 ,时间片 5个系统滴答,线程栈512字节 */
    tid = rt_thread_create("pin_thread",
                            pin_thread_entry,
                            RT_NULL,
                            STACK_SIZE,
                            THREAD_PRIORITY,
                            TIMESLICE);
    
    /* 创建成功则启动动态线程 */
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    } 

    return 0;
}

下载程序,在终端输入list_device命令:

【RT-Thread笔记】IO设备模型及GPIO设备_第22张图片

可以看到device是pin,类型是Miscellaneous Device,说明我们正在使用通用的GPIO设备驱动。这个实验中有三个文件值得关注,分别是

device.c:设备管理层
pin.c:设备驱动框架层
drv_gpio.c:设备驱动层

其中device.cpin.c属于RT-Thread的范畴,drv_gpio.c与具体的硬件有关,这个文件里操控的就是与硬件有关的东西,如:

【RT-Thread笔记】IO设备模型及GPIO设备_第23张图片

程序中用到的rt_pin_modert_pin_write等都是PIN设备管理接口。PIN设备管理有如下几个接口:

【RT-Thread笔记】IO设备模型及GPIO设备_第24张图片

设置引脚模式:

【RT-Thread笔记】IO设备模型及GPIO设备_第25张图片

RT-Thread 提供的引脚编号需要和芯片的引脚号区分开来,它们并不是同一个概念,引脚编号由 PIN设备驱动程序定义,和具体的芯片相关。

设置引脚电平:

【RT-Thread笔记】IO设备模型及GPIO设备_第26张图片

读取引脚电平:

【RT-Thread笔记】IO设备模型及GPIO设备_第27张图片

绑定引脚中断回调函数:

【RT-Thread笔记】IO设备模型及GPIO设备_第28张图片

使能引脚中断:

【RT-Thread笔记】IO设备模型及GPIO设备_第29张图片

脱离引脚中断回调函数:

【RT-Thread笔记】IO设备模型及GPIO设备_第30张图片

以上就是本次的笔记,如有错误,欢迎指出。


我的个人博客:https://zhengnianli.github.io/

我的微信公众号:嵌入式大杂烩

你可能感兴趣的:(【RT-Thread笔记】IO设备模型及GPIO设备)