Merge branch 'main' into lcd

This commit is contained in:
james 2024-08-01 01:01:19 +08:00
commit 9e50787861
34 changed files with 862 additions and 495 deletions

12
.config
View File

@ -1077,7 +1077,11 @@ CONFIG_PKG_AHT10_VER="latest"
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_CW2015 is not set
# CONFIG_PKG_USING_ICM20608 is not set
CONFIG_PKG_USING_ICM20608=y
CONFIG_PKG_ICM20608_PATH="/packages/peripherals/sensors/icm20608"
# CONFIG_PKG_USING_ICM20608_V100 is not set
CONFIG_PKG_USING_ICM20608_LATEST_VERSION=y
CONFIG_PKG_ICM20608_VER="latest"
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_STHS34PF80 is not set
# end of sensors drivers
@ -1567,7 +1571,7 @@ CONFIG_BSP_USING_FAL=y
CONFIG_BSP_USING_RW007_WLAN=y
CONFIG_BSP_USING_AHT21=y
# CONFIG_BSP_USING_AP3216C is not set
# CONFIG_BSP_USING_ICM20608 is not set
CONFIG_BSP_USING_ICM20608=y
# CONFIG_BSP_USING_USB_MOUSE is not set
# CONFIG_BSP_USING_CAN is not set
# CONFIG_BSP_USING_AUDIO is not set
@ -1604,7 +1608,9 @@ CONFIG_BSP_USING_SPI2=y
# CONFIG_BSP_USING_ADC is not set
CONFIG_BSP_USING_I2C=y
# CONFIG_BSP_USING_I2C1 is not set
# CONFIG_BSP_USING_I2C2 is not set
CONFIG_BSP_USING_I2C2=y
CONFIG_BSP_I2C2_SCL_PIN=81
CONFIG_BSP_I2C2_SDA_PIN=80
CONFIG_BSP_USING_I2C3=y
CONFIG_BSP_I2C3_SCL_PIN=64
CONFIG_BSP_I2C3_SDA_PIN=65

View File

@ -54,3 +54,4 @@ for item in list:
Return('group')
```
[RSOC问题汇总连接](https://docs.qq.com/doc/DY2VrUlpuRWlRUkdI)

View File

@ -4,7 +4,8 @@
![alt text](image.png)
1. √
2. 互斥量
3.
3. 挂起:先做其它
死锁:互相等待……
## 临界区
only one can use the resource at a time
@ -82,11 +83,11 @@ rt_err_t rt_sem_trytake(rt_sem_t sem);
``` c
rt_err_t rt_sem_release(rt_sem_t sem);
```
## 互斥量
## 互斥量(互斥锁)
约等于仅有的一把钥匙
保护临界资源
多次获取多次释放???
![alt text](image-7.png)
1. 互斥量所用权
2. 防止优先级反转
### 优先级反转
高优先级被低优先级阻塞
实时:高优先级先执行
@ -97,13 +98,14 @@ rt_err_t rt_sem_release(rt_sem_t sem);
![alt text](image-8.png)
把A的优先级临时赋C
![alt text](image-9.png)
### 创建和删除???互斥量
### 创建和删除互斥量
无论选择 RT_IPC_FLAG_PRIO 还是 RT_IPC_FLAG_FIFO内核均按照 RT_IPC_FLAG_PRIO 处理
``` c
rt_mutex_t rt_mutex_create (const char* name, rt_uint8_t flag);
rt_err_t rt_mutex_delete (rt_mutex_t mutex);
```
无论选择 RT_IPC_FLAG_PRIO 还是 RT_IPC_FLAG_FIFO内核均按照 RT_IPC_FLAG_PRIO 处理
### 初始化和脱离互斥量
``` c
@ -111,50 +113,74 @@ rt_err_t rt_mutex_init (rt_mutex_t mutex, const char* name, rt_uint8_t flag);
rt_err_t rt_mutex_detach (rt_mutex_t mutex);
```
### 获取互斥量
+1???
如果互斥量已经被当前线程控制,在当前线程再一次获取,那么该互斥量的持有计数+1当前线程不会挂起
``` c
rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time);
```
### 无等待获取互斥量
``` c
rt_err_t rt_mutex_trytake(rt_mutex_t mutex);
```
### 释放互斥量
信号量:谁都可以获取,谁都可以释放
互斥量:只有拥有互斥量控制权的线程才可以释放,每释放一次,持有计数-1当持有计数为0时才变为可用
``` c
rt_err_t rt_mutex_release (rt_mutex_t mutex);
```
## 事件集
一堆事件在32bit中在线程中与或判断执行
一堆事件在32bit中32个事件0/1在线程中与或判断执行
- 发送: 从中断/线程中
- 接收: 线程接收,条件检查
![alt text](image-10.png)
### 创建事件集
``` c
rt_event_t rt_event_create(const char* name, rt_uint8_t flag);
```
### 删除事件集
???唤醒
删除前唤醒所有挂起在该事件集上的线程,返回`-RT_ERROR`
create用这个
``` c
rt_err_t rt_event_delete(rt_event_t event);
```
### 初始化事件集
静态事件集对象的内存一般放于**读写数据段**或**未初始化数据段**中
``` c
rt_err_t rt_event_init(rt_event_t event, const char* name, rt_uint8_t flag);
```
### 脱离事件集
create 不能用
``` c
rt_err_t rt_event_detach(rt_event_t event);
```
### ……
jssjian
### 发送事件集
set 即我们要发送的1<<n
`rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set);`
### 接收事件集
set :当前目标需要的事件
option RT_EVENT_FLAG_OR RT_EVENT_FLAG_AND
recved : 接收到刚发送的事件
```c
rt_err_t rt_event_recv(rt_event_t event,
rt_uint32_t set,
rt_uint8_t option,
rt_int32_t timeout,
rt_uint32_t* recved);
```
## (消息)邮箱
也叫交换信息
4个字节32位恰好可以传递指针
![alt text](image-11.png)
### 创建邮箱
这块内存的大小等于邮件大小4 字节)与邮箱容量(size)的乘积
``` c
rt_mailbox_t rt_mb_create(const char* name, rt_uint32_t size, rt_uint8_t flag);
```
@ -164,34 +190,75 @@ rt_err_t rt_mb_delete(rt_mailbox_t mb);
```
### 初始化邮箱
``` c
rt_err_t rt_mb_init(rt_mailbox_t mb, const char* name, rt_uint32_t size, rt_uint8_t flag);
```
### 脱离邮箱
rt_err_t rt_mb_init(rt_mailbox_t mb,
const char* name,
void* msgpool,
rt_size_t size,
rt_uint8_t flag)
### 等待
不能在中断中使用???
```
### 发送邮件
``` c
rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32_t value);
```
### 等待方式发送
邮箱满了可以等待一段时间,不能在中断中使用
### 接收邮件
地址存到val ue
``` c
rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32_t* value, rt_int32_t timeout);
```
### ...
## 消息队列
![alt text](image-11.png)
### 异步通信
1.vs2.
超时机制即timeout
![alt text](image-12.png)
1消息 多线程?
FIFO 对于谁
launch
停止?
。。。
FIFO :线程先得到先进入消息队列的消息
RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO :哪个线程先
### 创建消息队列
区别rt_size_t msg_size, rt_size_t max_msgs,
``` c
rt_mq_t rt_mq_create(const char* name,
rt_size_t msg_size,
rt_size_t max_msgs,
rt_uint8_t flag);
```
![alt text](image-13.png)
### 发送
中断里面不可以用`rt_mq_send_wait`
``` c
rt_err_t rt_mq_send (rt_mq_t mq, void* buffer, rt_size_t size);
```
IPC示例
![ipc_sample](image-14.png)
[示例代码在这里](.\packages\kernel_samples-latest\zh)
[一个好用的串口工具类似mobaxterm](https://wterm.wkjay.com/)
dist 的好处
加入sample
配置完任何软件包都要在env中
``` c
pkgs --update
```
## 示例按键灭灯
## 按键灭灯实践
### 灭了怎么点都不亮
因为按键按灭就没再点亮
在key线程循环开始每次点亮
### 灯轻微闪烁,几乎看不出
不能及时获取?用无等待获取信号量?
### 还是一样……
因为采用了延时防止误触,判断是否按下按键花了一点时间
~~只要知道按键没有按下就亮灯就行~~
在下次判断按键没按下之后再亮灯
### 居然在按键的线程在控制led
改为没摁才释放信号量led线程获取到后设为亮灯
并在获取信号量前将led设为灭灯
``` c
#include <board.h>
#include <rtthread.h>
@ -303,15 +370,4 @@ static void led_name_entry(void *parameter)
}
}
```
### 灭了怎么点都不亮
因为按键按灭就没再点亮
在key线程循环开始每次点亮
### 灯轻微闪烁,几乎看不出
不能及时获取?用无等待获取信号量?
### 还是一样……
因为采用了延时防止误触,判断是否按下按键花了一点时间
~~只要知道按键没有按下就亮灯就行~~
在下次判断按键没按下之后再亮灯
### 居然在按键的线程在控制led
改为没摁才释放信号量led线程获取到后设为亮灯
并在获取信号量前将led设为灭灯

BIN
Day3/image-13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
Day3/image-14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

View File

@ -1,11 +1,36 @@
# 设备驱动
## I/O设备框架概念
### SPI驱动和设备驱动分离提供统一的API
• 更换 MCU 只需要改变对应的对接驱动
• 重新驱动设备,只需要重新编写设备驱动相关的代码
• 同一 API 接口,学习成本低
• 分离后设备驱动可以入库,供公司其他项目使用,减少碎片化开发,防止反复造轮子
• 代码框架会变复杂,但是从上面的优点来看是值得的
![spi驱动与设备驱动分离示意图](image-3.png)
### I/O框架
显示屏、串口通信、flash、SD卡、以太网接口
open,close...
I/O设备显示屏、串口通信、flash、SD卡、以太网接口……
接口open,close...
![I/O框架图](image-4.png)
![I/O框架图演进](image-7.png)
### 派生设备种类
![alt text](image.png)
``` c
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 /* USB device 设备 */
RT_Device_Class_USBHost /* USB host 设备 */
RT_Device_Class_SPIBUS /* SPI 总线设备 */
RT_Device_Class_SPIDevice /* SPI 设备 */
RT_Device_Class_SDIO /* SDIO 设备 */
RT_Device_Class_Miscellaneous /* 杂类设备 */
```
### 字符设备、块设备
#### 字符设备
顺序读取:键盘、串口
@ -14,39 +39,144 @@ open,close...
### 为什么分类设备
一类的控制相同
### 例子
RT_D
![alt text](image-5.png)
##
## api
[点击查看官网文档api介绍](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/device?id=%e5%88%9b%e5%bb%ba%e5%92%8c%e6%b3%a8%e5%86%8c-io-%e8%ae%be%e5%a4%87)
### 创建销毁设备
### 注册销毁
### flags
分行?
### 实验1注册
……_stream :向串口终端输出字符串
`\n ``\r\n`
### 实验1注册字符设备
``` c
#include <rtthread.h>
#include <rtdevice.h>
static int rt_device_test_init(void)
{
rt_device_t test_dev = rt_device_create(RT_Device_Class_Char,0);
if(!test_dev)
{
rt_kprintf("test_dev create failed\n");
return -RT_ERROR;
}
if(rt_device_register(test_dev,"test_dev",RT_DEVICE_FLAG_RDWR)!=RT_EOK)
{
rt_kprintf("test_dev register failed\n");
}
return RT_EOK;
}
MSH_CMD_EXPORT_ALIAS(rt_device_test_init,devtest, test device init);
```
![alt text](image-6.png)
### 访问设备
open,close...
### ……
### 访问
### 查找、初始化
### 打开、关闭
### 打开标志位
### 控制设备
### 读写设备
### 回调
### 调用关系图
IO设备管理层
PIN设备驱动框架层
PIN设备驱动层
## PIN设备
## GPIO
引脚电源、时钟、控制、I/O
GPIO,功能复用I/O
可编程控制中断
### GPIO
芯片上的引脚分为 4 类电源、时钟、控制、I/O
I/O 口使用模式:
- GPIOGeneral Purpose Input Output通用输入 / 输出)),
- 功能复用I/O如 SPI/I2C/UART 等)
### 可编程控制中断
![alt text](image-1.png)
rt_pin_mode()
rt_pin_write()
rt_pin_read()
### 常用接口
- rt_pin_mode()
- rt_pin_write()
- rt_pin_read()
- rt_pin_attach_irq() :绑定引脚中断回调函数
- rt_pin_irq_enable() :使能引脚中断
- rt_pin_detach_irq() :脱离引脚中断回调函数
……
![alt text](image-2.png)
Assert断言判断是否为真假则报错终止运行
### 外部中断
### 实验:外部中断
LOG 不用\n
``` c
#include <drv_gpio.h>
#include <rtdevice.h>
#include <rtthread.h>
#define LOG_TAG "pin.irq"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
#define KEY_UP GET_PIN(C, 5)
#define KEY_DOWN GET_PIN(C, 1)
#define KEY_LEFT GET_PIN(C, 0)
#define KEY_RIGHT GET_PIN(C, 4)
void key_up_callback(void *args)
{
int value = rt_pin_read(KEY_UP);
LOG_I("key up value: %d\n", value);
}
void key_down_callback(void *args)
{
int value = rt_pin_read(KEY_DOWN);
LOG_I("key down value: %d\n", value);
}
void key_left_callback(void *args)
{
int value = rt_pin_read(KEY_LEFT);
LOG_I("key left value: %d\n", value);
}
void key_right_callback(void *args)
{
int value = rt_pin_read(KEY_RIGHT);
LOG_I("key right value: %d\n", value);
}
static int rt_pin_irq_example(void)
{
rt_pin_mode(KEY_UP, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(KEY_DOWN, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(KEY_LEFT, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(KEY_RIGHT, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(KEY_UP, PIN_IRQ_MODE_FALLING, key_up_callback, RT_NULL);
rt_pin_attach_irq(KEY_DOWN, PIN_IRQ_MODE_FALLING, key_down_callback, RT_NULL);
rt_pin_attach_irq(KEY_LEFT, PIN_IRQ_MODE_FALLING, key_left_callback, RT_NULL);
rt_pin_attach_irq(KEY_RIGHT, PIN_IRQ_MODE_FALLING, key_right_callback, RT_NULL);
rt_pin_irq_enable(KEY_UP,PIN_IRQ_ENABLE);
rt_pin_irq_enable(KEY_DOWN,PIN_IRQ_ENABLE);
rt_pin_irq_enable(KEY_LEFT,PIN_IRQ_ENABLE);
rt_pin_irq_enable(KEY_RIGHT,PIN_IRQ_ENABLE);
return RT_EOK;
}
MSH_CMD_EXPORT_ALIAS(rt_pin_irq_example,irq, pin_irq_example);
```
![irq](image-8.png)
### FlexibleButton 按键库(可用)
![fexible button config](image-9.png)
## I2C总线
[官方文档链接](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/i2c)
I2C 是 Inter-Integrated Circuit 的简称读作I-squared-C
I2C 总线传输数据时只需两根信号线,一根是双向数据线 **SDA**serial data另一根是双向时钟线 **SCL**serial clock。SPI 总线有两根线分别用于主从设备之间接收数据和发送数据,而 I2C 总线只使用一根线进行数据收发。不同于 SPI 一主多从的结构,它允许同时有多个主设备存在
RTT用GPIO模拟I2C
![alt text](image-10.png)
应答信号: 每传输完成一个字节的数据,接收方就需要回复一个 ACKacknowledge。写数据时由从机发送 ACK读数据时由主机发送 ACK。当主机读到最后一个字节数据时可发送 NACKNot acknowledge然后跟停止条件。
![alt text](image-11.png)
![alt text](image-12.png)
![alt text](image-13.png)
手动添加
Kconfig → drv_soft_i2c.c&h
list device 查看
六轴***
![alt text](image-14.png)
可尝试i2c-tools 软件包

85
Day4/icm_20608_sample.c Normal file
View File

@ -0,0 +1,85 @@
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <icm20608.h>
#define LOG_TAG "icm.app"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
static void icm_thread_entry(void *parameter)
{
icm20608_device_t dev = RT_NULL;
const char *i2c_bus_name = "i2c2";
int count = 0;
rt_err_t result;
/* 初始化 icm20608 传感器 */
dev = icm20608_init(i2c_bus_name);
if (dev == RT_NULL)
{
LOG_E("The sensor initializes failure");
}
else
{
LOG_D("The sensor initializes success");
}
/* 对 icm20608 进行零值校准:采样 10 次,求取平均值作为零值 */
result = icm20608_calib_level(dev, 10);
if (result == RT_EOK)
{
LOG_D("The sensor calibrates success");
LOG_D("accel_offset: X%6d Y%6d Z%6d", dev->accel_offset.x, dev->accel_offset.y, dev->accel_offset.z);
LOG_D("gyro_offset : X%6d Y%6d Z%6d", dev->gyro_offset.x, dev->gyro_offset.y, dev->gyro_offset.z);
}
else
{
LOG_E("The sensor calibrates failure");
icm20608_deinit(dev);
}
while (count++ < 100)
{
rt_int16_t accel_x, accel_y, accel_z;
rt_int16_t gyros_x, gyros_y, gyros_z;
/* 读取三轴加速度 */
result = icm20608_get_accel(dev, &accel_x, &accel_y, &accel_z);
if (result == RT_EOK)
{
LOG_D("current accelerometer: accel_x%6d, accel_y%6d, accel_z%6d", accel_x, accel_y, accel_z);
}
else
{
LOG_E("The sensor does not work");
}
/* 读取三轴陀螺仪 */
result = icm20608_get_gyro(dev, &gyros_x, &gyros_y, &gyros_z);
if (result == RT_EOK)
{
LOG_D("current gyroscope : gyros_x%6d, gyros_y%6d, gyros_z%6d", gyros_x, gyros_y, gyros_z);
}
else
{
LOG_E("The sensor does not work");
break;
}
rt_thread_mdelay(1000);
}
}
static int icm_app(void)
{
rt_thread_t res = rt_thread_create("icm", icm_thread_entry, RT_NULL, 1024, 20, 50);
if(res == RT_NULL)
{
return -RT_ERROR;
}
rt_thread_startup(res);
return RT_EOK;
}
MSH_CMD_EXPORT(icm_app, icm_app);

BIN
Day4/image-10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
Day4/image-11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
Day4/image-12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
Day4/image-13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
Day4/image-14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
Day4/image-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
Day4/image-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
Day4/image-5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
Day4/image-6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
Day4/image-7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

BIN
Day4/image-8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
Day4/image-9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@ -234,7 +234,7 @@ W25Q64→注册为spi20设备挂载到spi2总线上**SPI设备**)→*通
**分区表**
| (不用管) | 分区名称 | 位置 | 偏移量 | 大小 |
| --- | --- | --- | --- | --- |
| - | - | - | - | - |
![分区表](image-2.png)
@ -274,8 +274,102 @@ void WIFI_CS_PULL_DOWM(void)
INIT_BOARD_EXPORT(WIFI_CS GET_PIN);
```
## 我的实践
### 读取传感器数据,上传到阿里云
### 1. 使用AHT10软件包采集温湿度并上传到阿里云
(合并头两个代码),拼接字符串时我用了`sprintf`,其实应该也可以样例原有的`HAL_Snprintf`的
### 2. 将font分区给挂载上。在温湿度上传上传云端的同时将数据同步放在文件系统处
文件名为Data.txt文件内容
> TempXX ; HumiXX ; Count 1自上电起所采集的数据次数
TempXX ; HumiXX ; Count 2自上电起所采集的数据次数
TempXX ; HumiXX ; Count 3自上电起所采集的数据次数
在`drv_filesystem.c`中实现挂载font
``` c
fal_init();
fal_blk_device_create("font");
/* 创建目录 */
ret = mkdir("/fal/test", 0x777);
if (ret < 0)
{
/* 创建目录失败 */
rt_kprintf("dir error!\n");
}
else
{
/* 创建目录成功 */
rt_kprintf("mkdir ok!\n");
}
/* 挂载块设备"font"到 DFS 目录/fal/test中 */
if (dfs_mount("font", "/fal/test", "elm", 0, 0) == 0)
{
LOG_I("font initialized!");
}
else
{
dfs_mkfs("elm", "font");
if (dfs_mount("font", "/fal/test", "elm", 0, 0) == 0)
{
LOG_I("font initialized!");
}
else
{
LOG_E("Failed to initialize font!");
LOG_D("You should create a filesystem(font) on the block device first!");
}
}
```
接着文件末尾添加数据(Data.txt)
![alt text](image-7.png)
``` c
void make_file()
{
//文件描述符
int fd;
//用只写方式打开文件,如果没有该文件,则创建一个文件
fd = open("/fal/test/Data.txt", O_WRONLY | O_CREAT | O_APPEND); //和原来相比只是把O_TRUNC参数更改为O_APPEND即更改为打开后如果再进行写入将从文件的末尾位置开始写。
// rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,String);
//如果打开成功
if (fd >= 0)
{
//写入文件
write(fd, tmp, sizeof(tmp));
// rt_kprintf("Write done.\n");
//关闭文件
close(fd);
}
else
{
rt_kprintf("File Open Fail.\n");
}
return;
}
```
### 3. 利用云端给开发板发送指令然后实现小灯翻转
```c
rt_pin_mode(GPIO_LED_R, PIN_MODE_OUTPUT);
//topic_info->payload 为发送的内容,可以据此设置命令
if(rt_pin_read(GPIO_LED_R) == PIN_HIGH)
{
// rt_kprintf("LED_R should be ON\n");
rt_pin_write(GPIO_LED_R, PIN_LOW);
}
else
{
// rt_kprintf("LED_R should be OFF\n");
rt_pin_write(GPIO_LED_R, PIN_HIGH);
}
```
### 完整代码
``` c
#include "rtthread.h"
#include "dev_sign_api.h"
@ -285,6 +379,7 @@ INIT_BOARD_EXPORT(WIFI_CS GET_PIN);
#include <stdio.h>
#include <string.h>
#include "aht10.h"
#include <dfs_posix.h>
char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
@ -299,6 +394,13 @@ int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
uint64_t HAL_UptimeMs(void);
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
//定义接受文件内容的缓冲区
char buffer[1026] = {};
char tmp[1026];
#define GPIO_LED_B GET_PIN(F,11)
#define GPIO_LED_R GET_PIN(F,12)
// AHT挂载的总线名字
#define AHT10_I2C_BUS "i2c3"
@ -324,6 +426,18 @@ static void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_even
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
/* print topic name and topic message */
EXAMPLE_TRACE("Message Arrived:");
rt_pin_mode(GPIO_LED_R, PIN_MODE_OUTPUT);
//topic_info->payload 为发送的内容,可以据此设置命令
if(rt_pin_read(GPIO_LED_R) == PIN_HIGH)
{
// rt_kprintf("LED_R should be ON\n");
rt_pin_write(GPIO_LED_R, PIN_LOW);
}
else
{
// rt_kprintf("LED_R should be OFF\n");
rt_pin_write(GPIO_LED_R, PIN_HIGH);
}
EXAMPLE_TRACE("Topic : %.*s", topic_info->topic_len, topic_info->ptopic);
EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
EXAMPLE_TRACE("\n");
@ -360,14 +474,44 @@ static int example_subscribe(void *handle)
return 0;
}
char tmp[256];
void make_file()
{
//文件描述符
int fd;
//用只写方式打开文件,如果没有该文件,则创建一个文件
fd = open("/fal/test/Data.txt", O_WRONLY | O_CREAT | O_APPEND); //和原来相比只是把O_TRUNC参数更改为O_APPEND即更改为打开后如果再进行写入将从文件的末尾位置开始写。
// rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,String);
//如果打开成功
if (fd >= 0)
{
//写入文件
write(fd, tmp, sizeof(tmp));
// rt_kprintf("Write done.\n");
//关闭文件
close(fd);
}
else
{
rt_kprintf("File Open Fail.\n");
}
return;
}
int cnt = 0;
void tmp_payload(void)
{
// 读取温湿度值
Humi = aht10_read_humidity(Dev);
Temp = aht10_read_temperature(Dev);
memset(tmp, 0, sizeof(tmp));
sprintf(tmp, "Temp: %.1f;Humi: %.1f;Count: %d\n", Temp, Humi,++cnt);
// rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,tmp);
make_file();
sprintf(tmp, "{\"params\":{\"temperature\":%.2f,\"humidity\":%.2f}}", Temp, Humi);
rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,tmp);
return;
}
static int example_publish(void *handle)
@ -382,7 +526,7 @@ static int example_publish(void *handle)
int topic_len = 0;
char *payload = tmp;
// strcpy(payload,tmp_payload());
rt_kprintf("payload:%s\n",payload);
// rt_kprintf("payload:%s\n",payload);
topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
topic = HAL_Malloc(topic_len);
if (topic == NULL) {
@ -421,6 +565,7 @@ static void mqtt_example_main(void *parameter)
EXAMPLE_TRACE("mqtt example");
memset(&mqtt_params, 0x0, sizeof(mqtt_params));
mqtt_params.handle_event.h_fp = example_event_handle;

View File

@ -2,7 +2,9 @@ from building import *
import os
cwd = GetCurrentDir()
src = Glob('*.c')
src = [
'mqtt.c',
]
CPPPATH = [cwd]

View File

@ -5,7 +5,7 @@
#include <dfs_posix.h>//需要添加软件包进这里
//定义要写入的内容
char String[] = "Hello, RT-Thread.Welcom to RSOC!";
char String[] = "Hello, RT-Thread.Welcom to RSOC!\n temp: 123, humi: 789";
//定义接受文件内容的缓冲区
char buffer[100] = {};

BIN
Day5/image-7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -1,295 +1,3 @@
// #include "rtthread.h"
// #include "dev_sign_api.h"
// #include "mqtt_api.h"
// char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
// char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
// char DEMO_DEVICE_SECRET[IOTX_DEVICE_SECRET_LEN + 1] = {0};
// void *HAL_Malloc(uint32_t size);
// void HAL_Free(void *ptr);
// void HAL_Printf(const char *fmt, ...);
// int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1]);
// int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1]);
// int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
// uint64_t HAL_UptimeMs(void);
// int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
// #define EXAMPLE_TRACE(fmt, ...) \
// do \
// { \
// HAL_Printf("%s|%03d :: ", __func__, __LINE__); \
// HAL_Printf(fmt, ##__VA_ARGS__); \
// HAL_Printf("%s", "\r\n"); \
// } while (0)
// static void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
// {
// iotx_mqtt_topic_info_t *topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
// switch (msg->event_type)
// {
// case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
// /* print topic name and topic message */
// EXAMPLE_TRACE("Message Arrived:");
// EXAMPLE_TRACE("Topic : %.*s", topic_info->topic_len, topic_info->ptopic);
// EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
// EXAMPLE_TRACE("\n");
// break;
// default:
// break;
// }
// }
// static int example_subscribe(void *handle)
// {
// int res = 0;
// const char *fmt = "/%s/%s/user/get";
// char *topic = NULL;
// int topic_len = 0;
// topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
// topic = HAL_Malloc(topic_len);
// if (topic == NULL)
// {
// EXAMPLE_TRACE("memory not enough");
// return -1;
// }
// memset(topic, 0, topic_len);
// HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
// res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL);
// if (res < 0)
// {
// EXAMPLE_TRACE("subscribe failed");
// HAL_Free(topic);
// return -1;
// }
// HAL_Free(topic);
// return 0;
// }
// static int example_publish(void *handle)
// {
// int res = 0;
// const char *fmt = "/sys/%s/%s/thing/event/property/post";
// char *topic = NULL;
// int topic_len = 0;
// char *payload = "{\"message\":\"hello!\"}";
// topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
// topic = HAL_Malloc(topic_len);
// if (topic == NULL)
// {
// EXAMPLE_TRACE("memory not enough");
// return -1;
// }
// memset(topic, 0, topic_len);
// HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
// res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, strlen(payload));
// if (res < 0)
// {
// EXAMPLE_TRACE("publish failed, res = %d", res);
// HAL_Free(topic);
// return -1;
// }
// HAL_Free(topic);
// return 0;
// }
// static void example_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
// {
// EXAMPLE_TRACE("msg->event_type : %d", msg->event_type);
// }
// /*
// * NOTE: About demo topic of /${productKey}/${deviceName}/user/get
// *
// * The demo device has been configured in IoT console (https://iot.console.aliyun.com)
// * so that its /${productKey}/${deviceName}/user/get can both be subscribed and published
// *
// * We design this to completely demonstrate publish & subscribe process, in this way
// * MQTT client can receive original packet sent by itself
// *
// * For new devices created by yourself, pub/sub privilege also requires being granted
// * to its /${productKey}/${deviceName}/user/get for successfully running whole example
// */
// void mqtt_example_main(void *parameter)
// {
// void *pclient = NULL;
// int res = 0;
// int loop_cnt = 0;
// iotx_mqtt_param_t mqtt_params;
// HAL_GetProductKey(DEMO_PRODUCT_KEY);
// HAL_GetDeviceName(DEMO_DEVICE_NAME);
// HAL_GetDeviceSecret(DEMO_DEVICE_SECRET);
// EXAMPLE_TRACE("mqtt example");
// /* Initialize MQTT parameter */
// /*
// * Note:
// *
// * If you did NOT set value for members of mqtt_params, SDK will use their default values
// * If you wish to customize some parameter, just un-comment value assigning expressions below
// *
// **/
// memset(&mqtt_params, 0x0, sizeof(mqtt_params));
// /**
// *
// * MQTT connect hostname string
// *
// * MQTT server's hostname can be customized here
// *
// * default value is ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com
// */
// /* mqtt_params.host = "something.iot-as-mqtt.cn-shanghai.aliyuncs.com"; */
// /**
// *
// * MQTT connect port number
// *
// * TCP/TLS port which can be 443 or 1883 or 80 or etc, you can customize it here
// *
// * default value is 1883 in TCP case, and 443 in TLS case
// */
// /* mqtt_params.port = 1883; */
// /**
// *
// * MQTT request timeout interval
// *
// * MQTT message request timeout for waiting ACK in MQTT Protocol
// *
// * default value is 2000ms.
// */
// /* mqtt_params.request_timeout_ms = 2000; */
// /**
// *
// * MQTT clean session flag
// *
// * If CleanSession is set to 0, the Server MUST resume communications with the Client based on state from
// * the current Session (as identified by the Client identifier).
// *
// * If CleanSession is set to 1, the Client and Server MUST discard any previous Session and Start a new one.
// *
// * default value is 0.
// */
// /* mqtt_params.clean_session = 0; */
// /**
// *
// * MQTT keepAlive interval
// *
// * KeepAlive is the maximum time interval that is permitted to elapse between the point at which
// * the Client finishes transmitting one Control Packet and the point it starts sending the next.
// *
// * default value is 60000.
// */
// /* mqtt_params.keepalive_interval_ms = 60000; */
// /**
// *
// * MQTT write buffer size
// *
// * Write buffer is allocated to place upstream MQTT messages, MQTT client will be limitted
// * to send packet no longer than this to Cloud
// *
// * default value is 1024.
// *
// */
// /* mqtt_params.write_buf_size = 1024; */
// /**
// *
// * MQTT read buffer size
// *
// * Write buffer is allocated to place downstream MQTT messages, MQTT client will be limitted
// * to recv packet no longer than this from Cloud
// *
// * default value is 1024.
// *
// */
// /* mqtt_params.read_buf_size = 1024; */
// /**
// *
// * MQTT event callback function
// *
// * Event callback function will be called by SDK when it want to notify user what is happening inside itself
// *
// * default value is NULL, which means PUB/SUB event won't be exposed.
// *
// */
// mqtt_params.handle_event.h_fp = example_event_handle;
// pclient = IOT_MQTT_Construct(&mqtt_params);
// if (NULL == pclient)
// {
// EXAMPLE_TRACE("MQTT construct failed");
// return;
// }
// res = example_subscribe(pclient);
// if (res < 0)
// {
// IOT_MQTT_Destroy(&pclient);
// return;
// }
// while (1)
// {
// if (0 == loop_cnt % 20)
// {
// example_publish(pclient);
// }
// IOT_MQTT_Yield(pclient, 200);
// loop_cnt += 1;
// }
// }
// #define THREAD_PRIORITY 25
// #define THREAD_STACK_SIZE 4096
// #define THREAD_TIMESLICE 5
// rt_thread_t MQTT_Thread;
// void MQTT_Creat_Thread(void)
// {
// // 创建线程
// MQTT_Thread = rt_thread_create("MQTT_Thread", mqtt_example_main, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
// // 创建成功就启动
// if (MQTT_Thread != RT_NULL)
// {
// rt_thread_startup(MQTT_Thread);
// }
// else
// {
// rt_kprintf("MQTT_Thread_Thread Create Fail");
// }
// }
// // 导出Shell命令
// MSH_CMD_EXPORT(MQTT_Creat_Thread, This Function will creat a MQTT thread.);
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*
* Again edit by rt-thread group
* Change Logs:
* Date Author Notes
* 2019-07-21 MurphyZhao first edit
*/
#include "rtthread.h"
#include "dev_sign_api.h"
#include "mqtt_api.h"
@ -298,6 +6,7 @@
#include <stdio.h>
#include <string.h>
#include "aht10.h"
#include <dfs_posix.h>
char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
@ -312,6 +21,13 @@ int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
uint64_t HAL_UptimeMs(void);
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
//定义接受文件内容的缓冲区
char buffer[1026] = {};
char tmp[1026];
#define GPIO_LED_B GET_PIN(F,11)
#define GPIO_LED_R GET_PIN(F,12)
// AHT挂载的总线名字
#define AHT10_I2C_BUS "i2c3"
@ -337,6 +53,18 @@ static void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_even
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
/* print topic name and topic message */
EXAMPLE_TRACE("Message Arrived:");
rt_pin_mode(GPIO_LED_R, PIN_MODE_OUTPUT);
//topic_info->payload 为发送的内容,可以据此设置命令
if(rt_pin_read(GPIO_LED_R) == PIN_HIGH)
{
// rt_kprintf("LED_R should be ON\n");
rt_pin_write(GPIO_LED_R, PIN_LOW);
}
else
{
// rt_kprintf("LED_R should be OFF\n");
rt_pin_write(GPIO_LED_R, PIN_HIGH);
}
EXAMPLE_TRACE("Topic : %.*s", topic_info->topic_len, topic_info->ptopic);
EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
EXAMPLE_TRACE("\n");
@ -373,14 +101,44 @@ static int example_subscribe(void *handle)
return 0;
}
char tmp[256];
void make_file()
{
//文件描述符
int fd;
//用只写方式打开文件,如果没有该文件,则创建一个文件
fd = open("/fal/test/Data.txt", O_WRONLY | O_CREAT | O_APPEND); //和原来相比只是把O_TRUNC参数更改为O_APPEND即更改为打开后如果再进行写入将从文件的末尾位置开始写。
// rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,String);
//如果打开成功
if (fd >= 0)
{
//写入文件
write(fd, tmp, sizeof(tmp));
// rt_kprintf("Write done.\n");
//关闭文件
close(fd);
}
else
{
rt_kprintf("File Open Fail.\n");
}
return;
}
int cnt = 0;
void tmp_payload(void)
{
// 读取温湿度值
Humi = aht10_read_humidity(Dev);
Temp = aht10_read_temperature(Dev);
memset(tmp, 0, sizeof(tmp));
sprintf(tmp, "Temp: %.1f;Humi: %.1f;Count: %d\n", Temp, Humi,++cnt);
// rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,tmp);
make_file();
sprintf(tmp, "{\"params\":{\"temperature\":%.2f,\"humidity\":%.2f}}", Temp, Humi);
rt_kprintf("\n%f %f tmp:%s\n",Humi,Temp,tmp);
return;
}
static int example_publish(void *handle)
@ -395,7 +153,7 @@ static int example_publish(void *handle)
int topic_len = 0;
char *payload = tmp;
// strcpy(payload,tmp_payload());
rt_kprintf("payload:%s\n",payload);
// rt_kprintf("payload:%s\n",payload);
topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
topic = HAL_Malloc(topic_len);
if (topic == NULL) {
@ -421,19 +179,6 @@ static void example_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_
EXAMPLE_TRACE("msg->event_type : %d", msg->event_type);
}
/*
* NOTE: About demo topic of /${productKey}/${deviceName}/user/get
*
* The demo device has been configured in IoT console (https://iot.console.aliyun.com)
* so that its /${productKey}/${deviceName}/user/get can both be subscribed and published
*
* We design this to completely demonstrate publish & subscribe process, in this way
* MQTT client can receive original packet sent by itself
*
* For new devices created by yourself, pub/sub privilege also requires being granted
* to its /${productKey}/${deviceName}/user/get for successfully running whole example
*/
static void mqtt_example_main(void *parameter)
{
void *pclient = NULL;
@ -447,103 +192,9 @@ static void mqtt_example_main(void *parameter)
EXAMPLE_TRACE("mqtt example");
/* Initialize MQTT parameter */
/*
* Note:
*
* If you did NOT set value for members of mqtt_params, SDK will use their default values
* If you wish to customize some parameter, just un-comment value assigning expressions below
*
**/
memset(&mqtt_params, 0x0, sizeof(mqtt_params));
/**
*
* MQTT connect hostname string
*
* MQTT server's hostname can be customized here
*
* default value is ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com
*/
/* mqtt_params.host = "something.iot-as-mqtt.cn-shanghai.aliyuncs.com"; */
/**
*
* MQTT connect port number
*
* TCP/TLS port which can be 443 or 1883 or 80 or etc, you can customize it here
*
* default value is 1883 in TCP case, and 443 in TLS case
*/
/* mqtt_params.port = 1883; */
/**
*
* MQTT request timeout interval
*
* MQTT message request timeout for waiting ACK in MQTT Protocol
*
* default value is 2000ms.
*/
/* mqtt_params.request_timeout_ms = 2000; */
/**
*
* MQTT clean session flag
*
* If CleanSession is set to 0, the Server MUST resume communications with the Client based on state from
* the current Session (as identified by the Client identifier).
*
* If CleanSession is set to 1, the Client and Server MUST discard any previous Session and Start a new one.
*
* default value is 0.
*/
/* mqtt_params.clean_session = 0; */
/**
*
* MQTT keepAlive interval
*
* KeepAlive is the maximum time interval that is permitted to elapse between the point at which
* the Client finishes transmitting one Control Packet and the point it starts sending the next.
*
* default value is 60000.
*/
/* mqtt_params.keepalive_interval_ms = 60000; */
/**
*
* MQTT write buffer size
*
* Write buffer is allocated to place upstream MQTT messages, MQTT client will be limitted
* to send packet no longer than this to Cloud
*
* default value is 1024.
*
*/
/* mqtt_params.write_buf_size = 1024; */
/**
*
* MQTT read buffer size
*
* Write buffer is allocated to place downstream MQTT messages, MQTT client will be limitted
* to recv packet no longer than this from Cloud
*
* default value is 1024.
*
*/
/* mqtt_params.read_buf_size = 1024; */
/**
*
* MQTT event callback function
*
* Event callback function will be called by SDK when it want to notify user what is happening inside itself
*
* default value is NULL, which means PUB/SUB event won't be exposed.
*
*/
mqtt_params.handle_event.h_fp = example_event_handle;
pclient = IOT_MQTT_Construct(&mqtt_params);

166
Day5/note.md Normal file
View File

@ -0,0 +1,166 @@
``` c
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 balanceTWK add sdcard port file
* 2021-05-10 Meco Man fix a bug that cannot use fatfs in the main thread at starting up
* 2021-07-28 Meco Man implement romfs as the root filesystem
*/
#include <rtthread.h>
#include <dfs_romfs.h>
#include <dfs_fs.h>
#include <dfs_file.h>
#if DFS_FILESYSTEMS_MAX < 4
#error "Please define DFS_FILESYSTEMS_MAX more than 4"
#endif
#if DFS_FILESYSTEM_TYPES_MAX < 4
#error "Please define DFS_FILESYSTEM_TYPES_MAX more than 4"
#endif
#define DBG_TAG "app.filesystem"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef BSP_USING_FS_AUTO_MOUNT
#ifdef BSP_USING_SDCARD_FATFS
static int onboard_sdcard_mount(void)
{
if (dfs_mount("sd", "/sdcard", "elm", 0, 0) == RT_EOK)
{
LOG_I("SD card mount to '/sdcard'");
}
else
{
LOG_E("SD card mount to '/sdcard' failed!");
}
return RT_EOK;
}
#endif /* BSP_USING_SDCARD_FATFS */
#endif /* BSP_USING_FS_AUTO_MOUNT */
#ifdef BSP_USING_FLASH_FS_AUTO_MOUNT
#ifdef BSP_USING_FLASH_FATFS
#define FS_PARTITION_NAME "filesystem"
static int onboard_fal_mount(void)
{
/* 初始化 fal 功能 */
extern int fal_init(void);
extern struct rt_device *fal_blk_device_create(const char *parition_name);
fal_init();
/* 在 spi flash 中名为 "filesystem" 的分区上创建一个块设备 */
struct rt_device *flash_dev = fal_blk_device_create(FS_PARTITION_NAME);
fal_blk_device_create("font");
if (flash_dev == NULL)
{
LOG_E("Can't create a block device on '%s' partition.", FS_PARTITION_NAME);
}
else
{
LOG_D("Create a block device on the %s partition of flash successful.", FS_PARTITION_NAME);
}
/* 挂载 spi flash 中名为 "filesystem" 的分区上的文件系统 */
if (dfs_mount(flash_dev->parent.name, "/fal", "elm", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
}
else
{
dfs_mkfs("elm", flash_dev->parent.name);
if (dfs_mount(flash_dev->parent.name, "/fal", "elm", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
}
else
{
LOG_E("Failed to initialize filesystem!");
LOG_D("You should create a filesystem on the block device first!");
}
}
int ret;
/* 创建目录 */
ret = mkdir("/fal/test", 0x777);
if (ret < 0)
{
/* 创建目录失败 */
rt_kprintf("dir error!\n");
}
else
{
/* 创建目录成功 */
rt_kprintf("mkdir ok!\n");
}
/* 挂载块设备"font"到 DFS 目录/fal/test中 */
if (dfs_mount("font", "/fal/test", "elm", 0, 0) == 0)
{
LOG_I("font initialized!");
}
else
{
dfs_mkfs("elm", "font");
if (dfs_mount("font", "/fal/test", "elm", 0, 0) == 0)
{
LOG_I("font initialized!");
}
else
{
LOG_E("Failed to initialize font!");
LOG_D("You should create a filesystem(font) on the block device first!");
}
}
return RT_EOK;
}
#endif /*BSP_USING_FLASH_FATFS*/
#endif /*BSP_USING_FLASH_FS_AUTO_MOUNT*/
const struct romfs_dirent _romfs_root[] =
{
#ifdef BSP_USING_SDCARD_FATFS
{ROMFS_DIRENT_DIR, "sdcard", RT_NULL, 0},
#endif
#ifdef BSP_USING_FLASH_FATFS
{ROMFS_DIRENT_DIR, "fal", RT_NULL, 0},
#endif
};
const struct romfs_dirent romfs_root =
{
ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root) / sizeof(_romfs_root[0])
};
static int filesystem_mount(void)
{
#ifdef BSP_USING_FS
if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) != 0)
{
LOG_E("rom mount to '/' failed!");
}
/* 确保块设备注册成功之后再挂载文件系统 */
rt_thread_delay(500);
#endif
#ifdef BSP_USING_FS_AUTO_MOUNT
onboard_sdcard_mount();
#endif /* BSP_USING_FS_AUTO_MOUNT */
#ifdef BSP_USING_FLASH_FS_AUTO_MOUNT
onboard_fal_mount();
#endif
return RT_EOK;
}
INIT_APP_EXPORT(filesystem_mount);
```

58
applications/init.c Normal file
View File

@ -0,0 +1,58 @@
#include <rtthread.h>
#include <rthw.h>
#include <wlan_mgnt.h>
#include <wlan_cfg.h>
#include <wlan_prot.h>
static int board_init(void)
{
return 0;
}
INIT_BOARD_EXPORT(board_init);
static int prev_init(void)
{
return 0;
}
INIT_PREV_EXPORT(prev_init);
static int device_init(void)
{
return 0;
}
INIT_DEVICE_EXPORT(device_init);
static int component_init(void)
{
return 0;
}
INIT_COMPONENT_EXPORT(component_init);
static int env_init(void)
{
return 0;
}
INIT_ENV_EXPORT(env_init);
static int app_init(void)
{
return 0;
}
INIT_APP_EXPORT(app_init);
// extern int wifi_join(int argc, char *argv[]);
int main_init(void)
{
// rt_thread_mdelay(18000);
// char *argv[] = {"wifi", "join", "Dong", "abcd07691234"};
// wifi_join(4, argv);
// char *ssid = "Dong";
// char *key = "abcd07691234";
// rt_wlan_connect(ssid, key);
return 0;
}

4
applications/init.h Normal file
View File

@ -0,0 +1,4 @@
#ifndef __INIT_H__
#define __INIT_H__
int main_init(void);
#endif // !__INIT_H__

View File

@ -50,17 +50,27 @@
// return 0;
// }
#include <rtthread.h>
#include <dfs_fs.h>
#include <board.h>
#include "init.h"
#include <drv_gpio.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#ifndef RT_USING_NANO
#include <rtdevice.h>
#endif // !RT_USING_NANO
static int onboard_sdcard_mount();
#define GPIO_LED_B GET_PIN(F,11)
#define GPIO_LED_R GET_PIN(F,12)
int main(void)
{
onboard_sdcard_mount();
main_init();
// rt_pin_mode(GPIO_LED_B, PIN_MODE_OUTPUT);
// while(1)
// {
// rt_pin_write(GPIO_LED_B, PIN_HIGH);
// rt_thread_mdelay(500);
// rt_pin_write(GPIO_LED_B, PIN_LOW);
// rt_thread_mdelay(500);
// }
return 0;
}
@ -78,10 +88,10 @@ static int onboard_sdcard_mount(void)
return RT_EOK;
}
// #define WIFI_CS GET_PIN(F, 10)
// void WIFI_CS_PULL_DOWM(void)
// {
// rt_pin_mode(WIFI_CS, PIN_MODE_OUTPUT);
// rt_pin_write(WIFI_CS, PIN_LOW);
// }
// INIT_BOARD_EXPORT(WIFI_CS_PULL_DOWM);
#define WIFI_CS GET_PIN(F, 10)
void WIFI_CS_PULL_DOWM(void)
{
rt_pin_mode(WIFI_CS, PIN_MODE_OUTPUT);
rt_pin_write(WIFI_CS, PIN_LOW);
}
INIT_BOARD_EXPORT(WIFI_CS_PULL_DOWM);

View File

@ -55,7 +55,8 @@ static int onboard_fal_mount(void)
extern struct rt_device *fal_blk_device_create(const char *parition_name);
fal_init();
/* 在 spi flash 中名为 "filesystem" 的分区上创建一个块设备 */
struct rt_device *flash_dev = fal_blk_device_create("font");
struct rt_device *flash_dev = fal_blk_device_create(FS_PARTITION_NAME);
fal_blk_device_create("font");
if (flash_dev == NULL)
{
LOG_E("Can't create a block device on '%s' partition.", FS_PARTITION_NAME);
@ -72,10 +73,50 @@ static int onboard_fal_mount(void)
}
else
{
LOG_E("Failed to initialize filesystem!");
LOG_D("You should create a filesystem on the block device first!");
dfs_mkfs("elm", flash_dev->parent.name);
if (dfs_mount(flash_dev->parent.name, "/fal", "elm", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
}
else
{
LOG_E("Failed to initialize filesystem!");
LOG_D("You should create a filesystem on the block device first!");
}
}
int ret;
/* 创建目录 */
ret = mkdir("/fal/test", 0x777);
if (ret < 0)
{
/* 创建目录失败 */
rt_kprintf("dir error!\n");
}
else
{
/* 创建目录成功 */
rt_kprintf("mkdir ok!\n");
}
/* 挂载块设备"font"到 DFS 目录/fal/test中 */
if (dfs_mount("font", "/fal/test", "elm", 0, 0) == 0)
{
LOG_I("font initialized!");
}
else
{
dfs_mkfs("elm", "font");
if (dfs_mount("font", "/fal/test", "elm", 0, 0) == 0)
{
LOG_I("font initialized!");
}
else
{
LOG_E("Failed to initialize font!");
LOG_D("You should create a filesystem(font) on the block device first!");
}
}
return RT_EOK;
}
#endif /*BSP_USING_FLASH_FATFS*/

6
dayandnight/README.md Normal file
View File

@ -0,0 +1,6 @@
### 使能了sd card
![alt text](image-2.png)
结果
![alt text](image.png)
关了就好了
![alt text](image-1.png)

BIN
dayandnight/image-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
dayandnight/image-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
dayandnight/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -468,6 +468,8 @@
#define PKG_USING_AHT10
#define PKG_USING_AHT10_LATEST_VERSION
#define PKG_USING_ICM20608
#define PKG_USING_ICM20608_LATEST_VERSION
/* end of sensors drivers */
/* touch drivers */
@ -574,6 +576,7 @@
#define BSP_USING_FAL
#define BSP_USING_RW007_WLAN
#define BSP_USING_AHT21
#define BSP_USING_ICM20608
/* end of Onboard Peripheral Drivers */
/* On-chip Peripheral Drivers */
@ -588,6 +591,9 @@
#define BSP_USING_SPI
#define BSP_USING_SPI2
#define BSP_USING_I2C
#define BSP_USING_I2C2
#define BSP_I2C2_SCL_PIN 81
#define BSP_I2C2_SDA_PIN 80
#define BSP_USING_I2C3
#define BSP_I2C3_SCL_PIN 64
#define BSP_I2C3_SDA_PIN 65