欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > bootloader跳转app卡死(IAP卡死)

bootloader跳转app卡死(IAP卡死)

2024/10/23 23:14:28 来源:https://blog.csdn.net/m0_61973119/article/details/141573040  浏览:    关键词:bootloader跳转app卡死(IAP卡死)

1、 关闭所有中断再跳转APP

        一般bootloader跳转到APP时要关闭app中用到的中断(防止中断打断程序的运行,导致程序跑飞),那么查看系统中用到的中断:串口中断、滴答定时器中断,所以,跳转之前要关闭这两个中断:_disable_irq()和systick。

void jumpToApp(void)
{if ( ( ( * ( __IO uint32_t * ) APPLICATIONADDRESS ) & 0x2FFE0000 ) == 0x20000000 ) //检查栈顶地址是否有数据,FLASH写入成功{LCD_ShowString(10,270,210,24,16,"Jumping to run program");//关闭必要中断SysTick->CTRL = 0X00;//禁止SysTickSysTick->LOAD = 0;SysTick->VAL = 0;__disable_irq();JumpAddress = *(__IO uint32_t*) (APPLICATIONADDRESS + 4);//用户代码区第二个字为程序开始地址(复位地址)Jump_To_Application = (pFunction) JumpAddress;//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)MSR_MSP(*(vu32*)APPLICATIONADDRESS);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)RCC_AHB2PeriphClockCmd( RCC_AHB2Periph_OTG_FS , DISABLE);  //必须失能USB,不然后续代码会因为USB卡死Jump_To_Application();}
}

更新的程序主函数中需要再次使能中断

	SCB->VTOR = 0x08000000|0x60000;__enable_irq();  	 /* 使能总中断 */

2、时钟不匹配问题

我遇到的情况是由于bootload和APP两个代码的时钟源不匹配导致app不运行。bootload用了内部时钟,APP用了外部8M时钟。导致跳转到APP代码时运行到时钟配置就卡死,而时钟没配置成功就无法初始化IO口,也没法发出信号做出提示,看着像app区的代码不运行,但其实还是运行了的。时钟初始化不成功卡死,设置了看门狗,这个时候就会复位。

处理方式:将bootload和APP的时钟源配置成相同的。

3、初始化外设卡死

       解决办法:将外设注销,恢复初始化之前的状态,但也有很大的可能性在APP卡死。

4、IAP跳转最佳思路

在IAP中,判断是否需要跳转APP,需要跳转就在Flash中一个固定地址写入一个标志,我这里就假设写入地址为0x080F FF00,写入标志位0x5555,两个字节的标志位数据。然后执行以下函数,这里就是最经典的一步,复位操作,复位可以让运行环境变得很干净,也不用管哪些外设需要关掉。

void SoftReset(void)
{__set_FAULTMASK(1); // 关闭全部中断NVIC_SystemReset(); // 复位
}int main()
{/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init */if (STMFLASH_Read_One_DWord(JUMP_FLG_ADDR) == 1){iap_jump_app();}//1、读JUMP_FLG_ADDR标志 = 0,不需要跳转,则运行升级程序//2、升级程序,写入到FLASH中,写JUMP_FLG_ADDR标志 = 1//3、SoftReset();//4、读JUMP_FLG_ADDR标志 =1,跳转app程序,但此时的环境是:没有初始化任何外设,没有初始化任何时钟,所以不会出现一些莫名奇妙的卡死问题
}

        通过这种方法跳转到APP,是不会出现时钟配置卡死,和外设初始化卡死的现象,特别注意的是,在进入APP之后一定要第一时间将IAP跳转标志清除,否则下一次升级时无法正常运行IAP。

  /* USER CODE BEGIN 1 */SCB->VTOR = 0x8010000;/* USER CODE END 1 *//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init */iap_clear_flag(JUMP_FLG_ADDR);

5、MCU的内部FLASH擦写寿命

测试的flash型号是sst39vf160,由于测试时间的问题,只测试了一个扇区4个字节,用了整整一个星期才完成所有测试,测试结果总结如下:
    1、flash有寿命限制,sst39vf160手册上说是10万次,实验片的实测却超过80万次。
    2、每一个位的寿命是独立的,也就是说,一个字节的bit0失效了,bit1仍然可以正常操作。
    3、flash的寿命指的是被改写的次数,如果一次擦除或写操作不改变某一个位的内容,该位就不会被磨损。比如一个字节被反复执行“擦除-写入0xfe”操作,把bit0损坏后,该字节高7位的寿命丝毫不受影响。
    4、flash磨损后,总是表现为擦除不干净,多擦除几次又能够擦干净,随着磨损程度的加剧,越来越难以擦除干净,但只要擦干净了,写入一定是正确的。但写入的数据是否牢固就没有办法测了。
    5、只要原来内容是1的位,总是可以被写入,但只要原来内容是0的位,就只有擦除才能改为1.

    实测数据,对一个字节反复写0和擦除,寿命指的是写0的次数。
    第一次擦除不干净的寿命:876842次
    第一次出现连续两次擦除仍然不干净的寿命:1169465次
    第一次出现连续4次擦除仍然不干净的寿命:1769609次
    第一次出现连续8次擦除仍然不干净的寿命:1886879次

6、EEPROM擦写寿命

EEPROM的写入寿命通常在百万次范围内(如EVASH的EV24C256A支持400万次写入)。但在高频次写入的应用中,写入次数限制可能导致芯片过早失效

根据标准,EEPROM在寿命测试中是允许一定的失效概率的,按照IEEE-STD-1005-1998和JEDEC的标准要求,失效概率允许1%。例如某EEPROM芯片的标称寿命为100万次,那拿100片做寿命试验,在100万次时失效的数量小于等于1.(这1片可能在10万次失效,100万次失效前都计算在内)。

7、架构(bootloader+app)

在一定的时间内如果没有程序需要更新则自动跳转到app地址执行用户程序

内部flash 512K

bootloader 跑裸机 48k 主要实现USB升级和eeprom标志位升级

app 跑freeRtos  464K 程序的基本功能,升级时软件复位开始执行bootloader升级

app2 外部flash(W25Q128)  主要用于将USB读取BIN文件先存放到外部FLASH中,在从外部FLASH写入内部FLASH,可以防止芯片变砖。

1、架构(bootloader+app)

在一定的时间内如果没有程序需要更新则自动跳转到app地址执行用户程序

内部flash 512K

bootloader 跑裸机 48k 主要实现USB升级和eeprom标志位升级

app 跑freeRtos  464K 程序的基本功能,升级时软件复位开始执行bootloader升级

app2 外部flash(W25Q128)  主要用于将USB读取BIN文件先存放到外部FLASH中,在从外部FLASH写入内部FLASH,可以防止芯片变砖。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com