📄 avr-bootloader.lst
字号:
__start:
__text_start:
FC68 E001 LDI R16,1
FC69 BF05 OUT 0x35,R16
FC6A E002 LDI R16,2
FC6B BF05 OUT 0x35,R16
FC6C EFCF LDI R28,0xFF
FC6D E1D0 LDI R29,0x10
FC6E BFCD OUT 0x3D,R28
FC6F BFDE OUT 0x3E,R29
FC70 51CE SUBI R28,0x1E
FC71 40D0 SBCI R29,0
FC72 EA0A LDI R16,0xAA
FC73 8308 STD Y+0,R16
FC74 2400 CLR R0
FC75 E0E4 LDI R30,4
FC76 E0F1 LDI R31,1
FC77 E012 LDI R17,2
FC78 30E4 CPI R30,4
FC79 07F1 CPC R31,R17
FC7A F011 BEQ 0xFC7D
FC7B 9201 ST R0,Z+
FC7C CFFB RJMP 0xFC78
FC7D 8300 STD Z+0,R16
FC7E ECEC LDI R30,0xCC
FC7F EFF8 LDI R31,0xF8
FC80 E0A0 LDI R26,0
FC81 E0B1 LDI R27,1
FC82 EF18 LDI R17,0xF8
FC83 E001 LDI R16,1
FC84 BF0B OUT 0x3B,R16
FC85 3DE0 CPI R30,0xD0
FC86 07F1 CPC R31,R17
FC87 F021 BEQ 0xFC8C
FC88 95D8 ELPM
FC89 9631 ADIW R30,1
FC8A 920D ST R0,X+
FC8B CFF9 RJMP 0xFC85
FC8C 940E FD63 CALL _main
_exit:
FC8E CFFF RJMP _exit
_boot_page_ew:
code --> Y,+4
p_address --> Y,+0
FC8F 940E FE33 CALL push_arg4
FILE: E:\项目\程序\Bootloader程序\AVR-Bootloader\AVR-Bootloader.c
(0001) #include <iom128v.h>
(0002) #define SPM_PAGESIZE 256
(0003)
(0004) #define BAUD_H 0x00
(0005) #define BAUD_L 0x17
(0006) #define DATA_BUFFER_SIZE SPM_PAGESIZE
(0007)
(0008) //定义Xmodem控制字符
(0009) #define XMODEM_NUL 0x00
(0010) #define XMODEM_SOH 0x01
(0011) #define XMODEM_STX 0x02
(0012) #define XMODEM_EOT 0x04
(0013) #define XMODEM_ACK 0x06
(0014) #define XMODEM_NAK 0x15
(0015) #define XMODEM_CAN 0x18
(0016) #define XMODEM_EOF 0x1A
(0017) #define XMODEM_RECIEVING_WAIT_CHAR 'C'
(0018)
(0019) //定义全局变量
(0020) //const char startupString[]="Type 'd' download,Others run app.\n\r\0";
(0021) const char startupString[]="Please press 'd' to bootloader within 3 seconds![Encrypted!]\n\r\0";
(0022) char data[DATA_BUFFER_SIZE];
(0023) long address=0;
(0024)
(0025) //擦除(code==0x03)和写入(code==0x05)一个Flash页
(0026) void boot_page_ew(long p_address,char code)
(0027) {
(0028) asm("mov r30,r16\n"
FC91 2FE0 MOV R30,R16
FC92 2FF1 MOV R31,R17
FC93 BF2B OUT 0x3B,R18
(0029) "mov r31,r17\n"
(0030) "out 0x3b,r18\n");
(0031) SPMCSR=code;
FC94 800C LDD R0,Y+4
FC95 9200 0068 STS 0x0068,R0
(0032) asm("spm\n");
FC97 95E8 SPM
FC98 9624 ADIW R28,4
FC99 9508 RET
_boot_page_fill:
data --> Y,+2
address --> Y,+0
FC9A 940E FE33 CALL push_arg4
(0033) }
(0034) //填充Flash缓冲页中的一个字
(0035) void boot_page_fill(unsigned int address,int data)
(0036) {
(0037) asm("mov r30,r16\n"
FC9C 2FE0 MOV R30,R16
FC9D 2FF1 MOV R31,R17
FC9E 2E02 MOV R0,R18
FC9F 2E13 MOV R1,R19
(0038) "mov r31,r17\n"
(0039) "mov r0,r18\n"
(0040) "mov r1,r19\n");
(0041) SPMCSR=0x01;
FCA0 E081 LDI R24,1
FCA1 9380 0068 STS 0x0068,R24
(0042) asm("spm\n");
FCA3 95E8 SPM
FCA4 9624 ADIW R28,4
FCA5 9508 RET
(0043) }
(0044) //等待一个Flash页的写完成
(0045) void wait_page_rw_ok(void)
(0046) {
_wait_page_rw_ok:
FCA6 C008 RJMP 0xFCAF
(0047) while(SPMCSR&0x40)
(0048) {
(0049) while(SPMCSR&0x01);
FCA7 9020 0068 LDS R2,0x0068
FCA9 FC20 SBRC R2,0
FCAA CFFC RJMP 0xFCA7
(0050) SPMCSR=0x11;
FCAB E181 LDI R24,0x11
FCAC 9380 0068 STS 0x0068,R24
(0051) asm("spm\n");
FCAE 95E8 SPM
FCAF 9020 0068 LDS R2,0x0068
FCB1 FC26 SBRC R2,6
FCB2 CFF4 RJMP 0xFCA7
FCB3 9508 RET
_de_encryptdata:
tmpchrL --> R10
tmpchrH --> R22
chr --> R20
i --> R16
FCB4 940E FE42 CALL push_xgsetF00C
(0052) }
(0053) }
(0054) ///对BIN文件的数据进行解密
(0055) char de_encryptdata(char i)
(0056) {
(0057) char chr,tmpchrH,tmpchrL;
(0058) chr=data[i];
FCB6 E084 LDI R24,4
FCB7 E091 LDI R25,1
FCB8 2FE0 MOV R30,R16
FCB9 27FF CLR R31
FCBA 0FE8 ADD R30,R24
FCBB 1FF9 ADC R31,R25
FCBC 8140 LDD R20,Z+0
(0059) tmpchrH=0xf0&chr;
FCBD 2F64 MOV R22,R20
FCBE 7F60 ANDI R22,0xF0
(0060) tmpchrL=0x0f&chr;
FCBF 2F84 MOV R24,R20
FCC0 708F ANDI R24,0xF
FCC1 2EA8 MOV R10,R24
(0061) chr=tmpchrH/16+tmpchrL*16;
FCC2 E180 LDI R24,0x10
FCC3 9D8A MUL R24,R10
FCC4 2F46 MOV R20,R22
FCC5 9542 SWAP R20
FCC6 704F ANDI R20,0xF
FCC7 0D40 ADD R20,R0
(0062) return (0xff-0x86^chr);
FCC8 E789 LDI R24,0x79
FCC9 2F04 MOV R16,R20
FCCA 2708 EOR R16,R24
FCCB 940C FE49 JMP pop_xgsetF00C
_write_one_page:
i --> R20
FCCD 934A ST R20,-Y
FCCE 935A ST R21,-Y
FCCF 9721 SBIW R28,1
(0063) }
(0064) //更新一个Flash页的完整处理
(0065) void write_one_page(void)
(0066) {
(0067) int i;
(0068) boot_page_ew(address,0x03);
FCD0 E083 LDI R24,3
FCD1 8388 STD Y+0,R24
FCD2 9120 0102 LDS R18,address+2
FCD4 9130 0103 LDS R19,address+3
FCD6 9100 0100 LDS R16,address
FCD8 9110 0101 LDS R17,address+1
FCDA DFB4 RCALL _boot_page_ew
(0069) wait_page_rw_ok();
FCDB DFCA RCALL _wait_page_rw_ok
(0070) for(i=0;i<SPM_PAGESIZE;i+=2)
FCDC 2744 CLR R20
FCDD 2755 CLR R21
(0071) {
(0072) boot_page_fill(i,de_encryptdata(i)+(de_encryptdata(i+1)<<8));
FCDE 2F04 MOV R16,R20
FCDF DFD4 RCALL _de_encryptdata
FCE0 2E40 MOV R4,R16
FCE1 2F04 MOV R16,R20
FCE2 5F0F SUBI R16,0xFF
FCE3 4F1F SBCI R17,0xFF
FCE4 924F PUSH R4
FCE5 DFCE RCALL _de_encryptdata
FCE6 904F POP R4
FCE7 2E20 MOV R2,R16
FCE8 2433 CLR R3
FCE9 2C32 MOV R3,R2
FCEA 2422 CLR R2
FCEB 2D24 MOV R18,R4
FCEC 2733 CLR R19
FCED 0D22 ADD R18,R2
FCEE 1D33 ADC R19,R3
FCEF 018A MOVW R16,R20
FCF0 DFA9 RCALL _boot_page_fill
FCF1 5F4E SUBI R20,0xFE
FCF2 4F5F SBCI R21,0xFF
FCF3 3040 CPI R20,0
FCF4 E0E1 LDI R30,1
FCF5 075E CPC R21,R30
FCF6 F33C BLT 0xFCDE
(0073) }
(0074) boot_page_ew(address,0x05);
FCF7 E085 LDI R24,5
FCF8 8388 STD Y+0,R24
FCF9 9120 0102 LDS R18,address+2
FCFB 9130 0103 LDS R19,address+3
FCFD 9100 0100 LDS R16,address
FCFF 9110 0101 LDS R17,address+1
FD01 DF8D RCALL _boot_page_ew
(0075) wait_page_rw_ok();
FD02 DFA3 RCALL _wait_page_rw_ok
FD03 9621 ADIW R28,1
FD04 9159 LD R21,Y+
FD05 9149 LD R20,Y+
FD06 9508 RET
(0076) }
(0077) //从RS232发送1个字节
(0078) void uart_putchar(char c)
(0079) {
(0080) while(!(UCSR0A&0x20));
_uart_putchar:
c --> R16
FD07 9B5D SBIS 0x0B,5
FD08 CFFE RJMP _uart_putchar
(0081) UDR0=c;
FD09 B90C OUT 0x0C,R16
FD0A 9508 RET
(0082) }
(0083) //从RS232接收1个字节
(0084) int uart_getchar(void)
(0085) {
(0086) unsigned char status,res;
(0087) if(!(UCSR0A&0x80)) return -1;
_uart_getchar:
status --> R18
res --> R16
FD0B 995F SBIC 0x0B,7
FD0C C003 RJMP 0xFD10
FD0D EF0F LDI R16,0xFF
FD0E EF1F LDI R17,0xFF
FD0F C009 RJMP 0xFD19
(0088) status=UCSR0A;
FD10 B12B IN R18,0x0B
(0089) res=UDR0;
FD11 B10C IN R16,0x0C
(0090) res=res;
(0091) if(status&0x1c) return -1;
FD12 2F82 MOV R24,R18
FD13 718C ANDI R24,0x1C
FD14 F019 BEQ 0xFD18
FD15 EF0F LDI R16,0xFF
FD16 EF1F LDI R17,0xFF
FD17 C001 RJMP 0xFD19
(0092) return res;
FD18 2711 CLR R17
FD19 9508 RET
_uart_waitchar:
c --> R10
FD1A 92AA ST R10,-Y
FD1B 92BA ST R11,-Y
(0093) }
(0094) //等待从RS232接收1个有效字节
(0095) char uart_waitchar(void)
(0096) {
(0097) int c;
(0098) while((c=uart_getchar())==-1);
FD1C DFEE RCALL _uart_getchar
FD1D 0158 MOVW R10,R16
FD1E 3F0F CPI R16,0xFF
FD1F EFEF LDI R30,0xFF
FD20 071E CPC R17,R30
FD21 F3D1 BEQ 0xFD1C
(0099) return (char)c;
FD22 90B9 LD R11,Y+
FD23 90A9 LD R10,Y+
FD24 9508 RET
_calcrc:
i --> R20
crc --> R10
count --> R18
ptr --> R16
FD25 940E FE38 CALL push_xgset300C
(0100) }
(0101) //计算CRC
(0102) int calcrc(char *ptr,int count)
(0103) {
(0104) int crc=0;
FD27 24AA CLR R10
FD28 24BB CLR R11
FD29 C01B RJMP 0xFD45
(0105) char i;
(0106) while(--count>=0)
(0107) {
(0108) crc=crc^(int)*ptr++<<8;
FD2A 01F8 MOVW R30,R16
FD2B 9021 LD R2,Z+
FD2C 018F MOVW R16,R30
FD2D 2433 CLR R3
FD2E 2C32 MOV R3,R2
FD2F 2422 CLR R2
FD30 24A2 EOR R10,R2
FD31 24B3 EOR R11,R3
(0109) i=8;
FD32 E048 LDI R20,0x8
(0110) do
(0111) {
(0112) if(crc&0x8000)
FD33 FEB7 SBRS R11,7
FD34 C009 RJMP 0xFD3E
(0113) crc=crc<<1^0x1021;
FD35 E281 LDI R24,0x21
FD36 E190 LDI R25,0x10
FD37 0115 MOVW R2,R10
FD38 0C22 LSL R2
FD39 1C33 ROL R3
FD3A 2628 EOR R2,R24
FD3B 2639 EOR R3,R25
FD3C 0151 MOVW R10,R2
FD3D C002 RJMP 0xFD40
(0114) else
(0115) crc=crc<<1;
FD3E 0CAA LSL R10
FD3F 1CBB ROL R11
(0116) }
(0117) while(--i);
FD40 2F84 MOV R24,R20
FD41 5081 SUBI R24,1
FD42 2F48 MOV R20,R24
FD43 2344 TST R20
FD44 F771 BNE 0xFD33
FD45 01C9 MOVW R24,R18
FD46 9701 SBIW R24,1
FD47 019C MOVW R18,R24
FD48 3020 CPI R18,0
FD49 E0E0 LDI R30,0
FD4A 073E CPC R19,R30
FD4B F6F4 BGE 0xFD2A
(0118) }
(0119) return (crc);
FD4C 0185 MOVW R16,R10
FD4D 940C FE3D JMP pop_xgset300C
(0120) }
(0121) //退出Bootloader程序,从0x0000处执行应用程序
(0122) void quit(void)
(0123) {
(0124) uart_putchar('O');uart_putchar('K');uart_putchar('?');
_quit:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -