【随手笔记】2024某项目的碎片

1. 开发环境

  1. 开发某项目,硬件资源是20K RAM+ 128K ROM
    应用场景是将传感器数据和云平台和手机交互
    软件系统可选项有
  • RT_thread
  • freeRTOS
  • cola os
    选用的软件操作系统是RT_thread

使用RT_thread可选用的开发环境有

  • RT thread studio
  • ENV+KEIL
  • ENV+VC code
  1. 第一种方案
    RT thread studio + STM32cubeMX +HAL库
    此种方案,软件环境搭建高效,稳定,
    可在RT thread settings直观裁剪操作系统初始配置
    直接进入用户代码的编写

  2. 第二种方案
    ENV+KEIL+STM32cubeMX
    此种方案,在于ENV工具使用的熟练度
    虽然ENV对于芯片扩展具有优势,配置的灵活性更大
    但是考虑到项目后期的试错成本平衡
    但是有时间还是要使用

  3. 回头看:从后面某个时间节点来看: 简单有效的工具就是合适

  4. 选用工具就是编译,调试一下,至于代码编写阅读工具,因人而异,没有最好

  5. source insight + vs code + 等等

2. 软件基础环境了解

  1. 进入链接,安装完成
    https://www.rt-thread.org/document/site/#/development-tools/rtthread-studio/um/studio-user-begin
    在这里插入图片描述
  2. 按照教程新建项目(可忽略)
  3. 创建好项目的路径(可忽略)
    在这里插入图片描述
    (workspace 为项目的工作空间路径)
  4. 导入现有的项目
    在这里插入图片描述
  5. 编译完成表示环境搭建完成
    在这里插入图片描述
  6. 进入RT_thread 进行系统初始配置,裁剪功能,合理分配资源
    在这里插入图片描述
  7. 进入cubemx setting进行MCU基础硬件初始化
    在这里插入图片描述
  • 详见文章下章
    每次使用CubeMX修改基础的硬件配置后请小心的检查此文件
    在这里插入图片描述
  1. 下面就进行用户代码的添加了

3. 项目文件夹

  1. 项目分类如下在这里插入图片描述
  • app 文件夹下为用户的应用层代码。涉及到软件每一个功能的逻辑
  • applications文件夹下为用户集中控制的逻辑
  • bsp文件夹为各外设模组的底层驱动,可以理解为模组的初始化,数据读写
  • cubemx为软件cubeMX自动生成的代码,此文件无需添加用户代码
  • Debug为编译调试生成文件,只需关注后期生产烧录的HEX文件,升级需要的BIN文件
  • drivers为操作系统自带的板级库函数,大多数已屏蔽,未使用
  • libraries为HAL库函数
  • lwrb为数据环形缓冲
  • RTT为SEGGER RTT文件,软件版本788
  • rt-thread为操作系统源文件. 版本403

4. 硬件初始化配置

  1. 详细的使用
    RT-Thread Studio与CubeMX联合编程
    推荐链接
    https://blog.csdn.net/qq_40824852/article/details/123067421
    链接1
  2. CubeMX 使用
    推荐链接
    https://www.waveshare.net/study/portal.php?mod=list&catid=40
    链接2

在这里插入图片描述
3. 配置概览
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 备注项
    在这里插入图片描述
  • 备注项

在HAL库中有一个stm32f1xx_hal_msp.c的文件,这个文件的作用就是根据用户所提供的具体的MCU型号以及硬件配置,对HAL库进行初始化设置操作。所以这个文件是就HAL库与MCU结合的纽带

虽然 STM32CubeMX 生成了多个文件用来初始化外设,但 RT-Thread 只使用了 STM32CubeMX 生成的 stm32fxx_hal_msp.c 文件和 stm32fxx_hal_conf.h 文件。

5. 基础配置完成

目前已经使用cubeMX和rt thread setting完成基础配置
开始进入软件的开发阶段

6. 主函数初始化

  1. 外设模组初始化在main.c文件中,
  2. 第一步初始化所有外设
  3. 进入主控线程
  4. 设备使用模型
    在这里插入图片描述
    在这里插入图片描述
  • 简述:第一步注册设备,添加设备对应接口
  • 第二步应用层调用接口,先查找设备,然后初始化打开,后面可以正常使用设备接口读写控制等
  • 备注:注册打开设备一定要有返回值,否则使用异常(。。。)
rt_err_t gps_init(rt_device_t dev)
{
	LOG_OUT("gps_init\r\n");

	return RT_EOK;
}
  1. 在设备扫描函数完成设备的查找,初始状态配置

7.软件框架设计

  • 项目软件的设计思想是

主函数main为主控函数
控制着其他线程的状态和整机设备的运行模式,
休眠模式或工作模式

NB的线程为两个
一个为与NB模组交互的AT指令控制线程
使用的是基于状态机编写的交互逻辑,用户自定义灵活度最高,占用资源小
有一款开源组件AT COMMAND
https://gitee.com/moluo-tech/AT-Command
在这里插入图片描述
此组件的问题是占用资源大,基础配置5K左右,编写逻辑不灵活、
选用的是基于状态机和二维数组编写的【表驱动】【查表】
推荐链接
https://blog.csdn.net/weixin_42192405/article/details/115765164
对逻辑编写,扩展很友好,不占用资源

一个为NB与云端交互的控制线程
控制着的事件有

typedef enum
{
	I_EVT_IDLE       		= 1 << 0,//空闲
	I_EVT_POWERON 	 		= 1 << 1,//电源上电事件

	I_EVT_RET_SUCC   		= 1 << 2,//返回成功事件
	I_EVT_RET_FAIL   		= 1 << 3,//返回失败事件

	I_EVT_UPDATA_SUCC       = 1 << 4,//上传成功事件
	I_EVT_UPDATA_FAIL       = 1 << 5,//上传失败事件

	I_EVT_RTC_UPDATA        = 1 << 6,//RTC触发事件
	
	I_EVT_SENSOR_REC        = 1 << 7,//传感器反馈结果事件
	I_EVT_SENSOR_SEND       = 1 << 8,//传感器控制参数事件
 
}IOT_EVT_EVENT_T;

每种事件对应执行一种任务,

蓝牙与NB类似
也是两个线程
一个是与模组交互AT控制的线程
一个是控制与APP交互的事件的线程

//EVT任务事件
typedef enum
{
	B_EVT_IDLE       		= 1 << 0,//空闲
	B_EVT_POWERON 	 		= 1 << 1,//电源上电事件

	B_EVT_RET_SUCC   		= 1 << 2,//返回成功事件
	B_EVT_RET_FAIL   		= 1 << 3,//返回失败事件

	B_EVT_UPDATA_SUCC       = 1 << 4,//上传成功事件
	B_EVT_UPDATA_FAIL       = 1 << 5,//上传失败事件

	B_EVT_RTC_UPDATA        = 1 << 6,//RTC触发事件(可忽略)

}BLE_EVT_EVENT_T;

传感器采集为一个线程
线程目前设计的是等待采集的事件触发,然后顺序采集数据,
采集完成数据后反馈给控制线程
然后挂起等待下一次采集事件

/*
 * 步骤
 */
typedef enum
{
    idle_step = 0,//空闲
    methane_step,//甲烷
    triaxial_step,//三轴
    temperature_step,//温度
    distance_step,//距离
    gps_step,//gps
    water_step,//水浸
    rtc_step,//rtc
    battery_step,//电量
    finish_step,//结束
}SENSOR_SCAN_STEP_T;
/*
 * 传感器数据
 */
typedef struct
{
    uint16_t methane;   //甲烷
    uint16_t temperature;//温度
    uint16_t air;//气压
    uint8_t  err;//错误状态
    uint8_t  direction_x;//x轴偏角
    uint8_t  direction_y;//y轴偏角
    uint8_t  direction_z;//z轴偏角
    uint16_t  temper;//温度
    uint16_t  humidity;//湿度
    uint16_t distance;//距离
    uint32_t latitude;//纬度
    uint32_t longitude;//经度
    uint8_t  water;//水浸
    uint32_t timestamp;//时间戳
    uint16_t battery;//电量
}sensor_data_t;

上面为传感器的类别与对应的数据

 case methane_step:
 {
     if(app_gas_data_read(&sensor_data.methane, &sensor_data.temperature, &sensor_data.air, &sensor_data.err) == true)
     {
         LOG_OUT("methane_step ok\r\n");

         LOG_OUT("methane=%d ", sensor_data.methane);
         LOG_OUT("temperature=%d ", sensor_data.temperature);
         LOG_OUT("air=%d ", sensor_data.air);
         LOG_OUT("err=%d\r\n", sensor_data.err);
     }
     else
     {
         LOG_OUT("methane_step err\r\n");
     }
     sensor_ctl.step++;
 }
 break;
bool app_gas_data_read(uint16_t *ch4, uint16_t *temper, uint16_t *air, uint8_t *err)
{
    uint8_t temp_buff[8] = {0};
    if(rt_device_read(app_gas_dev, RT_NULL, temp_buff, RT_NULL) > 0)
    {
//        for(uint8_t t=0; t<6; t++)
//        {
//        LOG_OUT("[%x]",temp_buff[t]);
//        }

        *ch4 = temp_buff[0]<<8 | temp_buff[1];
        *temper = temp_buff[2]<<8 | temp_buff[3];
        *air = temp_buff[4]<<8 | temp_buff[5];
        *err = temp_buff[7];

        return true;
    }
    return false;
}

8. 软件框架简述

  1. RTC驱动着设备的唤醒工作
  2. 设备工作先 采集数据 然后 上传 云端
  3. 共 6个 线程
  4. NB 2个, 一个和模组AT交互,一个控制着业务数据流
  5. BLE 2个, 一个和模组AT交互, 一个控制着业务数据流
  6. 传感器 1个, 被动开启工作,工作完挂起等待
  7. 主控 1个, 控制着设备的休眠和其他线程
  8. 蓝牙是随时可能连接插入
  9. 核心点是 数据本地保存+数据上云
  10. 难点是 0%数据丢失
  11. 复盘点是 如果要做一款极致性价比的产品 ,差距有多少, 当然考虑因素有很多

9. 备注点

  1. 上电初始化 - 蓝牙休眠 - 设备工作一轮 (传感器+NB)表明设备已上线
  2. 蓝牙是微信小程序随时可以连接, IO中断唤醒, 接收指令后, 开始采集
  3. NB与云端通讯是 先发送数据 再等待接收
  4. 硬件资源 RAM 20K 大概已使用 18K
  5. 固件大小 已 108K 左右
  6. BOOTloader 设计 16K 大小
  7. 总计 128K FLASH 没有剩余多少
  8. 芯片自带的6K EEPROM 使用了 2K 空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值