OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6254|回复: 4

STM32CUBE iap跳转到APP跑飞 求助

[复制链接]

15

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2020-3-12
在线时间
24 小时
发表于 2023-1-11 17:24:47 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 liyancao001 于 2023-1-11 17:28 编辑

硬件环境:STM32F767ZGT6
先用原子哥的例程改了下测试是可以的,boot程序运行10s后如果没有其他操作则直接跳转到app,app就是串口打印RTC数据。芯片也改成ZGT6了,APP起始地址改成0x0801800。但是我用STM32CUBE 6.3.0做了boot和app程序,并且使用了freeRTOS系统(理论系统不系统的跟IAP没关系吧)
我设计的boot程序初始化完成后打印个“boot初始化完成”,app程序初始化完成后打印个“app初始化完成”。
boot中复制了原子例程中的相关跳转代码,但是发现跳不过去。测试了4种情况:
①原子例程修改boot  + 原子例程修改app ,这个没问题,效果就是串口10s内间隔打印固定字符,10s后提示开始跳转,然后打印RTC时间。
②原子例程修改boot  + CUBE版app,这个不行,10s后提示开始跳转,然后就没任何消息了
③CUBE版boot  + CUBE版app,这个不行,10s后提示开始跳转,然后就没任何消息了
④CUBE版boot  + 原子例程修改app,这个不行,10s后提示开始跳转,然后就没任何消息了

CUBE的Boot添加IAP内容如下:
1)添加了一个iap的.c和.h
  1. #include "ecu_api_iap.h"

  2. #include "main.h"
  3. #include "ecu_api_can.h"

  4. uint8_t BOOT_RX_BUF[BOOT_REC_LEN] __attribute__ ((at(0X20021000)));//接收缓冲,最大USART_REC_LEN个字节,起始地址为0X20021000.  

  5. uint8_t IAP_Status = 0;//bit0为1表示收到下载申请,需要回应 ,bit4=1表示收到结束标志
  6. uint16_t CRC_Receive=0;

  7. iapfun jump2app;
  8. uint32_t iapbuf[512];         //2K字节缓存  
  9. uint32_t applenth=0;


  10. //设置栈顶地址
  11. //addr:栈顶地址
  12. __asm void MSR_MSP(uint32_t addr)
  13. {
  14.         MSR MSP, r0                         //set Main Stack value
  15.         BX r14
  16. }

  17. uint16_t crc_verify(uint8_t *dat,uint32_t lenth)
  18. {
  19.         uint32_t i,j;
  20.         uint16_t temp;
  21.         uint16_t CRC16=0xFFFF;
  22.         uint8_t LSB;

  23.         for(i=0;i<lenth;i++)
  24.         {
  25.                 CRC16 ^= dat[i];

  26.                 for(j=0;j<=7;j++)  
  27.                 {
  28.                         LSB=(uint8_t)(CRC16 & 0x0001 );
  29.                         CRC16=CRC16>>1;
  30.                         if(LSB==1)
  31.                         CRC16^=0xA001;
  32.                 }
  33.         }
  34.     temp=CRC16;
  35.     CRC16=((temp<<8)&0xFF00)|((temp>>8)&0X00FF);
  36.     return (CRC16);
  37. }
  38. //crc校验


  39. //读取指定地址的字(32位数据)
  40. //faddr:读地址
  41. //返回值:对应数据.
  42. uint32_t STMFLASH_ReadWord(uint32_t faddr)
  43. {
  44.         return *(__IO uint32_t *)faddr;
  45. }

  46. //获取某个地址所在的flash扇区
  47. //addr:flash地址
  48. //返回值:0~11,即addr所在的扇区
  49. uint16_t STMFLASH_GetFlashSector(uint32_t addr)
  50. {
  51.         if(addr<ADDR_FLASH_SECTOR_1)return FLASH_SECTOR_0;
  52.         else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_SECTOR_1;
  53.         else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_SECTOR_2;
  54.         else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_SECTOR_3;
  55.         else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_SECTOR_4;
  56.         else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_SECTOR_5;
  57.         else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_SECTOR_6;
  58.         return FLASH_SECTOR_7;        
  59. }

  60. //从指定地址开始写入指定长度的数据
  61. //特别注意:因为STM32F7的扇区实在太大,没办法本地保存扇区数据,所以本函数
  62. //         写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
  63. //         写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
  64. //         没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写.
  65. //该函数对OTP区域也有效!可以用来写OTP区!
  66. //OTP区域地址范围:0X1FF0F000~0X1FF0F41F
  67. //WriteAddr:起始地址(此地址必须为4的倍数!!)
  68. //pBuffer:数据指针
  69. //NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
  70. void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite)        
  71. {
  72.     FLASH_EraseInitTypeDef FlashEraseInit;
  73.     HAL_StatusTypeDef FlashStatus=HAL_OK;
  74.     uint32_t SectorError=0;
  75.         uint32_t addrx=0;
  76.         uint32_t endaddr=0;        
  77.     if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;        //非法地址
  78.    
  79.          HAL_FLASH_Unlock();             //解锁        
  80.         addrx=WriteAddr;                                //写入的起始地址
  81.         endaddr=WriteAddr+NumToWrite*4;        //写入的结束地址
  82.    
  83.     if(addrx<0X1FF00000)
  84.     {
  85.         while(addrx<endaddr)                //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
  86.                 {
  87.                         if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
  88.                         {   
  89.                 FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型,扇区擦除
  90.                 FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //要擦除的扇区
  91.                 FlashEraseInit.NbSectors=1;                             //一次只擦除一个扇区
  92.                 FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围,VCC=2.7~3.6V之间!!
  93.                 if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)
  94.                 {
  95.                     break;//发生错误了        
  96.                 }
  97.                 SCB_CleanInvalidateDCache();                            //清除无效的D-Cache
  98.                         }else addrx+=4;
  99.             FLASH_WaitForLastOperation(FLASH_WAITETIME);                //等待上次操作完成
  100.         }
  101.     }
  102.     FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME);            //等待上次操作完成
  103.         if(FlashStatus==HAL_OK)
  104.         {
  105.                 while(WriteAddr<endaddr)//写数据
  106.                 {
  107.             if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
  108.                         {
  109.                                 break;        //写入异常
  110.                         }
  111.                         WriteAddr+=4;
  112.                         pBuffer++;
  113.                 }
  114.         }
  115.         HAL_FLASH_Lock();           //上锁
  116. }

  117. //从指定地址开始读出指定长度的数据
  118. //ReadAddr:起始地址
  119. //pBuffer:数据指针
  120. //NumToRead:字(32位)数
  121. void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead)           
  122. {
  123.         uint32_t i;
  124.         for(i=0;i<NumToRead;i++)
  125.         {
  126.                 pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.
  127.                 ReadAddr+=4;//偏移4个字节.        
  128.         }
  129. }


  130. //appxaddr:应用程序的起始地址
  131. //appbuf:应用程序CODE.
  132. //appsize:应用程序大小(字节).
  133. void iap_write_appbin(uint32_t appxaddr,uint8_t *appbuf,uint32_t appsize)
  134. {
  135.         uint32_t t;
  136.         uint16_t i=0;
  137.         uint32_t temp;
  138.         uint32_t fwaddr=appxaddr;//当前写入的地址
  139.         uint8_t *dfu=appbuf;
  140.         for(t=0;t<appsize;t+=4)
  141.         {                                                   
  142.                 temp=(uint32_t)dfu[3]<<24;   
  143.                 temp|=(uint32_t)dfu[2]<<16;   
  144.                 temp|=(uint32_t)dfu[1]<<8;
  145.                 temp|=(uint32_t)dfu[0];         
  146.                 dfu+=4;//偏移4个字节
  147.                 iapbuf[i++]=temp;            
  148.                 if(i==512)
  149.                 {
  150.                         i=0;
  151.                         STMFLASH_Write(fwaddr,iapbuf,512);
  152.                         fwaddr+=2048;//偏移2048  512*4=2048
  153.                 }
  154.         }
  155.         if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.  
  156. }

  157. //跳转到应用程序段
  158. //appxaddr:用户代码起始地址.
  159. void iap_load_app(uint32_t appxaddr)
  160. {
  161.         if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000)        //检查栈顶地址是否合法.
  162.         {         
  163.                 printf("boot:地址合法,开始跳转!\r\n");
  164.                 HAL_RCC_DeInit();        
  165.                 jump2app=(iapfun)*(vu32*)(appxaddr+4);                //用户代码区第二个字为程序开始地址(复位地址)               
  166.                 MSR_MSP(*(vu32*)appxaddr);                                        //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
  167.                 jump2app();                                                                        //跳转到APP.
  168.         }
  169. }


  170. void IAP_CAN_Send(void)
  171. {
  172.         CAN_SEND_MSG msg1;
  173.         uint16_t CRC16=0;
  174.         static uint16_t cycle_count=0;
  175.         
  176.         msg1.ID = 0xCF00081;
  177.         msg1.DLC = 8;
  178.         msg1.IDE = API_CAN_IDE_EXT;        
  179.         
  180.         if((IAP_Status & 0x01) > 0){
  181.                 msg1.data[0]=0xFF;
  182.                 msg1.data[1]=0xFF;
  183.                 msg1.data[2]=0xFF;
  184.                 msg1.data[3]=0xFF;
  185.                 msg1.data[4]=0xFF;
  186.                 msg1.data[5]=0xF1;
  187.                 msg1.data[6]=0;
  188.                 msg1.data[7]=0;

  189.                 CAN_SendMessage(CAN_PORT_2,msg1);        
  190.                 IAP_Status &= 0xFE;
  191.                 printf("boot收到下载申请!\r\n");
  192.                 cycle_count =0;
  193.                 vTaskDelay(1000-1);        
  194.         }
  195.         
  196.         if((IAP_Status & 0x10) > 0){ //收到完成标志
  197.                 cycle_count =0;
  198.                 printf("boot用户程序接收完成!\r\n");
  199.                 printf("boot代码长度:%dBytes\r\n",applenth);               
  200.                
  201.                 msg1.data[0]=0xFF;
  202.                 msg1.data[1]=0xFF;
  203.                 msg1.data[2]=0xFF;
  204.                 msg1.data[3]=0xFF;
  205.                 msg1.data[4]=0xFF;
  206.                 msg1.data[5]=0xF2;
  207.                 msg1.data[6]=0;               
  208.                
  209.                 CRC16 = crc_verify(BOOT_RX_BUF,applenth);
  210.                 if(CRC_Receive == CRC16){
  211.                         msg1.data[7]=0;
  212.                         printf("bootCRC成功!\r\n");               
  213.                         CAN_SendMessage(CAN_PORT_2,msg1);        

  214.                         vTaskDelay(1000-1);        
  215.                         if(((*(vu32*)(0x20021000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
  216.                         {         
  217.                                 iap_write_appbin(FLASH_APP1_ADDR,BOOT_RX_BUF,applenth);//更新FLASH代码   
  218.                                 printf("boot 固件更新完成!\r\n");        
  219.                         }else
  220.                         {   
  221.                                 printf("非FLASH应用程序!\r\n");
  222.                         }        

  223.                         printf("boot 开始执行FLASH用户代码!!\r\n");
  224.                         if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
  225.                         {         
  226.                                 iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
  227.                         }else{
  228.                                 printf("boot非FLASH应用程序,无法执行!\r\n");   
  229.                         }                                       
  230.                 }
  231.                 else{
  232.                         msg1.data[7]=1;
  233.                         printf("bootCRC失败:%X,%X!\r\n", CRC16,CRC_Receive);
  234.                         CAN_SendMessage(CAN_PORT_2,msg1);
  235.                 }               
  236.                 IAP_Status &= 0xEF;
  237.         }
  238.         
  239.         if(cycle_count < 2000){
  240.                 cycle_count ++ ;
  241.         }
  242.         else{
  243.                 printf("启动超时,boot 开始执行FLASH用户代码!!\r\n");
  244.                 if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
  245.                 {         
  246.                         iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
  247.                 }else{
  248.                         printf("boot非FLASH应用程序,无法执行!\r\n");   
  249.                 }               
  250.         }
  251. }
复制代码
.h如下
  1. #ifndef __ECU_API_IAP_H__
  2. #define __ECU_API_IAP_H__

  3. /* Includes ------------------------------------------------------------------*/
  4. //#include "main.h"
  5. #include "usart.h"
  6. #include "stdint.h"

  7. #define BOOT_REC_LEN                          240*1024//定义最大接收字节数 320K
  8. extern uint8_t BOOT_RX_BUF[BOOT_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节,起始地址为0X20021000.  
  9. extern uint8_t IAP_Status;//bie0为1表示收到下载申请,需要回应
  10. extern uint32_t applenth;
  11. extern uint16_t CRC_Receive;

  12. typedef __IO uint32_t  vu32;
  13. typedef  void (*iapfun)(void);                                //定义一个函数类型的参数.   

  14. void MSR_MSP(uint32_t addr);        //设置堆栈地址

  15. //FLASH起始地址
  16. #define STM32_FLASH_BASE 0x08000000         //STM32 FLASH的起始地址
  17. #define FLASH_WAITETIME  50000          //FLASH等待超时时间

  18. #define FLASH_APP1_ADDR                0x08018000          //第一个应用程序起始地址(存放在FLASH)

  19. //STM32F767 FLASH 扇区的起始地址
  20. #if defined(DUAL_BANK)
  21.     #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) //扇区0起始地址, 16 Kbytes
  22.     #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) //扇区1起始地址, 16 Kbytes
  23.     #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) //扇区2起始地址, 16 Kbytes
  24.     #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) //扇区3起始地址, 16 Kbytes
  25.     #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) //扇区4起始地址, 64 Kbytes
  26.     #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) //扇区5起始地址, 128 Kbytes
  27.     #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) //扇区6起始地址, 128 Kbytes
  28.     #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) //扇区7起始地址, 128 Kbytes
  29.    
  30.     #define ADDR_FLASH_SECTOR_12    ((uint32_t)0x08080000) //扇区0起始地址, 16 Kbytes
  31.     #define ADDR_FLASH_SECTOR_13    ((uint32_t)0x08084000) //扇区0起始地址, 16 Kbytes
  32.     #define ADDR_FLASH_SECTOR_14    ((uint32_t)0x08088000) //扇区0起始地址, 16 Kbytes
  33.     #define ADDR_FLASH_SECTOR_15    ((uint32_t)0x0808C000) //扇区0起始地址, 16 Kbytes
  34.     #define ADDR_FLASH_SECTOR_16    ((uint32_t)0x08090000) //扇区4起始地址, 64 Kbytes
  35.     #define ADDR_FLASH_SECTOR_17    ((uint32_t)0x080A0000) //扇区5起始地址, 128 Kbytes
  36.     #define ADDR_FLASH_SECTOR_18    ((uint32_t)0x080C0000) //扇区5起始地址, 128 Kbytes
  37.     #define ADDR_FLASH_SECTOR_19    ((uint32_t)0x080E0000) //扇区5起始地址, 128 Kbytes
  38. #else
  39.     #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) //扇区0起始地址, 32 Kbytes  
  40.     #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) //扇区1起始地址, 32 Kbytes  
  41.     #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) //扇区2起始地址, 32 Kbytes  
  42.     #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) //扇区3起始地址, 32 Kbytes  
  43.     #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) //扇区4起始地址, 128 Kbytes  
  44.     #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) //扇区5起始地址, 256 Kbytes  
  45.     #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) //扇区6起始地址, 256 Kbytes  
  46.     #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) //扇区7起始地址, 256 Kbytes  
  47. #endif


  48. uint32_t STMFLASH_ReadWord(uint32_t faddr);                          //读出字  
  49. void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite);                //从指定地址开始写入指定长度的数据
  50. void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead);                   //从指定地址开始读出指定长度的数据


  51. void IAP_CAN_Send(void);


  52. #endif /* __ECU_API_UART_H__ */
复制代码
2) 把iap.c中的IAP_CAN_Send()放到了一个freeFTOS任务中间隔5ms执行一次。
3)程序中可以看出boot运行10s后就执行    iap_load_app(FLASH_APP1_ADDR);    实际根据串口打印数据看也确实执行了。但是后面没有进入app

目前看我的app和boot程序都有问题。先说boot,这个就直接一个跳转函数应该也没啥啊,数据从ram复制到flash都还没测试呢。。 另外还听说需要在跳转前加上HAL_RCC_DeInit();        ,实测没变化。
请教下做IAP应该掌握哪些调试手段呢?flash中的关键数据都具体什么含义呢?
发现0x08018000和0x08018004的数据跟原子例程中下载后的数据不一样。
这是原子例程修改的,可以正常运行的


这是我用CUBE做的boot和app下载后的数据



再说APP:
我在mian开始位置就加了地址偏移了
int main(void)
{
  /* USER CODE BEGIN 1 */
        SCB->VTOR = FLASH_BASE | 0x18000;//设置偏移量

查阅了一些帖子,另外的一种方法也测试过,那就是解开USER_VECT_TAB_ADDRESS的定义,并且对应修改修改#define VECT_TAB_OFFSET         0x18000U
通过使用CUBEprogrammer查看了下实际下载到芯片的代码,下图位置的数据是一样的。


而且设置里面也对应设置了,跟我修改的原子例程app一样的:


main部分代码如下
  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */
  4.         SCB->VTOR = FLASH_BASE | 0x18000;//设置偏移量
  5.         
  6.     SCB_EnableICache();//使能I-Cache
  7.     SCB_EnableDCache();//使能D-Cache   
  8.         SCB->CACR|=1<<2;   //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题        
  9.   /* USER CODE END 1 */

  10.   /* MCU Configuration--------------------------------------------------------*/

  11.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  12.   HAL_Init();

  13.   /* USER CODE BEGIN Init */
  14.         
  15.   /* USER CODE END Init */

  16.   /* Configure the system clock */
  17.   SystemClock_Config();

  18.   /* USER CODE BEGIN SysInit */

  19.   /* USER CODE END SysInit */

  20.   /* Initialize all configured peripherals */
  21.   MX_GPIO_Init();
  22.   MX_ADC1_Init();
  23.   MX_ADC3_Init();
  24.   MX_SPI1_Init();
  25.   MX_SPI5_Init();
  26.   MX_CAN1_Init();
  27.   MX_CAN2_Init();
  28.   MX_CAN3_Init();
  29.   MX_SPI2_Init();
  30.   MX_SPI3_Init();
  31.   MX_SPI4_Init();
  32.   MX_SPI6_Init();
  33.   MX_UART4_Init();
  34.   MX_UART7_Init();
  35.   MX_TIM6_Init();
  36.   MX_TIM3_Init();
  37.   /* USER CODE BEGIN 2 */
  38.   printf("app初始化1完成\r\n");
复制代码
计划的IAP逻辑是,在app中收到CAN的刷写请求指令后,直接复位到boot中,boot开始接收数据到ram,接收完成后校验没有错误后把程序复制到0x8018000开始的flash中,然后跳转过去。boot开始运行10s没有收到can数据且app程序空间有数据时也自动跳转。

最佳答案

查看完整内容[请看2#楼]

谢谢,试了下没有效果啊,我看SystemInit实现的也是地址偏移,跟SCB->VTOR = FLASH_BASE | 0x18000;这句话重复了啊。 现在能跳转了,但是卡在HAL_Delay这里了,我的timebase默认设置为TIM1了,结果TIM1一直到MX_FREERTOS_Init才开始计数。但是不用IAP的时候HAL_Delay是正常的啊。怎么搞? 我在地址偏移那加了开启所有中断的INTX_ENABLE,但是死到异常中断了。看样子是跳转之前产生的中断在跳转后还想跳过去吧。 有个帖子说: ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2020-3-12
在线时间
24 小时
 楼主| 发表于 2023-1-11 17:24:48 | 显示全部楼层
remonwoo 发表于 2023-1-12 13:14
SystemClock先重新复位下试试。

谢谢,试了下没有效果啊,我看SystemInit实现的也是地址偏移,跟SCB->VTOR = FLASH_BASE | 0x18000;这句话重复了啊。
现在能跳转了,但是卡在HAL_Delay这里了,我的timebase默认设置为TIM1了,结果TIM1一直到MX_FREERTOS_Init才开始计数。但是不用IAP的时候HAL_Delay是正常的啊。怎么搞?
我在地址偏移那加了开启所有中断的INTX_ENABLE,但是死到异常中断了。看样子是跳转之前产生的中断在跳转后还想跳过去吧。
有个帖子说:跳转前复位下SysTick变量的CTRL寄存器。这个怎么实现啊?
回复

使用道具 举报

15

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2020-3-12
在线时间
24 小时
 楼主| 发表于 2023-1-11 17:58:33 | 显示全部楼层
CUBE boot程序跳转到APP正常了,原因是需要把中断关一下再跳,跳到原子例程app是正常打印RTC了,但是跳到我自己的CUBE APP只是在开始打印了:app初始化正常,就没有其他反映了。。
回复

使用道具 举报

0

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
480
金钱
480
注册时间
2020-10-22
在线时间
76 小时
发表于 2023-1-12 13:14:32 | 显示全部楼层
SystemClock先重新复位下试试。
回复

使用道具 举报

0

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
480
金钱
480
注册时间
2020-10-22
在线时间
76 小时
发表于 2023-1-12 13:16:52 | 显示全部楼层
截图20230112131551.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 20:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表