硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2356|回复: 21
收起左侧

请教下,使用 iap 跳转功能时,貌似判断的值不对 ?

[复制链接]

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
发表于 2017-12-10 22:09:34 | 显示全部楼层 |阅读模式
请教下,使用 iap 跳转功能时,貌似判断的值不对 ?

#define  USER_FLASH_FIRST_PAGE_ADDRESS      0x08080000
void Jump_To_APP(void)
{
  //检测APP地址是否合法
   // Check if valid stack address (RAM address) then jump to user application
  /*
  // 根据不同的 用户 app 的地址,仿真得到的结果值 这个地方为何会不同啊 ???????????
  JumpAddress = ((*(__IO uint32_t*) 0x08080000 ) & 0x2FFE0000 );   // = 0x20020000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08060000 ) & 0x2FFE0000 );   // = 0x2FFE0000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08040000 ) & 0x2FFE0000 );   // = 0x2D700000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08020000 ) & 0x2FFE0000 );   // = 0x2F3E0000
  */
  
  if (((*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS ) & 0x2FFE0000 ) == 0x20020000)
  {
    // Jump to user application
    JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
    Jump_To_Application = (pFunction) JumpAddress;
   
    //设置APP程序堆栈指针
    __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);  //跳转到APP.  程序最终跳转后不能够运行,但是 app 程序如果单独下载运行是没有问题的
    Jump_To_Application();  //跳转到APP.
  }
  else
  {
    printf("jump uaer app run error ??\r\n");
    for(;;)
    {}

  }
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2017-12-11 00:18:10 | 显示全部楼层
这些判断:
  JumpAddress = ((*(__IO uint32_t*) 0x08080000 ) & 0x2FFE0000 );   // = 0x20020000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08060000 ) & 0x2FFE0000 );   // = 0x2FFE0000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08040000 ) & 0x2FFE0000 );   // = 0x2D700000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08020000 ) & 0x2FFE0000 );   // = 0x2F3E0000

  if (((*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS ) & 0x2FFE0000 ) == 0x20020000)

删掉,没用,你自己写程序的APP程序看下ram超没超即可。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-11 09:48:03 | 显示全部楼层

回 eric2013 的帖子

eric2013:这些判断:
  JumpAddress = ((*(__IO uint32_t*) 0x08080000 ) & 0x2FFE0000 );   // = 0x20020000
  
  JumpAddress = ((*(__IO uint32_t*) 0x08060000 ) & 0x2FFE0000 );   // = 0x2FFE0000
  
....... (2017-12-11 00:18)
我的 iap 的 ram 地址是从 0x2000 0000 开始的,

app 的 ram 也是从 0x2000 0000 开始的,他们应该不会发生冲突吧 ??

总的应用范围是没有超过的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2017-12-11 09:49:36 | 显示全部楼层

回 hpdell 的帖子

hpdell:我的 iap 的 ram 地址是从 0x2000 0000 开始的,

app 的 ram 也是从 0x2000 0000 开始的,他们应该不会发生冲突吧 ??

....... (2017-12-11 09:48) 
不会冲突。已经跳转到APP了,当前的已经没有用了。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-11 11:09:11 | 显示全部楼层

Re:回 hpdell 的帖子

eric2013:

不会冲突。已经跳转到APP了,当前的已经没有用了。

你好,我现在貌似可以跳转了,但是跳转 后,用户的 app 程序不能够运行,但是如果使用 jlink 直接下载用户 app 程序到板子里面是可以正常运行的,

iap 程序如下:
iap-0.png


iap-2.png


iap-1.png


#define  USER_FLASH_FIRST_PAGE_ADDRESS   0x08080000

void Jump_To_APP(void)
{
  __set_PRIMASK(1);// 关闭全局中断。注意,在跳转前,必须先关闭全局中断,进入用户程序后,在中断向量表地址设置完成后再开中断。   
    // 通过判断栈顶地址值是否正确来判断是否已经下载用户应用程序。因为用户程序的启动文件开始会初始化栈空间,如果栈顶地址正确,说明用户程序已经下载
//    __ASM("CPSID  I");
   printf("Jump to the new program.\\r\\n");
    // Jump to user application
    JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);// 前4字节为中断向量表
    Jump_To_Application = (pFunction) JumpAddress;// 指向用户程序复位函数所在的地址


//   __set_PSP(*(volatile uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
//   __set_CONTROL(0);   

    //设置APP程序堆栈指针
    __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);  // 设置用户程序的栈指针
    Jump_To_Application();  // 执行用户程序
}



用户app 设置如下:
用户 app 程序是带 FreeRTOS 的,不过我的 FreeRTOS 系统是在我所以的 外设初始化完成后才启动的
app-0-0x08080000.png


app-3-0x08080000.png


app-2-0x08080000.png



下面这个是 map 文件,程序入口地址貌似也是对的吧 ??
我使用的是 iar
app-1-0x08080000.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2017-12-12 00:34:44 | 显示全部楼层
看着没问题,是执行到APP的那部分死机的。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-12 10:25:02 | 显示全部楼层

回 eric2013 的帖子

eric2013:看着没问题,是执行到APP的那部分死机的。 (2017-12-12 00:34) 
程序跳转后,也不能够仿真,悲催啊,现在也不知道该如何搞啦
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2017-12-12 10:28:06 | 显示全部楼层

回 hpdell 的帖子

hpdell:程序跳转后,也不能够仿真,悲催啊,现在也不知道该如何搞啦 (2017-12-12 10:25) 
在必要的位置加串口打印看看。串口加不上的话,就弄个LED翻转。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-12 11:22:50 | 显示全部楼层

回 eric2013 的帖子

eric2013:在必要的位置加串口打印看看。串口加不上的话,就弄个LED翻转。 (2017-12-12 10:28) 
好的,我试试看,多谢多谢啊
回复

使用道具 举报

3

主题

66

回帖

75

积分

初级会员

积分
75
发表于 2017-12-12 12:11:41 | 显示全部楼层
IAP 程序把和 升级不相关的中断都不要开。你开串口中断了吗?跳转之前等串口打印完了再跳转。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-12 14:13:37 | 显示全部楼层

回 westzg 的帖子

westzg:IAP 程序把和 升级不相关的中断都不要开。你开串口中断了吗?跳转之前等串口打印完了再跳转。 (2017-12-12 12:11) 
串口貌似应该是没有开的,我使用串口发送数据一般都是查询方式的,程序中貌似是开启了

滴答定时器、sd卡 中断,我在跳转前已经关闭了所以中断功能了
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-12 19:54:06 | 显示全部楼层

回 eric2013 的帖子

eric2013:

在必要的位置加串口打印看看。串口加不上的话,就弄个LED翻转。
eric2013:
可以分开的,以我们的F429为了,我们是用的I2S时钟用于SAI,而SAI的时钟用于LCD。

ps:多发的一个帖子帮你删除了。

jmp.png

你好,现在最新进展情况,貌似执行了第 52 行的代码后就出现 什么  The stack pointer for stack 'CSTACK' (currently 0x20022CD8) is outside the stack range (0x200003B0 to 0x200043B0)

这个是怎么回事啊 ???????????

是不是我 的 iap 程序分的太大了啊 ? 我目前分配的是 256KB/512KB结果都是一样的

程序擦除函数如下:

int8_t FLASH_If_Erase(uint32_t StartSector)
{
  uint32_t FlashAddress;

  FlashAddress = StartSector;

  /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
     be done by word */

  if (FlashAddress <= (uint32_t) USER_FLASH_LAST_PAGE_ADDRESS)
  {
    FLASH_EraseInitTypeDef FLASH_EraseInitStruct;
    uint32_t sectornb = 0;
   
    FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
    FLASH_EraseInitStruct.Sector = FLASH_SECTOR_5;                          //  单片机是2MBflash大小
                                                                            //前面的256KB留给bootloader使用,所以
                                                                            //此处是扇区5开始
    FLASH_EraseInitStruct.NbSectors = FLASH_SECTOR_11 - FLASH_SECTOR_5 + 1;
    FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
   
    if (HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &sectornb) != HAL_OK)
      return (1);
  }
  else
  {
    return (1);
  }

  return (0);
}

扇区分配如下:
flash-sector.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2017-12-13 00:28:21 | 显示全部楼层

回 hpdell 的帖子

hpdell:

你好,现在最新进展情况,貌似执行了第 52 行的代码后就出现 什么  The stack pointer for stack 'CSTACK' (currently 0x20022CD8) is outside the stack range (0x200003B0 to 0x200043B0)
....... (2017-12-12 19:54) 
忘了问你了,你的IAP和APP都是裸机程序么,那个用RTOS了?
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-13 09:43:58 | 显示全部楼层

回 eric2013 的帖子

eric2013:忘了问你了,你的IAP和APP都是裸机程序么,那个用RTOS了? (2017-12-13 00:28) 
我的 iap 是裸机, app 是带 rtos的
回复

使用道具 举报

2

主题

134

回帖

140

积分

初级会员

积分
140
发表于 2017-12-13 12:24:10 | 显示全部楼层
我之前也遇到过跳转之后无法执行的问题   当时找到的原因是跟RTOS有关   RTOS启动之后跳转就无法执行   在RTOS启动之前跳转就可以正常运行   具体原因没找下去   推测可能跟中断向量有关系    你在跳转之前把所有的中断都复位
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-13 16:43:50 | 显示全部楼层

回 hanzixiangel 的帖子

hanzixiangel:我之前也遇到过跳转之后无法执行的问题   当时找到的原因是跟RTOS有关   RTOS启动之后跳转就无法执行   在RTOS启动之前跳转就可以正常运行   具体原因没找下去   推测可能跟中断向量有关系    你在跳转之 .. (2017-12-13 12:24)
你好,我刚刚又捣鼓了一下,目前 如果 是 app 不使用 系统的话,现在可以正常跳转了,

app 带系统的的还不行?

我目前的跳转函数如下:


void Jump_To_APP(void)
{
  //检测APP地址是否合法

  printf("\\r\\n_______ *** *** Jump to the new program run please ... *** ***_______\\r\\n\\r\\n");
   
  // 判断栈顶地址是否在0x2000 0000 - 0x2000 2000之间,这个判断也可以使用,完全木有任何问题的
  if (((*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS ) & 0x2FFE0000 ) == 0x20000000)
  {
    // 通过判断栈顶地址值是否正确来判断是否已经下载用户应用程序。因为用户程序的启动文件开始会初始化栈空间,如果栈顶地址正确,说明用户程序已经下载
//    __ASM("CPSID  I");
    // Jump to user application
    JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);// 前4字节为中断向量表
    Jump_To_Application = (pFunction) JumpAddress;// 指向用户程序复位函数所在的地址
   
    // 关闭所有外设中断
    HAL_NVIC_DisableIRQ(ETH_IRQn);
    HAL_NVIC_DisableIRQ(USART1_IRQn); //关闭串口中断
    HAL_NVIC_DisableIRQ(SD_IRQn);
    HAL_NVIC_DisableIRQ(SD_DMAx_Rx_IRQn);
    HAL_NVIC_DisableIRQ(SD_DMAx_Tx_IRQn);
   
    PWM_Stop();   
    HAL_FLASH_Lock();
    __disable_irq();  //关闭总中断

   {
        /*
        Reset of all peripherals  
        这些外设关闭非常重要,否则不能够正常实现程序跳转功能,切记切记
        */
        __APB1_FORCE_RESET();
        __APB1_RELEASE_RESET();
        __APB2_FORCE_RESET();
        __APB2_RELEASE_RESET();
        HAL_RCC_DeInit();   
    }

  
//   __set_PSP(*(volatile uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
//   __set_CONTROL(0);   
   
    //设置APP程序堆栈指针
    __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);  // 设置用户程序的栈指针
    __set_CONTROL(0);
   
    SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk;   // 关闭滴答定时器中断
    SysTick->VAL = 0;
    SysTick->LOAD = 0;   
   
    Jump_To_Application();  // 执行用户程序
  }
  else
  {
    printf("jump uaer app run error ??\\r\\n");
    for(;;)
    {}

  }
}

上述跳转函数中,红色的部分相当重要,否则 哪怕是 app 不带系统也无法实现跳转;
现在app 带 系统的程序跳转还没有实现,继续捣鼓中 ... ... ???
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2017-12-15 20:15:24 | 显示全部楼层
他奶奶的,终于搞定了,不容易呀

具体如下:

首先是这个判断需要更改
if (((*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS ) & 0x2FF80000 ) == 0x20000000)

关键就是 0x2FF80000  这个 这个貌似是根据 单片机内部的最大ram计算来的,不同的单片机对应的ram大小也不太,所以此次的值也不相同

我现在使用的 app 是带 rtos 系统的,跳转完全正常,跳转后工作也正常了,折腾好几天了个求

void Jump_To_APP(void)
{
    // 通过判断栈顶地址值是否正确来判断是否已经下载用户应用程序。因为用户程序的启动文件开始会初始化栈空间,如果栈顶地址正确,说明用户程序已经下载
     __ASM("CPSID  I");  

  printf("\\r\\n_______ *** *** Jump to the new program run please ... *** ***_______\\r\\n\\r\\n");

  if (((*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS ) & 0x2FF80000 ) == 0x20000000)
  {
    // 通过判断栈顶地址值是否正确来判断是否已经下载用户应用程序。因为用户程序的启动文件开始会初始化栈空间,如果栈顶地址正确,说明用户程序已经下载
    JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);// 前4字节为中断向量表
    Jump_To_Application = (pFunction) JumpAddress;// 指向用户程序复位函数所在的地址

    // 关闭所有外设中断
    HAL_NVIC_DisableIRQ(ETH_IRQn);
    HAL_NVIC_DisableIRQ(USART1_IRQn); //关闭串口中断
    HAL_NVIC_DisableIRQ(SD_IRQn);
    HAL_NVIC_DisableIRQ(SD_DMAx_Rx_IRQn);
    HAL_NVIC_DisableIRQ(SD_DMAx_Tx_IRQn);
    HAL_NVIC_DisableIRQ(OTG_HS_IRQn);

//   HAL_FLASH_Lock();
    SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk;   // 关闭滴答定时器中断
    SysTick->VAL = 0;
    SysTick->LOAD = 0;

    //  __set_PRIMASK(1);   // 关闭全局中断
    __disable_irq();  //关闭总中断, 在 app 处必须开启
   __disable_fault_irq();//关闭所以缺省中断, 在 app 处必须开启

    {
      uint8_t ii;
       /* Disable all interrupts */
      for(ii=0;ii<8;ii++)
        NVIC->ICER[ii] = NVIC->IABR[ii];

        /*
        Reset of all peripherals  
        这些外设关闭非常重要,否则不能够正常实现程序跳转功能,切记切记
        */
        __APB1_FORCE_RESET();
        __APB1_RELEASE_RESET();
        __APB2_FORCE_RESET();
        __APB2_RELEASE_RESET();

        __AHB1_FORCE_RESET();
        __AHB1_RELEASE_RESET();   

        __AHB2_FORCE_RESET();
        __AHB2_RELEASE_RESET();  

        __AHB3_FORCE_RESET();
        __AHB3_RELEASE_RESET();        

        HAL_RCC_DeInit();   
    }
    __set_PSP(*(volatile uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
    //设置APP程序堆栈指针
    __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);  // 设置用户程序的栈指针
//   __set_CONTROL(0);

    __DSB();     // 2017.12.13 add s
    __ISB();     // 2017.12.13 add s

    Jump_To_Application();  // 执行用户程序
  }
  else
  {
    printf("jump uaer app run error ??\\r\\n");
    for(;;)
    {}

  }
}
回复

使用道具 举报

5

主题

85

回帖

100

积分

初级会员

积分
100
发表于 2018-4-16 11:48:20 | 显示全部楼层
谢谢分享;MARK!
回复

使用道具 举报

5

主题

85

回帖

100

积分

初级会员

积分
100
发表于 2018-4-16 14:26:00 | 显示全部楼层
请问楼主,IAP程序是否使用ucos或者是 rtos 系统进行过实验。
回复

使用道具 举报

610

主题

3063

回帖

4913

积分

至尊会员

积分
4913
 楼主| 发表于 2018-5-16 22:37:28 | 显示全部楼层
lidp000 发表于 2018-4-16 14:26
请问楼主,IAP程序是否使用ucos或者是 rtos 系统进行过实验。

使用ucos 或者 freertos 貌似都基本一样的,我现在使用的就是 FreeRTOS 系统,木有问题
回复

使用道具 举报

27

主题

91

回帖

172

积分

初级会员

积分
172
发表于 2018-8-18 21:18:29 | 显示全部楼层
hpdell 发表于 2017-12-15 20:15
他奶奶的,终于搞定了,不容易呀

具体如下:

...已参考分享...
回复

使用道具 举报

23

主题

211

回帖

280

积分

高级会员

积分
280
发表于 2018-8-23 10:07:25 | 显示全部楼层
感谢lz分享经验!
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-17 17:27 , Processed in 0.277390 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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