我们知道ST推出的Cortex-M3平台STM32内部有两个Flash区域,一是System Flash,ST官方保留的一个区域,用于存放IAP代码。该区域不对用户开放,仅提供UART的通讯接口用于IAP升级;另一个区域是User Flash,这一部分是供用户自由使用的。STM32自带USB 2.0 Device接口,如果需要通过USB接口来实现IAP功能需要如何做呢?这里介绍如何利用ST STM32xx USB Development Kit提供的DFU代码来实现上述功能。我用STM3210EVB来演示这个功能。
下列步骤将介绍如何通过ST官方的USB升级代码实现程序的下载更新的功能(IAP)。
1、打开STM3210B-EVAL demonstration software压缩包,在STM3210B-EVAL demonstration software/Demo/source下打开main.c文件,找到void InterruptConfig(void) 函数
/* Set the Vector Table base address at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
这里我们需要修改代码的中断矢量起始地址,这样做的目的是为了处理IAP代码在Flash存放的区域与Application Code部分的存放空间不会发生地址冲突。这里我们假设IAP存放在User Flash的0x08000000~0x08003FFF区域,Application code存放在User Flash的0x08004000~0x0801FFFF区域。因为Application code的开始地址是由0x08004000开始,这样我们需要为应用代码的中断向量地址做一个重映射。因此我们修改该代码为:
/* Set the Vector Table base address at 0x08004000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);
请注意这里NVIC_SetVectorTable函数的型参送入的是相对偏移地址,而不是绝对地址;
2、在STM3210B-EVAL demonstration software/Demo/project/EWARM下找到lnkarm_flash.xcl文件,在XCL文件中找到下面的配置,该配置用于定制应用代码在Flash区域的存放空间和代码运行是RAM可以提供的空间。
// Code memory in FLASH
-DROMSTART=0x8000000
-DROMEND=0x803FFFF
// Data in RAM
-DRAMSTART=0x20000000
-DRAMEND=0x20004FFF
由于我们的目标应用代码将是在0x08004000区域运行,因此我们修改为:
// Code memory in FLASH
-DROMSTART=0x8004000
-DROMEND=0x801FFFF
// Data in RAM
-DRAMSTART=0x20000000
-DRAMEND=0x20004FFF
在编译的时候请确保Project-》Options-》Linker-》Config标签下的链接命令文件选择的是上述lnkarm_flash.xcl文件;
3、应用部分改好,现在我们修改USB固件升级部分的代码,打开STM32F10xxx USB developer kit开发包。
4、在开发包下面找到 /STM32F10xUSBLib/USBLib/demos/Device_Firmware_Upgrade例程,该例程是一个在STM32F10xx系列MCU上实现运行在User Flash区域的IAP自升级代码,通过STM32自身提供的USB接口实现。在/STM32F10xUSBLib/USBLib/demos/Device_Firmware_Upgrade/source路径下找到main.c文件,在56行:
if (DFU_Button_Read() != 0x00)
{ /* Test if user code is programmed starting from address 0x8003000 */
if (((*(vu32*)0x8003000) & 0x2FFF0000 ) == 0x20000000)
{ /* Jump to user application */
JumpAddress = *(vu32*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application‘s Stack Pointer */
__MSR_MSP(*(vu32*) ApplicationAddress);
Jump_To_Application();
}
} /* Otherwise enters DFU mode to allow user to program his application */
这段代码的功能是对应用部分的代码开始地址做判断,这里的地址与我们之前的步骤1、2都是对应的。
同样这个代码做如下更改:
/* Test if user code is programmed starting from address 0x8004000 */
if (((*(vu32*)0x8004000) & 0x2FFF0000 ) == 0x20000000)
5、hw_config.h中定义:
#define ApplicationAddress 0x08003000
改为
#define ApplicationAddress 0x08004000
编译代码,下载到STM3210 Evaluation Board。
6、在ST的网站中找到USB IAP的PC端用于程序DfuSe USB Device Firmware Upgrade,安装后执行DfuSe Demonstration程序。
CortexM3的中断向量表处理比ARM7方便了很多,它可以设定中断向量表的起始位置,而ARM7如果要实现IAP,则必须用“两级跳”的方式来实现中断处理,即中断到来时先跳到0地址为起始地址的相应中断入口,这个入口实际又是一个跳转,它跳转到RAM中的中断向量表(系统启动后需要注册相关中断向量到此位置),进而进入ISR。所以说CortexM3系统可以有N个中断向量表,只要修改一下起始地址就可以了。
部分回帖
。 ApplicationAddress对应着你的应用程序“stm32f10x_vector.c”这个文件中的__vector_table
*(__IO uint32_t*)ApplicationAddress 与 __vector_table[0]是一样的
*(__IO uint32_t*) (ApplicationAddress + 4) 与 __vector_table[1]是一样的
__vector_table[0]是应用程序栈的顶
__vector_table[1]是应用程序的启动地址
(X & 0x2FFE0000 ) == 0x20000000 意思是说X是不是在0x20000000与0x2001FFFF之间,即栈顶是不是在以0x20000000开始的128K 的范围内,这里便是STM32的RAM区域,虽然现在最大的只有64k。
我们知道ST推出的Cortex-M3平台STM32内部有两个Flash区域,一是System Flash,ST官方保留的一个区域,用于存放IAP代码。该区域不对用户开放,仅提供UART的通讯接口用于IAP升级;另一个区域是User Flash,这一部分是供用户自由使用的。STM32自带USB 2.0 Device接口,如果需要通过USB接口来实现IAP功能需要如何做呢?这里介绍如何利用ST STM32xx USB Development Kit提供的DFU代码来实现上述功能。我用STM3210EVB来演示这个功能。
下列步骤将介绍如何通过ST官方的USB升级代码实现程序的下载更新的功能(IAP)。
1、打开STM3210B-EVAL demonstration software压缩包,在STM3210B-EVAL demonstration software/Demo/source下打开main.c文件,找到void InterruptConfig(void) 函数
/* Set the Vector Table base address at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
这里我们需要修改代码的中断矢量起始地址,这样做的目的是为了处理IAP代码在Flash存放的区域与Application Code部分的存放空间不会发生地址冲突。这里我们假设IAP存放在User Flash的0x08000000~0x08003FFF区域,Application code存放在User Flash的0x08004000~0x0801FFFF区域。因为Application code的开始地址是由0x08004000开始,这样我们需要为应用代码的中断向量地址做一个重映射。因此我们修改该代码为:
/* Set the Vector Table base address at 0x08004000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);
请注意这里NVIC_SetVectorTable函数的型参送入的是相对偏移地址,而不是绝对地址;
2、在STM3210B-EVAL demonstration software/Demo/project/EWARM下找到lnkarm_flash.xcl文件,在XCL文件中找到下面的配置,该配置用于定制应用代码在Flash区域的存放空间和代码运行是RAM可以提供的空间。
// Code memory in FLASH
-DROMSTART=0x8000000
-DROMEND=0x803FFFF
// Data in RAM
-DRAMSTART=0x20000000
-DRAMEND=0x20004FFF
由于我们的目标应用代码将是在0x08004000区域运行,因此我们修改为:
// Code memory in FLASH
-DROMSTART=0x8004000
-DROMEND=0x801FFFF
// Data in RAM
-DRAMSTART=0x20000000
-DRAMEND=0x20004FFF
在编译的时候请确保Project-》Options-》Linker-》Config标签下的链接命令文件选择的是上述lnkarm_flash.xcl文件;
3、应用部分改好,现在我们修改USB固件升级部分的代码,打开STM32F10xxx USB developer kit开发包。
4、在开发包下面找到 /STM32F10xUSBLib/USBLib/demos/Device_Firmware_Upgrade例程,该例程是一个在STM32F10xx系列MCU上实现运行在User Flash区域的IAP自升级代码,通过STM32自身提供的USB接口实现。在/STM32F10xUSBLib/USBLib/demos/Device_Firmware_Upgrade/source路径下找到main.c文件,在56行:
if (DFU_Button_Read() != 0x00)
{ /* Test if user code is programmed starting from address 0x8003000 */
if (((*(vu32*)0x8003000) & 0x2FFF0000 ) == 0x20000000)
{ /* Jump to user application */
JumpAddress = *(vu32*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application‘s Stack Pointer */
__MSR_MSP(*(vu32*) ApplicationAddress);
Jump_To_Application();
}
} /* Otherwise enters DFU mode to allow user to program his application */
这段代码的功能是对应用部分的代码开始地址做判断,这里的地址与我们之前的步骤1、2都是对应的。
同样这个代码做如下更改:
/* Test if user code is programmed starting from address 0x8004000 */
if (((*(vu32*)0x8004000) & 0x2FFF0000 ) == 0x20000000)
5、hw_config.h中定义:
#define ApplicationAddress 0x08003000
改为
#define ApplicationAddress 0x08004000
编译代码,下载到STM3210 Evaluation Board。
6、在ST的网站中找到USB IAP的PC端用于程序DfuSe USB Device Firmware Upgrade,安装后执行DfuSe Demonstration程序。
CortexM3的中断向量表处理比ARM7方便了很多,它可以设定中断向量表的起始位置,而ARM7如果要实现IAP,则必须用“两级跳”的方式来实现中断处理,即中断到来时先跳到0地址为起始地址的相应中断入口,这个入口实际又是一个跳转,它跳转到RAM中的中断向量表(系统启动后需要注册相关中断向量到此位置),进而进入ISR。所以说CortexM3系统可以有N个中断向量表,只要修改一下起始地址就可以了。
部分回帖
。 ApplicationAddress对应着你的应用程序“stm32f10x_vector.c”这个文件中的__vector_table
*(__IO uint32_t*)ApplicationAddress 与 __vector_table[0]是一样的
*(__IO uint32_t*) (ApplicationAddress + 4) 与 __vector_table[1]是一样的
__vector_table[0]是应用程序栈的顶
__vector_table[1]是应用程序的启动地址
(X & 0x2FFE0000 ) == 0x20000000 意思是说X是不是在0x20000000与0x2001FFFF之间,即栈顶是不是在以0x20000000开始的128K 的范围内,这里便是STM32的RAM区域,虽然现在最大的只有64k。
举报