STM32 IAP example

发布者:Zhenxiang最新更新时间:2024-09-30 来源: cnblogs关键字:STM32  IAP 手机看文章 扫描二维码
随时随地手机看文章

///////////////////////////////////////////////////////////////////////////////////////////////////

bool ota_EraseSector(void)

{

  nd_FlashUnlock();

 

  FLASH_EraseInitTypeDef FLASH_EraseInitStruct;

 

  FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;

  FLASH_EraseInitStruct.Sector = FLASH_SECTOR_6;

  FLASH_EraseInitStruct.NbSectors = 1;

  FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;

  uint32_t SectorError = 0;

  return (HAL_OK == HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &SectorError));

}

bool app_EraseSector(void)

{

  nd_FlashUnlock();

  FLASH_EraseInitTypeDef FLASH_EraseInitStruct;

 

  FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;

  FLASH_EraseInitStruct.Sector = FLASH_SECTOR_5;

  FLASH_EraseInitStruct.NbSectors = 1;

  FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;

  uint32_t SectorError = 0;

  return (HAL_OK == HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &SectorError));

}

bool config_EraseSector(void)

  nd_FlashUnlock();

  FLASH_EraseInitTypeDef FLASH_EraseInitStruct;

 

  FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;

  FLASH_EraseInitStruct.Sector = FLASH_SECTOR_1;

  FLASH_EraseInitStruct.NbSectors = 1;

  FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;

  uint32_t SectorError = 0;

  return (HAL_OK == HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &SectorError));

}

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

nd_ota_config_t g_ota_conf = {0};

void load_factory_config(void)

{

  nd_flash_read(NDADDR_INFO, (uint8_t *)&g_ota_conf, sizeof(nd_ota_config_t));

}

void save_factory_config(void)

{

  nd_FlashUnlock();

  nd_flash_write(NDADDR_INFO, (uint8_t *)&g_ota_conf, sizeof(nd_ota_config_t));

}

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

4.      引导代码.


static void exec_application(void)

  uint32_t JumpAddress;

  pFunction Jump_To_Application;

 

  if ((((*(__IO uint32_t *) NDADDR_FW_APP)  & 0x2FFE0000) == 0x20000000) /* 检查栈顶地址是否合法 */

        || (((*(__IO uint32_t *) NDADDR_FW_APP) & 0xFF000000) ==

            0x10000000))

  {

    /* Jump to user application */

    JumpAddress = *(__IO uint32_t *) (NDADDR_FW_APP + 4);

    Jump_To_Application = (pFunction) JumpAddress;

    /* Initialize user application's Stack Pointer */

    __set_MSP(*(__IO uint32_t *) NDADDR_FW_APP);

    Jump_To_Application();

  }

}

static void update_app_from_ota(void)

{

  app_EraseSector();

 

  nd_FlashUnlock();

  //g_ota_conf.page_cnt * 2K 的 数据从 OTA区 转移到 App区.

  uint32_t idx_pages, idx_oft;

  uint32_t src_addr = NDADDR_FW_OTA;

  uint32_t dst_addr = NDADDR_FW_APP;

 

  for (idx_pages = 0; idx_pages < g_ota_conf.page_cnt; idx_pages++) {

    nd_flash_write(dst_addr, (uint8_t *)src_addr, FW_PAGE_SIZE);

    dst_addr += FW_PAGE_SIZE;

    src_addr += FW_PAGE_SIZE;

  }

}

int main(void)

{

  //首先读取 g_ota_conf, 确定是否需要升级.

  memset(&g_ota_conf, 0, sizeof(g_ota_conf));

  load_factory_config(); 

 

  if (NDADDR_FW_OTA == g_ota_conf.fw_addr) { //不需要升级.

    //从OTA更新到APP.

    update_app_from_ota();

   

    //改写配置.

    if (config_EraseSector()) {

      g_ota_conf.fw_addr = NDADDR_FW_APP;

      g_ota_conf.page_cnt = 0; 

      //g_ota_conf.sn = 0x8010191120A90200;  

      save_factory_config();

    }   

  }

 

  exec_application(); //升级完毕后, 调用应用端. 

  while (1)

  {

  }

}

5.      App区

在 main.c 中开始位置写入SCB->VTOR = NDADDR_FW_APP; 即可. 

最好的是写在 system_stm32f7xx.c 的 SystemInit的第一行

同时设置 

同样主要是起始地址 和大小

下面就是实现协议从主机下载固件并更新到 OTA区即可.

发现的问题, IAP到了App时候启动比较慢.


[1] [2]
关键字:STM32  IAP 引用地址:STM32 IAP example

上一篇:Stm32空指令使用
下一篇:STM32 UART/USART 的差别

推荐阅读最新更新时间:2024-11-13 14:23

STM32看门狗总结篇(续)
在调节利用DMA向串口发送数据的过程中,必须在使能DMA,执行完发送数据的操作后再关闭DMA,否则串口将不能连续自动发送数据。只能在复位时进行发送,不复位则停止发送。 如图所示,添加关闭DMA的语句,则可实现连续发送: 在注释掉关闭DMA的语句后,则串口不能连续发送数据: 如有大神指导原因,可以在此留言,谢谢。 补充DMA相关的知识: ①、DMA的各个通道对应特定的外设,在使用时需要一一对应。 ②、三种传输方式:外设- 内存,内存- 外设,内存- 内存 ③、由于DMA传输不需要CPU的参与。所以在调试的时候会发现,在我们单步停止的时候,串口依然不停地向外发送数据。(未经验证) ④、DMA实现数据转移是采用共享系统
[单片机]
<font color='red'>STM32</font>看门狗总结篇(续)
STM32--对原子哥USART实验中printf重定向进行分析
原子哥的USART代码中,有一部分感觉看得不是很懂 #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef
[单片机]
盛况空前,高峰论坛、STM32峰会圆满结束
STM32峰会圆满结束 STM32峰会4月26日-27日在深圳如期召开,盛况空前! o 出席人数达3500人 o 45个合作伙伴参与 o 180个展出 o 40场专题会议和技术研讨会 o 在线观众最高时达到5万多人! 2019年STM32峰会以一场AI魔鞋舞蹈揭开帷幕,精彩表演令全场嘉宾惊艳。 日本公司No New Folk Studio的首个智能鞋日志平台Orphe Track是STM32峰会上主要的第三方演示产品之一。该智能鞋的传感器模块Orphe Core采用意法半导体的传感器,能够极其精确和高效地跟踪用户的运动。传感器内部AI算法能够学习用户的行走和跑
[物联网]
盛况空前,高峰论坛、<font color='red'>STM32</font>峰会圆满结束
18. 利用TIM3产生PWM输出实验
一。 PWM简介 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。 STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出。 这里我们仅利用 TIM3的 CH2 产生一路 PWM 输出。 对于每个通道都有一个捕获比较寄存器CCRx,C
[单片机]
18. 利用TIM3产生PWM输出实验
STM32+freeRTOS学习笔记-1.使用cube MX创建一个freeRTOS的keil工程
硬件:机智云STM32平台V2.1 软件:cube MX+keil MDK-ARM V5 机智云的STM32开发平台小巧玲珑,用起来也顺手,所以就将正点原子的战舰开发板扔一旁吃灰了。目前刚开始学习,用到的硬件资源也不多,后续做相关实验时说不准又捡起来了。 1.简单介绍一下cube MX的使用 下载安装的过程就不在赘述,直接开始使用。 双击打开cube MX,点击新建工程 由于本底板的MCU型号是:STM32F103C8T6,所以按照下图来选择就对了。这个根据当时自己使用的MCU型号来对应选择就好了。 接着就是资源配置界面了, 1、先配置RCC的时钟源为外部高速时钟 2、配置时钟系统,其实很简单,
[单片机]
STM32+freeRTOS学习笔记-1.使用cube MX创建一个freeRTOS的keil工程
STM32定时器控制led灯亮灭
SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置 系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产 生一次中断,以此循环往复。 在使用时,只需要配置前三个寄存器,最后一个校准寄存器不需要使用。 接下来,利用 SysTick 产生 1s 的时基,LED 以 1s 的频率闪烁。 1、设置重装载寄存器的值 2、清除当前数值寄存器的值 3、配置控制与状态寄存器 配置头文件: void PendSV_Handler(void) { }
[单片机]
解决STM32 SD卡官方库移植时 获取不到SD Status寄存器值的问题
前言 SD卡内部的SD Status寄存器和Card Status寄存器从名字上来看好像都是状态寄存器,但实际上所要呈现的工程是不同的,这一点要注意; 本博文主要说内容是怎样正确的获取SD Status寄存器的值; 如有不足之处,还请多多指教; 问题 SD Status寄存器表如下,我想获取其中的AU_SIZE的值 ( 这段位域内没有信息,我这里忽略了) 如下图,AU_SIZE的值本身应该在0x01~0x09之间,但是我用串口打印出来的值却是0; 获取SD Status寄存器的函数代码如下: /** * @brief SD Card Status */ typedef struct { __IO uint8_
[单片机]
解决<font color='red'>STM32</font> SD卡官方库移植时 获取不到SD Status寄存器值的问题
STM32硬件电路设计注意事项
1、电源 1) 、无论是否使用模拟部分和AD 部分,MCU 外围出去VCC 和GND,VDDA 、VSSA 、Vref(如果封装有该引 脚)都必需要连接,不可悬空; 2) 、对于每组对应的VDD 和GND 都应至少放置一个104的陶瓷电容用于滤波,并接该电容应放置尽量靠 近MCU; 2、复位、启动选择 1) 、Boot引脚与JTAG无关。它仅是用于MCU启动后,判断执行代码的起始地址; 2) 、在电路设计上可能Boot引脚不会使用,但要求一定要外部连接电阻到地或电源(为0或1),切不可悬空; 3 、ADC 1) 、ADC 是有工作电压的,且与MCU 的工作电压不完全相同。MCU 工
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved