AT90CAN32 跳转到BOOTLOADER

来源:互联网 发布:淘宝网化妆品货到付款 编辑:程序博客网 时间:2024/05/22 06:44

为了程序方便升级,在单片机程序中使用了BOOTLOADER,主程序收到升级指令,将会跳转到BOOTLOADER

跳转代码如下:

#define CALL_FUNC(pfun)       (*((void(*)(void))(pfun)))()

CALL_FUNC(boot_start);

在程序小于16K时跳转正常,在程序大于16K时,不能跳转

万恶的防火墙google不能上,一阵狂搜

Here's something more like what I do-#include //---------------------------------------//bootloader//---------------------------------------uint8_t func1(void){    return PINB;}void func2(uint8_t val){    PORTB=val;}//func table in bootloader//-mmcu=atmega8 -Wl,-section-start=.func_table=0x1ffc//void jump_table(void) __attribute__((naked,section(".func_table")));void jump_table(void){    asm("rjmp func2"); //&__vectors-4    asm("rjmp func1"); //&__vectors-2}//---------------------------------------//app//---------------------------------------extern void* __vectors;#define FUNC1       ( (uint8_t(*)(void)) &__vectors-2 )#define FUNC2(val)  ( (void(*)(uint8_t)) &__vectors-4 )(val)int main (){    PORTC=FUNC1();    FUNC2(0xFF);} The rjmp table is fine for any bootloader (for bootloaders 4kb or less anyway), the function defines for 8kb or less avrs needs a known reference address. Can't use 'raw' numbers, as they will be relative to the section the code is in (16kb or larger it works because those call instructions are not relative, but absolute). So __vectors is used since it is already a global function created by the c runtime startup code (and is normally at 0x0000, unless its the bootloader).For some reason, to me it seems like a waste to use 'normal' function pointers (use ram).exhibit a- http://www.mtcnet.net/~henryvm/AvrAscii/index_old.htmlexhibit b- http://www.mtcnet.net/~henryvm/AvrAscii/index.html

Try this... This works in my AT90USB1287 :)   VOIDFUNC Start_Bootloader(void){    UDCON = 1;USBCON = (1<<FRZCLK);  // disable USBUCSR1B = 0;EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;    //disable A/D converterTIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; TWCR = 0;         //disable timersDDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;     //disable I/O pin driversPORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; asm("jmp 0x1E000"); //jump to boot loader   //word address = 0xF000    //byte address = 2*word address = 0x1E000                    //here we use byte address for the jump    }
经过尝试asm("jmp boot_start");一条语句搞定

希望给以后遇到问题的友友借鉴

摸索的过程是痛苦的,但是结果是喜悦的。


0 0
原创粉丝点击