RT Thread Studio 配置OTA(亲测成功,巨详细)
用rt thread新建工程,我用的stm32f103vet6,stlink
首先配置外部时钟hse,可以直接复制以下代码到drv_clk.c中的void system_clock_config(int target_freq_Mhz),也可以自己在cubemx生成。
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
- in the RCC_OscInitTypeDef structure.
/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
配置spi,这个按board.h中的步骤来就行
这里我用的野火的f103指南者,w25q64是a5,a6,a7,不同的板子要在cubemx自己修改
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI3 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
然后配置rtc,按这个步骤来就行
标题在applications下创建flash.c,这里叫什么无所谓,把以下代码复制进去
#include "spi_flash_sfud.h"
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
rt_uint8_t wData[4096] = {"SPI bus write data to W25X flash."};
rt_uint8_t rData[4096];
extern rt_err_t rt_hw_spi_device_attach(const char *bus_name,
const char *device_name,
GPIO_TypeDef* cs_gpiox,
uint16_t cs_gpio_pin);
int spi1_device_init(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
//设备挂载到SPI总线,抽象为 spi10 设备
rt_hw_spi_device_attach("spi1", "spi10", GPIOC, GPIO_PIN_0);
if (rt_sfud_flash_probe("W25Q64", "spi10")) {
rt_kprintf("rt sfud flash probe success\n");
} else {
rt_kprintf("rt sfud flash probe fail\n");
};
return RT_EOK;
}
INIT_DEVICE_EXPORT(spi1_device_init);//自动初始化
rt_hw_spi_device_attach(“spi1”, “spi10”, GPIOC, GPIO_PIN_0);这行就是spi中的cs,如果用的引脚不同记得修改,和硬件上对应。编译,下载。
添加fal软件包,这个地方,把名字改成和自己对应的,我的是W25Q64
把这个文件复制到这里。
回到rt thread studio刷新一下,把下面代码复制进去。
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtconfig.h>
#include <board.h>
#include <rtconfig.h>
#define FLASH_SIZE_GRANULARITY_16K (4 * 16 * 1024)
#define FLASH_SIZE_GRANULARITY_64K (64 * 1024)
#define FLASH_SIZE_GRANULARITY_128K (7 * 128 * 1024)
#define STM32_FLASH_START_ADRESS_16K STM32_FLASH_START_ADRESS
#define STM32_FLASH_START_ADRESS_64K (STM32_FLASH_START_ADRESS_16K + FLASH_SIZE_GRANULARITY_16K)
#define STM32_FLASH_START_ADRESS_128K (STM32_FLASH_START_ADRESS_64K + FLASH_SIZE_GRANULARITY_64K)
/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev stm32_onchip_flash_16k;
extern const struct fal_flash_dev stm32_onchip_flash_64k;
extern const struct fal_flash_dev stm32_onchip_flash_128k;
/* ===================== Flash device Configuration ========================= */
extern struct fal_flash_dev nor_flash0;
#define FAL_FLASH_DEV_TABLE \
{ \
&stm32_onchip_flash_16k, \
&stm32_onchip_flash_64k, \
&stm32_onchip_flash_128k, \
&nor_flash0, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
\
{FAL_PART_MAGIC_WORD, "app", "onchip_flash_128k", 0, 256*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", FAL_USING_NOR_FLASH_DEV_NAME, 0, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
然后编译会报错
是因为这几个16k,64k,128k没定义,复制一下程序到这个.c文件里
const struct fal_flash_dev stm32f2_onchip_flash =
{
.name = "stm32_onchip",
.addr = 0x08000000,
.len = 1024*1024,
.blk_size = 128*1024,
.ops = {init, read, write, erase},
.write_gran = 8
};
const struct fal_flash_dev stm32_onchip_flash_128k =
{
.name = "onchip_flash_128k",
.addr = 0x08020000,
.len = 1024*1024,
.blk_size = 1024*1024,
.ops = {init, read, write, erase},
.write_gran = 8
};
const struct fal_flash_dev stm32_onchip_flash_16k =
{
.name = "onchip_flash_16k",
.addr = 0x08000000,
.len = 1024*1024,
.blk_size = 256*1024,
.ops = {init, read, write, erase},
.write_gran = 8
};
const struct fal_flash_dev stm32_onchip_flash_64k =
{
.name = "onchip_flash_64k",
.addr = 0x08010000,
.len = 1024*1024,
.blk_size = 1024*1024,
.ops = {init, read, write, erase},
.write_gran = 8
};
这里打开main.c把下面的代码复制进去
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09-26 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <board.h>
#include <rtdevice.h>
#include "fal.h"
#define RT_APP_PART_ADDR 0x08020000
#define VER "V3.6.0"
int main(void)
{
int count = 1;
fal_init();
LOG_D("Hello RT-Thread!");
rt_kprintf("version:%s\r\n",VER);
while (count++)
{
rt_thread_mdelay(1000);
}
return RT_EOK;
}
编译,下载
恭喜你。快成功了。打开link.lds,修改为0x802
安装ota
把ymodem也打开
接下来配置bootloader。进入http://iot.rt-thread.com
这个地方随便创建就好,其他的按自己板子的情况选就好
点击生成bootloader
打开STM32 ST-LINK Utility,用j-link也行,这方面的教程很多,我这里用STM32 ST-LINK Utility,选择刚刚在邮箱下载的bin文件。
重新下程序,出现报错,把libc打开
可能会出现stlink下不进程序的问题,重新用STM32 ST-LINK Utility升级一下stlink固件就好了,或者按着单片机复位键下程序。这里是为啥我也不知道。
用打包工具打包,在这个路径下
选择该工程的固件
在命令行输入ymodem_ota
然后得用一下xshell了,右键传输,选择刚刚debug文件下的rbl,文件
点击打开就开始了,这里实现远程下载的话可以用4g模块,其实esp8266应该也可以