AT90CAN32 跳转到BOOTLOADER

为了程序方便升级,在单片机程序中使用了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.html
exhibit 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 USB
UCSR1B = 0;

EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;    //disable A/D converter
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; TWCR = 0;         //disable timers
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;     //disable I/O pin drivers
PORTA = 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值