美文网首页
stm32f4 boot 跳转

stm32f4 boot 跳转

作者: 嵌入式工作 | 来源:发表于2018-09-10 18:17 被阅读0次

作者: **lison0103 **时间: **2015-12-7 17:07 关于FreeRTOS使用IAP跳转

1裸机跳转

之前做了一个IAP程序,bootloader使用裸机,APP使用ucos2系统,IAP可以互相跳转
程序如下:

void iap_load_app(u32 appxaddr)
{
  if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)                           //检查栈顶地址是否合法.
  { 
                 jump2app=(iapfun)*(vu32*)(appxaddr+4);                         //用户代码区第二个字为程序开始地址(复位地址) 
                __set_PSP(*(volatile unsigned int*) appxaddr);                  //重新设置进程PSP堆栈地址
                __set_CONTROL(0);                                                           //设置为MSP
                __set_MSP(*(volatile unsigned int*) appxaddr);                  //重新设置进程MSP堆栈地址
                jump2app();  //跳转到APP.
  }
}

2 FreeRTOS跳转

现在学习FreeRTOS,就把bootloader程序改为了FreeRTOS,但是在jump2app()跳转的时候进入到了HardFault_Handler 尝试在设置堆栈和跳转前,关闭调度器vPortEndScheduler()和挂起调度vTaskSuspendAll()都没有效果。
然后又尝试把所有任务都注释掉,就添加一个任务,就是跳转,然后启用调度,也是不行。
不打开任务和调度,就可以跳转。

感觉是堆栈没设置好,不知道各位有没有试过在FreeRTOS程序跳转或有什么思路?
谢谢!

 * File      : rbl_jump_stm32f2_f4.c.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2014-03-12     aozima       first version.
 * 2015-09-22     aozima       disable and clean up all interrupts.
 */

#include <stdint.h>

#include <board.h>

void jump_to_app(uint32_t app_address)
{
    typedef void (*_func)(void);

    __disable_irq();

    /* MCU peripherals re-initial. */
    {
        GPIO_InitTypeDef GPIO_InitStruct;

        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IN;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
        GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_NOPULL;

        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All;
        GPIO_InitStruct.GPIO_Pin &= ~(GPIO_Pin_13 | GPIO_Pin_14); /* SWDIO/SWCLK */
        GPIO_Init(GPIOA, &GPIO_InitStruct);

        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All;
        GPIO_Init(GPIOB, &GPIO_InitStruct);
        GPIO_Init(GPIOC, &GPIO_InitStruct);
        GPIO_Init(GPIOD, &GPIO_InitStruct);
        GPIO_Init(GPIOE, &GPIO_InitStruct);
        GPIO_Init(GPIOF, &GPIO_InitStruct);
        GPIO_Init(GPIOG, &GPIO_InitStruct);
        GPIO_Init(GPIOH, &GPIO_InitStruct);
        GPIO_Init(GPIOI, &GPIO_InitStruct);

        /* reset systick */
        SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;

        /* disable all peripherals clock. */
        RCC->AHB1ENR = (1<<20); /* 20: F4 CCMDAT ARAMEN. */
        RCC->AHB2ENR = 0;
        RCC->AHB3ENR = 0;
        RCC->APB1ENR = 0;
        RCC->APB2ENR = 0;

        /* Switch to default cpu clock. */
        RCC->CFGR = 0;
    } /* MCU peripherals re-initial. */

    /* Disable MPU */
    MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;

    /* disable and clean up all interrupts. */
    {
        int i;

        for(i = 0; i < 8; i++)
        {
            /* disable interrupts. */
            NVIC->ICER *= 0xFFFFFFFF;

            /* clean up interrupts flags. */
            NVIC->ICPR *= 0xFFFFFFFF;
        }
    }

    /* Set new vector table pointer */
    SCB->VTOR = app_address;

    /* reset register values */
    __set_BASEPRI(0);
    __set_FAULTMASK(0);

    /* set up MSP and switch to it */
    __set_MSP(*(uint32_t*)app_address);
    __set_PSP(*(uint32_t*)app_address);
    __set_CONTROL(0);

    /* ensure what we have done could take effect */
    __ISB();

    __disable_irq();

    /* never return */
    ((_func)(*(uint32_t*)(app_address + 4)))();
}

rbl_jump_stm32f2_f4.c

3相关评论

1

谢谢!
刚才自己调试解决了,在跳转前加一句关闭所有中断就可以了
看到你的程序也是有关闭中断的语句
之前裸机和ucos2都不用也没问题,看来是原来的程序还不够完善

2

**作者: **ofourme **时间: **2015-12-7 17:30
用jtag仿真看看?然后,你那个栈顶地址检查不合法的,至少应该给个死循环吧?

3

**作者: **FreeRTOS **时间: **2015-12-7 19:49
我公司的项目也是用FreeRTOS,前段时间也弄完了IAP在线升级,没发现你所说的问题,我用的单片机是STM32F051,IAP过程比103的复杂一些,需要手动拷贝向量表到SRAM的起始地址并作映射,但这些问题都解决了,祝你好运!

相关文章

网友评论

      本文标题:stm32f4 boot 跳转

      本文链接:https://www.haomeiwen.com/subject/mrqegftx.html