作者: **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)))();
}
3相关评论
1
谢谢!
刚才自己调试解决了,在跳转前加一句关闭所有中断就可以了
看到你的程序也是有关闭中断的语句
之前裸机和ucos2都不用也没问题,看来是原来的程序还不够完善
2
**作者: **ofourme **时间: **2015-12-7 17:30
用jtag仿真看看?然后,你那个栈顶地址检查不合法的,至少应该给个死循环吧?
3
**作者: **FreeRTOS **时间: **2015-12-7 19:49
我公司的项目也是用FreeRTOS,前段时间也弄完了IAP在线升级,没发现你所说的问题,我用的单片机是STM32F051,IAP过程比103的复杂一些,需要手动拷贝向量表到SRAM的起始地址并作映射,但这些问题都解决了,祝你好运!
网友评论