MCU SDK 移植

更新时间:2023-04-13 07:30:58下载pdf

MCU SDK 是根据涂鸦开发平台定义的产品功能自动生成的 MCU 代码,能够协助您快速完成 MCU 程序的开发。本文为您介绍低功耗蓝牙单点通用方案移植 MCU SDK 的流程以及注意事项。

开发步骤

  1. protocol.h 配置产品。例如,蓝牙状态指示灯的处理方式,是否支持 MCU 升级功能等。
  2. 移植 MCU_SDK。具体步骤查看 protocol.c 文件内的说明。
  3. 添加数据下发处理、数据上报函数调用。

文件结构

文件
说明
mcu_api.c 包含可供调用的函数。
mcu_api.h mcu_api.c中的函数声明。
protocol.c 包含协议数据体的内容处理函数。您可以根据项目需求,在相应函数内添加代码,获取低功耗蓝牙模组向 MCU 发送的数据。
protocol.h protocol.h 包含以下信息:
  • MCU 要发送至低功耗蓝牙模组初始化所需的参数。
  • SDK 裁剪所定义的宏。您可根据需要的功能打开相应的宏定义。
  • protocol.c中的函数声明。
system.c 串口通讯协议解析的具体实现。
system.h system.h 包含以下信息:
  • 协议命令字的定义。
  • 部分全局变量的定义。
  • system.c中的函数声明。
bluetooth.h 包含蓝牙相关宏定义。

mcu_ota_handler.hmcu_ota_handler.c 需要您自行配置。OTA 和芯片强相关,需要您自行调试修改适用自己的芯片平台。

第一步:初始化

  1. 在需要使用到蓝牙相关功能的文件中添加代码 include "bluetooth.h"

  2. 在 MCU 初始化中调用 mcu_api.c 文件中的 bt_protocol_init() 函数。

  3. 将 MCU 串口单字节发送函数填入 protocol.c 文件中 uart_transmit_output 函数内,并删除 #error

    void uart_transmit_output(unsigned char value)
    {
        uart_send(&value,1);
    }
    
  4. 在 MCU 串口接收函数中调用 mcu_api.c 文件内的 uart_receive_input 函数,并将接收到的字节作为参数传入。

    void uart_isr(void)
    {
        uint32_t IntStat;
    
        IntStat = uart_isr_stat_get();
    
        if(uart_rx_fifo_need_rd_isr_getf() || uart_rx_end_isr_getf()|| uart_rxd_wakeup_isr_getf())
        {
            while((REG_APB3_UART_FIFO_STAT & (0x01 << 21)))
            {
                uint8_t ch = UART_READ_BYTE();
                uart_receive_input(ch);
                    ……
            }
            ……
        }
        ……
    }
    
  5. 单片机进入 while 循环后调用 mcu_api.c 文件内的 bt_uart_service() 函数。

    void main_loop(void)
    {
        while(1)
        {
        bt_uart_service();
        ……
        }
    }
    

第二步:实现具体用户函数

下发数据处理

    static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length)
    {
      //示例:当前 DP 类型为 BOOL
      unsigned char ret;
      //0:关/1:开
      unsigned char switch_1;

      switch_1 = mcu_get_dp_download_bool(value,length);
      if(switch_1 == 0)
      {
        //开关关
      }
      else
      {
        //开关开
      }

      //处理完 DP 数据后的反馈
      ret = mcu_dp_bool_update(DPID_SWITCH_1,switch_1);
      if(ret == SUCCESS)
        return SUCCESS;
      else
        return ERROR;
    }
    ……

上报数据处理

    uint8_t key_onOff_status;
    uint8_t raw_test[4];
    uint32_t value_test;
    uint8_t string_test[16];
    uint8_t enum_test;
    void all_data_update(void)
    {
      //此代码为平台自动生成,请按照实际数据修改每个可下发可上报函数和只上报函数
      mcu_dp_bool_update(DPID_SWITCH_1,key_onOff_status); //BOOL 型数据上报
      mcu_dp_raw_update(DPID_RAW_TEST,raw_test,sizeof(raw_test)); //RAW 型数据上报
      mcu_dp_value_update(DPID_INT_TEST,value_test); //VALUE 型数据上报
      mcu_dp_string_update(DPID_STRING_TEST,string_test,sizeof(string_test)); //STRING 型数据上报
      mcu_dp_enum_update(DPID_ENUM_TEST,enum_test); //枚举型数据上报
    }

第三步:完成数据帧的选择

    //=============================================================================
    //数据帧类型
    //=============================================================================
    #define         HEAT_BEAT_CMD                   0                               //心跳包
    #define         PRODUCT_INFO_CMD                1                               //产品信息
    #define         WORK_MODE_CMD                   2                               //查询 MCU 设定的模组工作模式
    #define         BT_STATE_CMD                    3                               //蓝牙工作状态
    #define         BT_RESET_CMD                    4                               //重置蓝牙
    #define         DATA_QUERT_CMD                  6                               //命令下发
    #define         STATE_UPLOAD_CMD                7                               //状态上报
    #define         STATE_QUERY_CMD                 8                               //状态查询
    //////////////////////////////////当前 MCU SDK 版本较上一版本新增支持协议接口////////////////////
    //如果不需要某一条命令接口,可以直接注释命令宏的定义,以减小代码空间,相关代码将不会被编译
    #define TUYA_BCI_UART_COMMON_UNBOUND_REQ                    0x09                //模组解绑
    #define TUYA_BCI_UART_COMMON_RF_TEST                        0x0E                //RF 射频测试
    #define TUYA_BCI_UART_COMMON_SEND_STORAGE_TYPE              0xE0                //记录型数据上报(离线缓存)
    #define TUYA_BCI_UART_COMMON_SEND_TIME_SYNC_TYPE            0xE1                //获取实时时间
    #define TUYA_BCI_UART_COMMON_MODIFY_ADV_INTERVAL            0xE2                //修改休眠模式广播间隔
    #define TUYA_BCI_UART_COMMON_TURNOFF_SYSTEM_TIME            0xE4                //关闭系统时钟功能
    #define TUYA_BCI_UART_COMMON_ENANBLE_LOWER_POWER            0xE5                //低功耗使能
    #define TUYA_BCI_UART_COMMON_SEND_ONE_TIME_PASSWORD_TOKEN     0xE6                //获取一次性动态密码匹配结果
    #define TUYA_BCI_UART_COMMON_ACTIVE_DISCONNECT                0xE7                //断开蓝牙连接
    #define TUYA_BCI_UART_COMMON_QUERY_MCU_VERSION                0xE8                //查询 MCU 版本号
    #define TUYA_BCI_UART_COMMON_MCU_SEND_VERSION                0xE9                //MCU 主动发送版本号

    #define TUYA_BCI_UART_COMMON_MCU_OTA_REQUEST                0xEA                //OTA 升级请求
    #define TUYA_BCI_UART_COMMON_MCU_OTA_FILE_INFO                0xEB                //OTA 升级文件信息
    #define TUYA_BCI_UART_COMMON_MCU_OTA_FILE_OFFSET            0xEC                //OTA 升级文件偏移请求
    #define TUYA_BCI_UART_COMMON_MCU_OTA_DATA                     0xED                //OTA 升级数据
    #define TUYA_BCI_UART_COMMON_MCU_OTA_END                    0xEE                //OTA 升级结束

第四步:配置固件版本信息

    //protocol.h
    #define MCU_VER "1.0.0"                                 // 您的软件版本,用于 MCU 固件升级。MCU 升级版本需修改
    #define MCU_APP_VER_NUM      0x010000                    // 您的软件版本,用于 MCU 固件升级。MCU 升级版本需修改                    1.0.0
    #define MCU_HARD_VER_NUM     0x010000                    // 您的硬件版本,当前没有实际用处

第五步:完善接口

protocol.c 文件中添加功能接口,示例如下。

    void bt_rf_test_result(unsigned char result,signed char rssi)
    {
      #error "请自行完善该功能,完成后请删除该行"
      if(result == 0)
      {
        //测试失败
      }
      else
      {
        //测试成功
        //RSSI 为信号强度,大于-70dbm 为正常
      }

    }

第六步:完善 MCU OTA 功能

请根据您的具体业务需求修改 mcu_ota_handler.hmcu_ota_handler.c 文件。OTA 和芯片强相关,需要您自行调试修改适用自己的芯片平台。参考示例入下。

    /*****************************************************************************
    函数名称 : mcu_flash_init
    功能描述 :闪存初始化函数
    输入参数 :

    返回参数 : 无
    使用说明 : 您需要将闪存初始化函数在此完善,如果在其他处有闪存初始化操作,该函数可以不被调用
     *****************************************************************************/
    uint8_t mcu_flash_init(void)
    {
        #error "请自行完善该功能,完成后请删除该行"
    }
    /*****************************************************************************
    函数名称 : mcu_flash_erase
    功能描述 :闪存擦除函数
    输入参数 :addr 地址 size 大小

    返回参数 : 无
    使用说明 : 您需要自行完善
     *****************************************************************************/
    uint8_t mcu_flash_erase(uint32_t addr,uint32_t size)
    {
        #error "请自行完善该功能,完成后请删除该行"
    }
    /*****************************************************************************
    函数名称 : mcu_flash_write
    功能描述 :闪存写函数
    输入参数 :addr 地址 size 大小 p_data 待写入数据地址

    返回参数 : 无
    使用说明 : 您需要自行完善
     *****************************************************************************/

    uint8_t mcu_flash_write(uint32_t addr, const uint8_t *p_data, uint32_t size)
    {
        #error "请自行完善该功能,完成后请删除该行"
    }

    /****************************************************************************
    函数名称 : mcu_flash_read
    功能描述 :flash 读函数
    输入参数 :addr 地址 size 大小 p_data 待读出数据地址

    返回参数 : 无
    使用说明 : 您需要自行完善
    *****************************************************************************/

    uint8_t mcu_flash_read(uint32_t addr, uint8_t *p_data, uint32_t size)
    {
        #error "请自行完善该功能,完成后请删除该行"
    }
    /*****************************************************************************
    函数名称 : mcu_device_delay_restart
    功能描述 :延迟重启函数,建议延迟 500ms 重启,以等待 MCU 完成一些必要的操作
    输入参数 :

    返回参数 : 无
    使用说明 : 您需要自行完善
     *****************************************************************************/

    void mcu_device_delay_restart(void)
    {
        error "请自行完善该功能,完成后请删除该行"
    }

如果需要写入 boot 标志位,可以在 on_dfu_complete 函数中添加。