第11章 RT-Thread IO设备和软件包_第1页
第11章 RT-Thread IO设备和软件包_第2页
第11章 RT-Thread IO设备和软件包_第3页
第11章 RT-Thread IO设备和软件包_第4页
第11章 RT-Thread IO设备和软件包_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第11章RT-ThreadI/O设备和软件包11.1I/O设备介绍嵌入式系统包括一些I/O(Input/Output,输入/输出)设备。例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的Flash或SD卡,以及网络设备的以太网接口等,都是嵌入式系统中容易找到的I/O设备例子。RT-Thread提供了一套简单的I/O设备模型框架,如图11-1所示。位于硬件和应用程序之间,共分成三层,从上到下分别是I/O设备管理层、设备驱动框架层、设备驱动层。11.1.1I/O设备模型框架图11-1I/O设备模型框架应用程序通过I/O设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层I/O硬件设备进行数据(或控制)交互。I/O设备模型框架从下往上共分为设备驱动层、设备驱动框架层和IO设备管理层三层。1.设备驱动层I/O设备驱动层封装驱动程序,提供标准接口,确保硬件操作与应用独立,降低耦合提升系统可靠性。2.设备驱动框架层设备驱动框架层抽象同类设备驱动公共部分,接口留给设备驱动层实现,源码在rt-thread/components/drivers目录。3.IO设备管理层设备管理层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。简单I/O设备使用序列图如图11-2所示,主要有以下2点:(1)设备驱动根据设备模型定义,创建出具备硬件访问能力的设备实例,将该设备通过rt_device_register()接口注册到I/O设备管理器中。(2)应用程序通过rt_device_find()接口查找到设备,然后使用I/O设备管理接口来访问硬件。图11-2简单I/O设备使用序列图看门狗设备使用序列图如图图11-3所示。主要有以下几点:(1)看门狗设备驱动程序根据看门狗设备模型定义,创建出具备硬件访问能力的看门狗设备实例,并将该看门狗设备通过rt_hw_watchdog_register()接口注册到看门狗设备驱动框架中。(2)看门狗设备驱动框架通过rt_device_register()接口将看门狗设备注册到I/O设备管理器中。(3)应用程序通过I/O设备管理接口来访问看门狗设备硬件。图11-3看门狗设备使用序列图RT-Thread设备模型基于内核对象模型,设备作为对象管理,继承基对象属性并派生私有属性。设备继承关系图如图11-4所示。11.1.2I/O设备模型图11-4设备继承关系图设备对象具体定义如下所示:structrt_device{structrt_objectparent;/*内核对象基类*/enumrt_device_class_typetype;/*设备类型*/rt_uint16_tflag;/*设备参数*/rt_uint16_topen_flag;/*设备打开标志*/rt_uint8_tref_count;/*设备被引用次数*/rt_uint8_tdevice_id;/*设备ID,0-255*//*数据收发回调函数*/rt_err_t(*rx_indicate)(rt_device_tdev,rt_size_tsize);rt_err_t(*tx_complete)(rt_device_tdev,void*buffer);conststructrt_device_ops*ops;/*设备操作方法*//*设备的私有数据*/void*user_data;};typedefstructrt_device*rt_device_t;RT-Thread支持多种I/O设备类型,主要设备类型如下所示:RT_Device_Class_Char/*字符设备*/RT_Device_Class_Block/*块设备*/RT_Device_Class_NetIf/*网络接口设备*/RT_Device_Class_MTD/*内存设备*/RT_Device_Class_RTC/*RTC设备*/RT_Device_Class_Sound/*声音设备*/RT_Device_Class_Graphic/*图形设备*/RT_Device_Class_I2CBUS/*I2C总线设备*/RT_Device_Class_USBDevice/*USBdevice设备*/11.1.3I/O设备类型RT_Device_Class_USBHost/*USBhost设备*/RT_Device_Class_SPIBUS/*SPI总线设备*/RT_Device_Class_SPIDevice/*SPI设备*/RT_Device_Class_SDIO/*SDIO设备*/RT_Device_Class_Miscellaneous/*杂类设备*/其中字符设备、块设备是常用的设备类型,它们的分类依据是设备数据与系统之间的传输处理方式。块设备如图11-5所示。图11-5块设备11.2创建和注册I/O设备驱动层负责创建设备实例,并注册到I/O设备管理器中,可以通过静态申明的方式创建设备实例,也可以用下面的接口进行动态创建:rt_device_trt_device_create(inttype,intattach_size);函数参数说明如下:type:设备类型,可取前面小节列出的设备类型值attach_size:用户数据大小返回:无设备句柄:创建成功RT_NULL:创建失败,动态内存分配失败调用该接口时,系统会从动态堆内存中分配一个设备控制块,大小为structrt_device和attach_size的和,设备的类型由参数type设定。设备被创建后,需要实现它访问硬件的操作方法。structrt_device_ops{/*commondeviceinterface*/rt_err_t(*init)(rt_device_tdev);rt_err_t(*open)(rt_device_tdev,rt_uint16_toflag);rt_err_t(*close)(rt_device_tdev);rt_size_t(*read)(rt_device_tdev,rt_off_tpos,void*buffer,rt_size_tsize);rt_size_t(*write)(rt_device_tdev,rt_off_tpos,constvoid*buffer,rt_size_tsize);rt_err_t(*control)(rt_device_tdev,intcmd,void*args);};11.3访问I/O设备IO设备管理接口与IO设备操作方法的映射关系如图11-6所示。图11-6I/O设备管理接口与I/O设备的操作方法的映射关系1. 查找设备应用程序根据设备名称获取设备句柄,进而可以操作设备。查找设备函数如下所示:rt_device_trt_device_find(constchar*name);2. 初始化设备获得设备句柄后,应用程序可使用如下函数对设备进行初始化操作:rt_err_trt_device_init(rt_device_tdev);3. 打开和关闭设备通过设备句柄,应用程序可以打开和关闭设备,打开设备时,会检测设备是否已经初始化,没有初始化则会默认调用初始化接口初始化设备。通过如下函数打开设备:rt_err_trt_device_open(rt_device_tdev,rt_uint16_toflags);4. 控制设备通过命令控制字,应用程序也可以对设备进行控制,通过如下函数完成:rt_err_trt_device_control(rt_device_tdev,rt_uint8_tcmd,void*arg);参数cmd的通用设备命令可取如下宏定义:5. 读写设备应用程序从设备中读取数据可以通过如下函数完成:rt_size_trt_device_read(rt_device_tdev,rt_off_tpos,void*buffer,rt_size_tsize);6. 数据收发回调当硬件设备收到数据时,可以通过如下函数回调另一个函数来设置数据接收指示,通知上层应用线程有数据到达:rt_err_trt_device_set_rx_indicate(rt_device_tdev,rt_err_t(*rx_ind)(rt_device_tdev,rt_size_tsize));通过如下函数设置设备发送完成指示,函数参数及返回值见:rt_err_trt_device_set_tx_complete(rt_device_tdev,rt_err_t(*tx_done)(rt_device_tdev,void*buffer));11.4设备访问示例下面代码为用程序访问设备的示例,首先通过rt_device_find()口查找到看门狗设备,获得设备句柄,然后通过rt_device_init()口初始化设备,通过rt_device_control()口设置看门狗设备溢出时间。#include<rtthread.h>#include<rtdevice.h>#defineIWDG_DEVICE_NAME"wdt"staticrt_device_twdg_dev;staticvoididle_hook(void){/*在空闲线程的回调函数里喂狗*/rt_device_control(wdg_dev,RT_DEVICE_CTRL_WDT_KEEPALIVE,NULL);rt_kprintf("feedthedog!\n");}intmain(void){rt_err_tres=RT_EOK;rt_uint32_ttimeout=10;/*溢出时间*/

/*根据设备名称查找看门狗设备,获取设备句柄*/wdg_dev=rt_device_find(IWDG_DEVICE_NAME);if(!wdg_dev){rt_kprintf("find%sfailed!\n",IWDG_DEVICE_NAME);returnRT_ERROR;}/*初始化设备*/res=rt_device_init(wdg_dev);if(res!=RT_EOK){rt_kprintf("initialize%sfailed!\n",IWDG_DEVICE_NAME);returnres;}/*设置看门狗溢出时间*/res=rt_device_control(wdg_dev,RT_DEVICE_CTRL_WDT_SET_TIMEOUT,&timeout);if(res!=RT_EOK){rt_kprintf("set%stimeoutfailed!\n",IWDG_DEVICE_NAME);returnres;}/*设置空闲线程回调函数*/rt_thread_idle_sethook(idle_hook);returnres;}11.5PIN设备芯片上的引脚一般分为4类:电源、时钟、控制与I/O。通用I/O口主要特性如下。1. 可编程控制中断中断触发模式可配置,一般有如图11-7所示5种中断触发模式。11.5.1引脚简介图11-7所示5种中断触发模式2. 输入输出模式可控制(1)输出模式:一般包括推挽、开漏、上拉、下拉。引脚为输出模式时,可以通过配置引脚输出的电平状态为高电平或低电平来控制连接的外围设备。(2)输入模式:一般包括浮空、上拉、下拉、模拟。引脚为输入模式时,可以读取引脚的电平状态,即高电平或低电平。应用程序通过RT-Thread提供的PIN设备管理接口来访问GPIO,相关接口如下所示:(1)rt_pin_get():获取引脚编号。(2)rt_pin_mode():设置引脚模式。(3)rt_pin_write():设置引脚电平。(4)rt_pin_read():读取引脚电平。(5)rt_pin_attach_irq():绑定引脚中断回调函数。(6)rt_pin_irq_enable():使能引脚中断。(7)rt_pin_detach_irq():脱离引脚中断回调函数。11.5.2访问PIN设备1. 获取引脚编号RT-Thread提供的引脚编号需要和芯片的引脚号区分开来,它们并不是同一个概念,引脚编号由PIN设备驱动程序定义,和具体的芯片相关。有3种方式可以获取引脚编号:API接口获取、使用宏定义或者查看PIN驱动文件。(1)使用API。使用rt_pin_get()获取引脚编号,如下获取PF9的引脚编号:pin_number=rt_pin_get("PF9");(2)使用宏定义.如果使用rt-thread/bsp/stm32目录下的BSP则可以使用下面的宏获取引脚编号:GET_PIN(port,pin)获取引脚号为PF9的LED0对应的引脚编号的示例代码如下所示:#defineLED0_PINGET_PIN(F,9)(3)查看驱动文件。如果使用其他BSP则需要查看PIN驱动代码drv_gpio.c文件确认引脚编号。此文件里有一个数组存放了每个PIN脚对应的编号信息,如下所示:staticconstrt_uint16_tpins[]={__STM32_PIN_DEFAULT,__STM32_PIN_DEFAULT,__STM32_PIN(2,A,15),__STM32_PIN(3,B,5),__STM32_PIN(4,B,8),__STM32_PIN_DEFAULT,__STM32_PIN_DEFAULT,__STM32_PIN_DEFAULT,__STM32_PIN(8,A,14),__STM32_PIN(9,B,6),......}以__STM32_PIN(2,A,15)为例,2为RT-Thread使用的引脚编号,A为端口号,15为引脚号,所以PA15对应的引脚编号为2。2. 设置引脚模式引脚在使用前需要先设置好输入或者输出模式,通过如下函数完成:voidrt_pin_mode(rt_base_tpin,rt_base_tmode);pin:引脚编号mode:引脚工作模式目前RT-Thread支持的引脚工作模式可取如所示的5种宏定义值之一,每种模式对应的芯片实际支持的模式需参考PIN设备驱动程序的具体实现:#definePIN_MODE_OUTPUT0x00/*输出*/#definePIN_MODE_INPUT0x01/*输入*/#definePIN_MODE_INPUT_PULLUP0x02/*上拉输入*/#definePIN_MODE_INPUT_PULLDOWN0x03/*下拉输入*/#definePIN_MODE_OUTPUT_OD0x04/*开漏输出*/3. 设置引脚电平设置引脚输出电平的函数如下所示:voidrt_pin_write(rt_base_tpin,rt_base_tvalue);pin:引脚编号value:电平逻辑值,可取2种宏定义值之一:PIN_LOW低电平,PIN_HIGH高电平4. 读取引脚电平读取引脚电平的函数如下所示:intrt_pin_read(rt_base_tpin);Pin:引脚编号返回:无PIN_LOW:低电平PIN_HIGH:高电平5. 绑定引脚中断回调函数若要使用到引脚的中断功能,可以使用如下函数将某个引脚配置为某种中断触发模式并绑定一个中断回调函数到对应引脚,当引脚中断发生时,就会执行回调函数:rt_err_trt_pin_attach_irq(rt_int32_tpin,rt_uint32_tmode,void(*hdr)(void*args),void*args);pin:引脚编号。mode:中断触发模式。hdr:中断回调函数,用户需要自行定义这个函数。args:中断回调函数的参数,不需要时设置为RT_NULL。返回:无。RT_EOK :绑定成功。错误码:绑定失败。6. 使能引脚中断绑定好引脚中断回调函数后使用下面的函数使能引脚中断:rt_err_trt_pin_irq_enable(rt_base_tpin,rt_uint32_tenabled);pin:引脚编号enabled

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论