I/O设备模型
io设备管理层提供了对设备驱动程序的封装,应用程序通过io设备管理层提供的接口向下访问硬件设备
设备驱动层是与硬件交互工作的程序,实现访问硬件设备的功能,负责注册和创建io设备
-
设备驱动层相关接口
rt_device_create
:设备被创建后需要实现它访问硬件条件的操作方法rt_device_register
:设备注册rt_device_find
:设备查找rt_device_read
:设备读取rt_device_open
:打开设备rt_device_write
:设备写入数据rt_device_close
:关闭设备
-
I/O设备模型
设备模型建立在内核基础上,设备对象是由基类派生而来。
- 访问io设备
应用程序通过I/O设备管理接口来访问硬件设备
- I/O设备模型框架
UART设备
应用程序通过RT-Thread提供的I/O设备管理接口来访问串口硬件
- 串口设备接收和发送数据的模式
- 中断模式
- DMA模式
- 流模式(轮询模式),如果没有指定模式,默认为该模式
流模式 RT_DEVICE_FLAG_STREAM 可以和接收发送模式参数使用或 “|” 运算符一起使用。
-
串口设备的相应API与设备驱动层接口一一对应
-
控制串口设备
rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);
缓冲区通过control接口修改,缓冲区大小无法动态修改,只有在open设备之前,可以配置,在open设备之后,缓冲区大小不可以再进行更改,除过缓冲区之外的其他参数,在设备open前后都可以进行更改。
- 串口发送完成回调函数:底层硬件数据发送完毕之后调用
rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t
dev,void *buffer));
- 串口接收完成回调函数:当串口接收到数据,通知上层应用数据到达
rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t
dev,rt_size_t size));
- 串口接收不定长数据
流程;串口接收不定长数据需要用户在应用层进行处理,一般会有特定的协议,比如一帧数据可能会有起始标记位、数据长度位、数据、终止标记位等,发送数据帧时按照约定的协议进行发送,接收数据时再按照协议进行解析。
PIN设备
-
芯片引脚分类
-
电源
-
时钟
-
控制与IO
- GPIO - 复用功能IO
-
-
Pin设备访问相关接口
- rt_pin_mode
- rt_pin_write
- rt_pin_read
- rt_pin_attach_irq
- rt_pin_irq_enable
- rt_pin_attach_irq
-
RT-Thread中的引脚编号与芯片引脚号
RT-Thread中的引脚编号在设备驱动程序
drv_gpio,c
中定义
也可以通过GET_PIN来获取芯片引脚对应的引脚编号#define LED0_PIN GET_PIN(F, 9)
- 对于某些设备驱动,我们通过menuconfig配置添加好了设备驱动之后,设备驱动会注册设备总线,之后我们需要向设备总线上挂载设备,之后再执行配置实现功能。如果是设备总线我们就需要添加设备使用,如果类型是设备,那么我们就可以直接使用。通过list_device查看
finsh控制台
- 概念
finsh是rtt的命令行组件,提供用户在命令行调用的接口,用于调试和打印信息。
-
finsh执行流程图
-
finsh的两种输入模式
- 传统命令行 msh 执行格式 command [arg1] [arg2] […]
- C语言解释器模式,输入的命令必须是C语言中的函数调用方式,必须携带()
可以在执行过程中添加以下代码,就能在执行过程中打印出finsh内置命令的信息
extern int msh_exec(char *cmd, rt_size_t length);
msh_exec("list_mailbox", rt_strlen("list_mailbox"));
-
打印出finsh的所有内置命令
help
-
自定义FinSH命令
将一个自定义的命令导出到msh模式使用这个函数接口
MSH_CMD_EXPORT(name,desc)
- 自定义C-Style命令和变量
将一个自定义命令到处到C-Style模式使用这个接口
FINSH_FUNCTION_EXPORT(name,desc)
自定义一个变量FINSH_VAR_EXPORT(name, type, desc)
- Finsh功能配置
finsh功能可裁剪,宏配置选项在rtconfig.h文件中定义
虚拟文件系统
-
DFS(Device File System) 设备虚拟文件系统
-
文件系统目录的表示
统一的根目录 / ,根目录下的文件f1.bin 表示为 /f1.bin,目录分隔符是
\
-
DFS框架
-
POSIX接口层:
表示可移植操作系统接口(Portable Operating System Interface of UNIX),posix标准定义了操作系统应该为应用程序提供的接口标准,是 IEEE 为要在各种 UNIX 操作系统上运行
的软件而定义的一系列 API 标准的总称。目的是为了获得源代码级别的软件可移植性。
-
虚拟文件系统层:
- FatFS
- RomFS
- Jffs2:日志闪存文件系统
- DevFS:设备文件系统
- NFS网络文件系统
- UFFS,Ultra-low-cost Flash File System(超低功耗的闪存文件系统)的简称。
-
设备抽象层
将物理设备抽象成符合文件系统可以访问的设备,不同文件系统独立与存储设备驱动实现的,把底层存储设备的驱动接口和文件系统对接,才可以正确使用文件系统功能。
-
文件系统初始化的步骤
-
- 初始化DFS组件 dfs_init()
-
- 注册文件系统
-
- 将存储设备注册为块设备:只有块设备可以挂载到文件系统上
-
- 格式化文件系统
-
- 挂载文件系统:将一个存储设备挂接到一个已经存在的路径上
-
- 卸载文件系统
-
-
文件描述符
当使用open打开或者创建一个文件时,内核会向进程返回一个文件描述符,所有执行的io操作都是通过这个文件描述符索引到对应的文件,在同一个进程中打开同一个文件,只有一个文件描述符。
-
文件管理相关接口
- 打开文件
int open(const char *file, int flags, ...)
- 关闭文件
int close(int fd)
- 读数据
int read(int fd, void *buf, size_t len)
- 写数据
int write(int fd, const void *buf, size_t len)
- 重命名
int rename(const char *old, const char *new)
- 取得状态
int stat(const char *file, struct stat *buf)
- 删除文件
int unlink(const char *pathname)
- 同步文件数据到存储设备
int fsync(int fildes)
- 查询文件系统相关的信息
int statfs(const char *path, struct statfs *buf)
- 监视IO设备状态
select()
- 打开文件
-
目录管理
- 读取目录:
struct dirent* readdir(DIR *d)
- 取的目录流的读取位置
long telldir(DIR *d)
- 设置下次读取目录的位置
void seekdir(DIR *d, off_t offset)
- 重设读取目录的位置为开头位置
void rewinddir(DIR *d)
- 读取目录:
虚拟文件系统配置使用步骤
- 首先通过STM32CUbemx来配置sd卡相关的驱动
- 通过编写kconfig文件来将sd相关的驱动添加文件中,这时候设备列表就已经有了sd设备
- 初始化DFS组件,这一步已经在初始化中自动配置
- 先查找相关的sd设备,之后挂载文件系统
dfs_mount
,文件系统正常挂载之后就可以正常操作文件系统
日志
- 日志
将软件运行的相关信息输出到不同的控制台介质中