rt\_pin\_mode(LED1_PIN, PIN_MODE_OUTPUT);
/\* 把KEY引脚设置为输入 \*/
rt\_pin\_mode(KEY0_PIN, PIN_MODE_INPUT);
rt\_pin\_mode(KEY1_PIN, PIN_MODE_INPUT);
rt\_pin\_mode(KEY2_PIN, PIN_MODE_INPUT);
rt\_pin\_mode(KEY_UP_PIN, PIN_MODE_INPUT);
/\* 先把两个灯都关掉 \*/
rt\_pin\_write(LED0_PIN, PIN_HIGH);
rt\_pin\_write(LED1_PIN, PIN_HIGH);
while (1)
{
/\* 读取KEY0引脚电平 \*/
if (rt\_pin\_read(KEY0_PIN) == PIN_LOW)//按键按下时为低电平
{
rt\_thread\_mdelay(10);//延时消抖
t++;
if (t == 200)
{//长按两秒
j = ~j;
if(j)
{
rt\_pin\_write(LED1_PIN, PIN_LOW);//点亮LED1
}
else
{
rt\_pin\_write(LED1_PIN, PIN_HIGH);//熄灭LED1
}
}
}
else if(rt\_pin\_read(KEY0_PIN) != PIN_LOW)//按键松开
{
if(t >=3 && t<= 200)
{//短按
i = ~i;
if(i)
{
rt\_pin\_write(LED0_PIN, PIN_LOW);//点亮LED0
}
else
{
rt\_pin\_write(LED0_PIN, PIN_HIGH);//熄灭LED0
}
}
t = 0;
}
}
}
**启用Rthread studio 的Terminal 可以开启串口**
使用xterm来进行msh的使用(要求main里面的while(1)需要延时期间会挂起线程不占用cpu资源)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6e1d24d0e8d94ac5a212cdba16564173.png)
### 2.IO设备框架
[矜辰所致的博客导航]( )
简单的设备–无需经过设备驱动层,直接注册到IO设备管理层,
复杂的设备 --> 设备驱动层–>IO设备管理层
创建的设备示例先注册到对应的设备驱动框架,再有设备驱动框架往IO设备管理层进行注册
drv.usart.c --> serial.c -->
在RT-Thread中,设备也是一种内核对象,和以前说的线程,IPC机制,定时器等对象一样,有自己的对象控制块
**设备对象控制块**
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f933fad26daa46f8988b4b21b72e7044.png)
设备类型 —字符、块、其他设备类型
设备注册 flag --属于什么状态的设备,可读、可写、收发等
设备访问 open\_flag —设备访问的时候,需要使用这个 open\_flag 来判断需要对设备进行什么操作,是读?还是写? 还是发送等。。。
/** rtdef.h
* Device structure
*/
struct rt_device
{
struct rt_object parent; /**< inherit from rt_object */
enum rt\_device\_class\_type type; /\*\*< device type \*/
rt\_uint16\_t flag; /\*\*< device flag \*/
rt\_uint16\_t open_flag; /\*\*< device open flag \*/
rt\_uint8\_t ref_count; /\*\*< reference count \*/
rt\_uint8\_t device_id; /\*\*< 0 - 255 \*/
/\* device call back \*/
rt\_err\_t (\*rx_indicate)(rt\_device\_t dev, rt\_size\_t size);
rt\_err\_t (\*tx_complete)(rt\_device\_t dev, void \*buffer);
#ifdef RT_USING_DEVICE_OPS
const struct rt_device_ops *ops;
#else
/* common device interface */
rt_err_t (*init) (rt_device_t dev);
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
rt_err_t (*close) (rt_device_t dev);
rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
#endif
#if defined(RT_USING_POSIX)
const struct dfs_file_ops *fops;
struct rt_wqueue wait_queue;
#endif
void \*user_data; /\*\*< device private data \*/
};
device.c
设备创建 = 初始化+操作方法 vs 设备销毁
设备注册 (到IO设备管理器,应用程序才可访问) vs 设备注销
注销只是把这个 设备对象结构体 从管理链表中去掉,并不会释放这个对象结构体的空间,要释放空间需要调用销毁设备函数。
查找设备
初始化设备
打开和关闭设备
UART 设备模型 是复习理解 RT-Thread I/O 设备模型的完美设备。
设备驱动层和设备驱动框架层
在 RT-Thread 操作系统中,对UART设备的初始化,可以理解为就是对 stm32\_uart 结构体对象 的初始化
int rt_hw_usart_init(void)
{
rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct stm32_uart);
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_err_t result = 0;
stm32\_uart\_get\_dma\_config();
for (int i = 0; i < obj_num; i++)
{
uart_obj[i].config = &uart_config[i];
uart_obj[i].serial.ops = &stm32_uart_ops;
uart_obj[i].serial.config = config;
/\* register UART device \*/
result = rt\_hw\_serial\_register(&uart_obj[i].serial, uart_obj[i].config->name,
RT_DEVICE_FLAG_RDWR
| RT_DEVICE_FLAG_INT_RX
| RT_DEVICE_FLAG_INT_TX
| uart_obj[i].uart_dma_flag
, NULL);
RT\_ASSERT(result == RT_EOK);
}
return result;
}
board.c(rt\_hw\_board\_init–>hw\_board\_init 完成板子的bsp初始化,其内部使用宏来管理pin设备和usat设备等通rtthread setting 组件一致)
rt\_hw\_usart\_init–> (usart初始化)
rt\_hw\_serial\_register(设备驱动框架,其内部调用rt\_device\_register)
–>rt\_device\_register(通用注册函数,用于将其注册到IO设备管理器)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/97f9fa96bb2d49349ee2aea7306091a3.png)
串口RX —我们正常的项目使用中,一般都是 中断接收 或者 DMA 接收,
~~基本上不会使用 轮询接收的方式~~
在 RT-Thread 系统中,我们常用信号量或者消息队列 来标志是否接收到串口数据,这样的好处是当没有数据的时候,会将数据处理线程挂机,让出CPU资源
串口TX — 轮询 方式发送。
/*轮询方式发送,中断接收orDMA接收*/
[RT-thread相关教程汇总–env]( )
开发环境搭建!rtthread源码版本下载4.0.3(可通过rtthread studio快速获取)
尽量使用env开发工具来增添移除文件,使用keil来增添时,下一次使用env将会移除
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/36f0cc6fe00d49ddba8db0e5d1930cf9.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/49ccb791eaed4d488d9cf87d7f811be3.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2e86b65d07d24f34913cae1d6b8ad3b7.png)
UART 设备的设备驱动框架层,是有定义了 UART 设备自己的控制块,其继承了rt\_device的内容,同时还增加了 UART 设备特有的一些配置,操作,回调函数之类的内容
### pin设备
pin设备的对象结构体在pin.h中有定义,struct rt\_device\_pin
rt\_hw\_pin\_init()会调用 rt\_device\_pin\_register 函数进行 PIN 设备的初始化
![int entry --> rtthread_startup-->bo](https://img-blog.csdnimg.cn/direct/248c86eadfe14469964e75c799a37ef9.png)
在hw\_board\_ini进行对rt\_hw\_pin\_init()对引脚进行配置,通过宏开启是否对该组件进行配置
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0c4bc42363ec4b26a1887f705a2508cd.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b79d66a2caf24ce6ae12aa4749bdea92.png)
rt\_hw\_pin\_init()内部使用rt\_device\_pin\_register设备驱动框架层注册,
rt\_device\_pin\_register使用rt\_device\_register注册到IO设备管理层,在pin.c中,提供了应用层访问硬件的接口
应用层是通过设备驱动框架层的rt\_pin\_get 、rt\_pin\_read 、rt\_pin\_write 来控制硬件
### ADC设备
**ADC 通道** MCU一般都有 ADC 引脚,将需要检测的模拟量连接至对应的 IO 口,做好配置就能使用
**ADC 分辨率**
STM32F1xx 系列的芯片来说,他们的 ADC 最大支持12位
一个ADC设置为 12 位的分辨率,2 的12 次方 = 4096,简单来说就是这个 ADC 设备把他的量程分为 4096 份:0 ~ 4095 最大值 4095 就等于他量程的最大值
STM32 ADC的量程为 0~ 3.3V,如果读到 4095 的ADC 值,就表示读到的电压为 3.3V
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f4c1ddc0e20d4775a54f468df32628a0.png)
ADC设备操作函数
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ddb870f0665f47468841820d2aaa09f3.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ea18f0d596064811ae6d57e36360b571.png)
**实际操作**
[I/O 设备模型之ADC设备]( )
### SPI设备
SPI 通讯有4种模式,由 CPOL (时钟的极性)和 CPHA (时钟的相位)决定:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/912c1a9d9028472e8748dc03c98bcaf0.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/67cef94c819b43e3a72903ea5f251aca.png)
挂载SPI设备,
spi设备操作:读取墨水屏驱动ID,
[RT-thread SPI SFUD读写W25Q128]( )
SFUD库源移植: [sfud-通用的spi-flash库]( )
基于hal库的使用,printf的重定向支持,
## wds\_rtthread study
### 开始篇目:先从设备驱动程序学习!
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/31f7ca4838c9463cbaf99ca4af54b223.png)
1. 统一设备接口,使用设备驱动框架层()
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/74104a0c674b48a3a6a36f4af3f4359f.png)
2. PIN驱动分析
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a4a393236d274bf8a7574c759aec9289.png)
---
3. I2C设备
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5c13fd8674dd44febdaa04ceedde541e.png)
4. 块设备驱动程序
核心要点就是:
写入数据到pos位置,由此读该pos位置可以得到写入的数据,
不同于字符设备主要体现在控制功能,如led点亮熄灭操作。块设备传输数据的单位为扇区,具有存储功能
描述磁盘容量信息:有多少个扇区,扇区大小为多少,可擦除的块有多大
5. 文件系统
[基于RTThread的DFS文件系统组件使用笔记]( )
POSIX 标准定义了操作系统应该为应用程序提供的接口标准,是 IEEE 为要在各种 UNIX 操作系统上运行的软件而定义的一系列 API 标准的总称
DFS虚拟文件系统向用户应用程序提供POSIX接口层,POSIX接口层是给开发者使用的接口 函数层。开发者使用POSIX接口层提供的POSIX API进行文件操作,无需关心文件系统是 如何实现的,也无需关心数据是存放在哪个存储设备中。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e8de2deb6be6418985d2232d55c4c684.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/45a67de47bda45b1be868c5f75152829.png)
提炼点:[参考文章]( )
5.1.挂载点
windows 下插入一个U盘,盘符信息、文件系统格式信息、块设备驱动程序(读、写、擦除设备操作)
对于rtthread或linux系统来说,没有盘符的概念,而是一个树状结构的文件目录格式,相当与将某一设备挂载在某一个目录下(该目录等价于设备之于操作系统明确的实际位置)
以linux 操作系统举例:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d19d19ac4cba484c9a0137949c346b82.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/74fc2789c3214d2bb141a1f3c7db8676.png)
---
5.1.挂载点、文件系统、块设备三者之间的关系
### 提升篇目: 链表与对象管理器的学习
### 内核知识学习
### stm32基础+cubemx+硬件
[硬件开发+嵌软+自制MQTT服务器]( )
STM32程序编写风格:
把所有用到的头文件存放到一个include.h 中,后期所有的.c 文件皆包含该头文件,举例如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1c55244fba6242a38379554e0b518ce4.png)
用法,效果修饰凡是test.h 声明的函数,其他文件就可以直接去使用
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0baa132f3245473db1426c0f36e8f6a5.png)
在test.c中定义一个变量,同时在test.h 中声明,让其他文件调用
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f0ac98fc47094eb0b133444d5fb79c2f.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/14967c61bdc2426cbc05d8c4abd7c0b9.png)
## 总结
提示:这里对文章进行总结:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ca03e3fedd3243ad91a0a4c35d1876de.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/eeefb1e96c2249f9a90a095f121121c0.png)
### env 工具的学习
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/19f1d183deb5bba5f114ab2ffbf4c10f.png)
![img](https://img-blog.csdnimg.cn/img_convert/b57e196bddacfe41956da5b47464ec8a.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/a29f6626737787809f536bbad2129612.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
![img](https://img-blog.csdnimg.cn/img_convert/d55a5fa90e749eab28a8ee2bec3bc35c.png)
![img](https://img-blog.csdnimg.cn/img_convert/ddf5d31ea167c3b037d3c836d092bf5f.png)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**
<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />
# 最后
**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**
**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**
mg-VxWGqTQV-1712309365118)]
[外链图片转存中...(img-3vAc35in-1712309365119)]
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**
<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />
# 最后
**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**
**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**
**[更多资料点击此处获qu!!](https://bbs.csdn.net/topics/618376385)**