RT_Thread应用开发

一、Bootloader固件升级

RT-Thread ST固件更新过程

RT-Thread 通用 Bootloader 的软件框架

image

RT-Thread 通用 Bootloader 特点

  • 以 bin 文件的形式提供,无需修改即可使用
  • 资源占用小,ROM 最小只需要 16KB,最大 32KB
  • 适用于多系列 STM32 芯片(目前支持 F1 和 F4 系列 )
  • 支持各种 SPI Flash 存储固件
  • 支持固件加解密功能
  • 支持多种固件压缩方式
  • 支持恢复出厂固件功能

1.固件升级过程

image

当系统需要升级固件时,Bootloader 将从 download 分区将固件搬运到 app 分区,主要功能流程如下所示:

  1. Bootloader 启动时检查 download 分区和 app 分区中的固件版本。
  2. 如果两个固件版本相同,则跳转到 app 分区,Bootloader 运行结束。
  3. 固件版本不同则将 download 分区中的固件搬运到 app 分区。
  4. 在搬运的过程中 Bootloader 可以对固件进行校验、解密、解压缩等操作。
  5. 搬运完毕后,删除 download 分区中存储的固件。
  6. 重启系统跳转到 app 分区中的固件运行,Bootloader 运行结束。

2.获取 Bootloader

Bootloader 在线获取地址

fal:Flash 抽象层

根据板级实际情况选择硬件配置和分区

image

3.工程设置分区表

/* partition table */
#define FAL_PART_TABLE                                                                                                     \
{                                                                                                                          \
    {FAL_PART_MAGIC_WROD, "download",        "onchip_flash_128k", 0 , (128*1024), 0}, \
    {FAL_PART_MAGIC_WROD, "app",        "onchip_flash_128k", (1*128*1024) , FLASH_SIZE_GRANULARITY_128K-(128*1024), 0}, \
}
//onchip_flash_128k代表首地址为地址0x08020000基础,偏移0, 长度为(128*1024),即128k

二、example程序使用

将示例程序添加到bsp/xxx/application文件夹下,工程文件夹路径下,并在SConscript文件中加入其文件,在编译时或生成工程时,就会将文件加入工程之中执行编译

  • application的SConscript文件

    import rtconfig
    from building import *
    
    cwd     = GetCurrentDir()
    CPPPATH = [cwd, str(Dir('#'))]
    src     = Split("""
    application.c
    startup.c
    """)
    
    # add UI engine demo.
    if GetDepend('PKG_USING_GUIENGINE'):
        src += ['rtgui_demo.c']
        
    src += ['tofile.c'] #将需要添加的文件加入src变量中
    src += ['rtc_test.c']
    
    group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
    
    Return('group')
    

通过FINSH_FUNCTION_EXPORT或MSH_CMD_EXPORT 宏定义,可以将函数加入到Finsh或MSH的命令之中

1.使用Ymodem协议传输文件到RT-Thread文件系统

1)使能Ymodem组件
  • 开启RT-Thread Components ---> Utilities ---> Enable Ymodem
2)添加tofile.c应用程序
  • 将rt-thread\examples\ymodem\tofile.c文件添加到bsp工程的application文件夹中,并在其SConscript文件中添加tofile.c
3)修改文件默认保存路径
  • tofile.c默认使用根目录/保存文件,但ST的SPI Flash关连的文件系统挂载在/spi路径下,所以需要将修改文件保存路径,否则无法生成文件

    static enum rym_code _rym_bg(
            struct rym_ctx *ctx,
            rt_uint8_t *buf,
            rt_size_t len)
    {
        struct custom_ctx *cctx = (struct custom_ctx*)ctx;
        cctx->fpath[0] = '/';
      cctx->fpath[1] = 's';
      cctx->fpath[2] = 'p';
      cctx->fpath[3] = 'i';
      cctx->fpath[4] = '/';
      /* the buf should be the file name */
        strcpy(&(cctx->fpath[5]), (const char*)buf);
    
4)增加msh命令
  • tofile.c默认使用FinSH命令,增加一个msh命令方便使用

    //在tofile.c末尾添加
    rt_err_t ymodem_rec(uint8_t argc, char **argv)
    {
      rt_err_t res;
    
        rt_device_t dev = rt_device_find(argv[1]);
        if (!dev)
        {
            rt_kprintf("could not find device:%s\n", argv[1]);
            return -RT_ERROR;
        }
    
        res = rym_write_to_file(dev);
    
        return res;
    }
    
    MSH_CMD_EXPORT(ymodem_rec, receive files by ymodem protocol);
    
5)使用Ymodem
  • 编译并烧录程序,使用SecureCRT连接调试串口
    • 在msh命令中输入:ymodem_rec uart1,准备接收文件,在SecureCRT选择Ymodem传输方式,选择文件传输。

三、设备和驱动

RT_Thread设备类型定义

enum rt_device_class_type
{
    RT_Device_Class_Char = 0,                           /**< character device */
    RT_Device_Class_Block,                              /**< block device */
    RT_Device_Class_NetIf,                              /**< net interface */
    RT_Device_Class_MTD,                                /**< memory device */
    RT_Device_Class_CAN,                                /**< CAN device */
    RT_Device_Class_RTC,                                /**< RTC device */
    RT_Device_Class_Sound,                              /**< Sound device */
    RT_Device_Class_Graphic,                            /**< Graphic device */
    RT_Device_Class_I2CBUS,                             /**< I2C bus device */
    RT_Device_Class_USBDevice,                          /**< USB slave device */
    RT_Device_Class_USBHost,                            /**< USB host bus */
    RT_Device_Class_SPIBUS,                             /**< SPI bus device */
    RT_Device_Class_SPIDevice,                          /**< SPI device */
    RT_Device_Class_SDIO,                               /**< SDIO bus device */
    RT_Device_Class_PM,                                 /**< PM pseudo device */
    RT_Device_Class_Pipe,                               /**< Pipe device */
    RT_Device_Class_Portal,                             /**< Portal device */
    RT_Device_Class_Timer,                              /**< Timer device */
    RT_Device_Class_Miscellaneous,                      /**< Miscellaneous device */
    RT_Device_Class_Sensor,                             /**< Sensor device */
    RT_Device_Class_Unknown                             /**< unknown device */
};

char *const device_type_str[] =
{
    "Character Device",
    "Block Device",
    "Network Interface",
    "MTD Device",
    "CAN Device",
    "RTC",
    "Sound Device",
    "Graphic Device",
    "I2C Bus",
    "USB Slave Device",
    "USB Host Bus",
    "SPI Bus",
    "SPI Device",
    "SDIO Bus",
    "PM Pseudo Device",
    "Pipe",
    "Portal Device",
    "Timer Device",
    "Miscellaneous Device",
    "Sensor Device",
    "Unknown"
};
  • rt-thread\bsp\stm32的资源配置在drv_config.h中选择。

  • rt-thread\bsp\stm32\stm32f429-atk-apollo\board\CubeMX_Config\Src\stm32f4xx_hal_msp.c是芯片具体的资 源配置。

  • 可以通过stm32cubemx生成资源配置文件。

1.Pin设备

应用程序通过 RT-Thread 提供的 PIN 设备管理接口来访问 GPIO,相关接口如下所示:

函数 描述
rt_pin_mode() 设置引脚模式
rt_pin_write() 设置引脚电平
rt_pin_read() 读取引脚电平
rt_pin_attach_irq() 绑定引脚中断回调函数
rt_pin_irq_enable() 使能引脚中断
rt_pin_detach_irq() 脱离引脚中断回调函数
  • 这些函数默认没有使用宏定义RTM_EXPORT将其导出到符号表,如果动态模块需要使用,则需要将其导出。
1)获取引脚编号
  • 如果使用 rt-thread/bsp/stm32 目录下的 BSP 则可以使用下面的宏获取引脚编号
    • GET_PIN(port, pin)
  • 如果使用其他 BSP 则需要查看 PIN 驱动代码 drv_gpio.c 文件确认引脚编号。此文件里有一个数组存放了每个 PIN 脚对应的编号信息
    • 如:STM32F429-apollo是基于STM32F4xx_PIN_NUMBERS == 176的芯片,参考rt-thread\bsp\stm32f429-apollo\drivers\drv_gpio.c的pins[]数组,PB.0和PB.1分别对应index 56和57。

2.ADC

  • 开启adc需要把RT_USING_DEVICE_OPS也打开,否则看不到adc设备

    • RT-Thread Kernel → Kernel Device Object → Using ops for each device object
  • rt-thread\bsp\stm32f429-apollo的drivers默认没有注册adc设备的驱动,需要自行添加

    • 其stm32f4xx_hal_conf.h中也没有define HAL_ADC_MODULE_ENABLED 需要自行打开注释

3.UART

  • bsp\stm32\stm32f429-atk-apollo中只会初始化uart1,需要在底层文件中添加uart2和uart3的初始化程序

    • rt-thread\bsp\stm32\stm32f429-atk-apollo\board\CubeMX_Config\Src\stm32f4xx_hal_msp.c是芯片具体的资源配置
    • stm32_configure -> HAL_UART_Init -> HAL_UART_MspInit(UART_HandleTypeDef* huart)
    void HAL_UART_MspInit(UART_HandleTypeDef* huart)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(huart->Instance==USART1)
      {
      /* USER CODE BEGIN USART1_MspInit 0 */
          
    
      /* USER CODE END USART1_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
      
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART1 GPIO Configuration    
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        /* USART1 interrupt Init */
        HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
      /* USER CODE BEGIN USART1_MspInit 1 */
    
      /* USER CODE END USART1_MspInit 1 */
      }
      
      if (huart->Instance == USART2)
      {
          /* Enable USARTx clock */
          __HAL_RCC_USART2_CLK_ENABLE();
          
          __HAL_RCC_GPIOA_CLK_ENABLE();
          /**USART1 GPIO Configuration    
          PA2     ------> USART2_TX
          PA3     ------> USART2_RX 
          */
          GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Pull = GPIO_PULLUP;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
          GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
          HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
          /* USART1 interrupt Init */
          HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);
          HAL_NVIC_EnableIRQ(USART2_IRQn);
      }
    
      if (huart->Instance == USART3)
      {
          /* Enable USARTx clock */
          __HAL_RCC_USART2_CLK_ENABLE();
          
          __HAL_RCC_GPIOA_CLK_ENABLE();
          /**USART1 GPIO Configuration    
          PB10     ------> USART3_TX
          PB11     ------> USART3_RX 
          */
          GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Pull = GPIO_PULLUP;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
          GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
          HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
          /* USART1 interrupt Init */
          HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);
          HAL_NVIC_EnableIRQ(USART2_IRQn);
      }
    
    }
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容