C8051F340 BOOTLOADER 固件升级的的实现过程
实现过程:一:内部flash 的空间划分
0XFFFF 保留区 应用程序区BOOTLOADER可操作区域
0XF000
0X1000
0X1000
0X0000
二:中断向量软件映射
MCU中断向量分布在复位(0x0000)以后,按规则排布,若改变编译器设置,如51,可改变程序在FLASH中的位置,可改变中断向量起始点,如改到这样0X1000,即:就是将0X0000地址内容映射到0X1000,把0X1000作为一个虚拟的复位地址,编译后,中断向量安装在0X1000后。但是,硬件跳转是不能改变的。就是说中断发生后,仍然进入以0X0000为复位地址的向量表。但是,这个向量表中,不再是直接跳转到中断服务程序,而是需要手动跳转到虚拟中断向量表,再由虚拟中断向量表跳转到中断服务程序。但是其原始向量表可能为空,所以需要加入程序判进行手动跳转到新向量表。
所以编译的时候,将APP程序中断向量表虚拟,BOOT程序使用原始的向量表。所以任何时候中断发生后,将执行BOOT中断服务程序。在BOOT中断服务程序中判断当前程序是执行BOOT区还是APP区,如果是执行APP区,就跳转到APP中断服务程序即可(入口向量已经规则地排布在0X1000以后)。
51的中断向量排布规则是:LJMP 3+8*INTERRUPT_VECTOR_NUMBER
图解:
原始地址(向量表)作用描述
0000HRESETPOWER UP ENTRY
0003HINTERRUPT 0入口
000BHINTERRUPT 1入口
0013HINTERRUPT 2入口
………
虚拟后地址(向量表)作用描述
1000H虚拟复位地址
1003HINTERRUPT 0虚拟入口进入中断
100BHINTERRUPT 1虚拟入口进入中断
………
注意:中断向量虚拟后,并不是说发生中断程序就转入虚拟后的向量表。而是:中断向量表的实质是一条跳转指令,跳转到相关ISR,虚拟后,这个跳转指令被放在了新的地址,而不是原始默认地址。所以,需要在原始地址处再放一辅助向量表(中断发生后,硬件挑到此处),用于跳转到新的向量表。这个辅助向量表有BOOT区完成。
1:STARTUP.A51文件设置:
;vector_base EQU 01000h
;vector
CSEG AT 03h
LJMP vect + 03h ;// 0 外部中断0 (/INT0)
;user_address EQU 01000h
user_process:
LJMP vect;user_address
CSEG AT 0bh
LJMP vect + 0bh ;// 1 定时器0溢出
CSEG AT 13h
LJMP vect + 013h ;// 2 外部中断1 (/INT1)
CSEG AT 1bh
LJMP vect + 01bh ;// 3 定时器1溢出
CSEG AT 23h
LJMP vect + 023h ;// 4 UART0
CSEG AT 2bh
LJMP vect + 02bh ;// 5 定时器2溢出
CSEG AT 33h
LJMP vect + 033h ;// 6 SPI0
CSEG AT 3bh
LJMP vect + 03bh ;// 7 SMB0
CSEG AT 43h
LJMP vect + 043h ;// 8 USB0
CSEG AT 4bh
LJMP vect + 04bh ;// 9 ADC0窗口比较
CSEG AT 53h
LJMP vect + 053h ;// 10 ADC0转换结束
CSEG AT 5bh
LJMP vect + 05bh ;// 11 可编程计数器阵列
CSEG AT 63h
LJMP vect + 063h ;// 12 比较器0
CSEG AT 6bh
LJMP vect + 06bh ;// 13 比较器1
CSEG AT 73h
LJMP vect + 073h ;// 14 定时器3溢出
CSEG AT 7bh
LJMP vect + 07bh ;// 15 VBUS电平
CSEG AT 83h
LJMP vect + 083h ;// 16 UART1
CSEG AT 000h
?C_STARTUP: LJMP STARTUP1
2:应用程序区工程设置:
3:bootloader程序和 APP 应用程序的初始化时钟必须是一致的, 否则容易造成死机的现象
三:BOOTLOADER 程序
1:主程序的编写
main(void)
{
uint8 uartRX;
uint16 timeout;
void (*boot)( void);
Sys_Clk_Init();// 初始化设备
PORT_Init();
UART0_Init();
FLSCL = 0x86;
if (1) {
Uart_Print("\n");
Uart_Print("**************BootLoader v1.0***************\n");
Uart_Print(">Please press 's' to start programming.\n");
while (1)
{
for(timeout=0;timeout<4000;timeout++)
{
if(RI0)
{
uartRX=SBUF0;
RI0=0;
break;
}
delay_ms(10);
}
if (uartRX=='s')
{RTload();
uartRX = 0;
}
else if(vect == 0x02)
{
goto USE_CODE;
}
}
}
USE_CODE:
user_process();
while(1)
{
}
2:片内FLASH的 操作
unsigned char FLASH_ByteRead (FLADDR addr)
{
bit EA_SAVE = EA;
char code * data pread;
unsigned char byte;
EA = 0;
pread = (char code *) addr;
byte = *pread;
EA = EA_SAVE;
return byte;
}
void FLASH_ByteWrite (FLADDR addr, char byte)
{
bit EA_SAVE = EA;
char xdata * data pwrite;
EA = 0;
pwrite = (char xdata *) addr;
PFE0CN = PFE0CN & 0xFE;
PSCTL= 0x01;
FLKEY= 0xA5;
FLKEY= 0xF1;
*pwrite = byte;
PSCTL = 0;
EA = EA_SAVE;
}
void FLASH_PageErase (FLADDR addr)
{
bit EA_SAVE = EA;
char xdata * data pwrite;
EA = 0;
pwrite = (char xdata *) addr;
FLKEY= 0xA5;
FLKEY= 0xF1;
PSCTL= 0x03;
*pwrite = 0;
PSCTL = 0;
EA = EA_SAVE;
}
可以正常使用串口更新程序, 有需要的, 可以给我留言,一起起步!
总感觉固件在线升级很神秘,没弄过! 说通俗点就是自编程
很好!很强大! 借用别个的,风光一下自己,写好自己的在放上来,风光风光 2:应用程序区工程设置:
这个设置能不能分享一下了,谢谢! DYS 发表于 2014-6-16 15:05 static/image/common/back.gif
2:应用程序区工程设置:
这个设置能不能分享一下了,谢谢!
这个就是跳转偏移而已,自己多看看上面的代码就明白了 不错的资料,支持中。。。
不错的资料,支持中。。。 C8051F好像见到的很少了,是不是被32 排挤的?
页:
[1]