红联Linux门户
Linux帮助

linux下mege88单片机的IAP在应用编程

发布时间:2016-09-11 10:25:06来源:blog.csdn.net/hanglinux作者:hanglinux
通常情况下单片机的烧录都是通过ISP或者串口下载线进行程序的下载升级,mege88支持通过切换到bootloader自行进行升级。
linux下mege88单片机的IAP在应用编程
通过上图可以知道,mega88将Flash存储区分成两块,一块用来存放bootloader,一块用来存放应用程序。当需要升级的时候,通过跳转指令调至bootloader区,串口接受应用程序的二进制文件,写入到应用区,最后跳转到0地址处开始执行应用程序。
所以先编写IAP bootloader程序,然后写一个测试的应用程序,在Linux 下用minicom自带的xmodem传输方式将程序下载到mega88。
 
一、通过Xmodem协议接收应用程序。
mege88设置波特率9600,串口使用xmodem协议收发数据。
协议简单介绍:
Xmodem的控制字符:<soh> 01H、<eot> 04H、<ack> 06H、<nak> 15H、<can> 18H、<eof> 1AH。
Xmodem传输数据块格式:“<soh> <packNO> <255-packNO><…128个字节的数据块…> <cksum>”。
其中<soh>为起始字节;<packNO>为数据块编号字节,每次加一;<255-packNO>是前一字节的反码;
接下来是长度为128字节的数据块;最后的<cksum>是128字节数据的CRC校验码,长度为2个字节。 
接收端收到一个数据块并校验正确时,回送<ack>;接收错误回送<nak>;而回送<can>表示要发送端停止发送。
发送端收到<ack>后,可继续发送下一个数据块(packNO+1);而收到<nak>则可再次重发上一个数据块。
发送端发送<eot>表示全部数据发送完成。如果最后需要发送的数据不足128个字节,用<eof>填满一个数据块。
控制字符“C”有特殊的作用,当发送端收到“C”控制字符时,它会重新开始以CRC校验方式发送数据块(packNO = 1)。
每发送一个新的数据块<packNO>加1,加到OxFF后下一个数据块的<packNO>为零。
校验方式采用16位CRC校验(X^16 + X^12 + X^5 + 1)。
 
二、写入应用程序区
Xmodem一次传送128Byte数据,但是mege88每个页64Byte大小,所以接收一次数据需要写两次才能完成。
linux下mege88单片机的IAP在应用编程
void write_one_page(void)  
{   
int i;   
boot_page_ew(address, 0x03); //擦除一个Flash页   
wait_page_rw_ok(); //等待擦除完成   
for(i = 0;i < SPM_PAGESIZE; i += 2) //将数据填入Flash缓冲页中   
{
boot_page_fill(i, (data[i] + (data[i+1]<<8)));   
}
boot_page_ew(address,0x05); //将缓冲页数据写入一个Flash页   
wait_page_rw_ok(); //等待写入完成  
address += SPM_PAGESIZE; //Flash页加1  
boot_page_ew(address, 0x03);   
wait_page_rw_ok();   
for (i = SPM_PAGESIZE; i < 128; i += 2)   
{  
boot_page_fill(i, (data[i] + (data[i + 1] << 8)));  
}  
boot_page_ew(address, 0x05);    
wait_page_rw_ok();      
address += SPM_PAGESIZE;    
}
 
三、退出bootloader 跳转到应用程序处执行
定义bootloader区大小为1K,应用程序从0x0000地址开始执行。
linux下mege88单片机的IAP在应用编程
void quit(void)  
{   
uart_putchar('O');uart_putchar('K');   
uart_putchar(0x0d);uart_putchar(0x0a);  
while(!(UCSR0A & 0x20)); //等待结束提示信息回送完成   
MCUCR = 0x01;   
MCUCR = 0x00; //将中断向量表迁移到应用程序区头部   
asm("LDI R30,0X00\n"   //LDI 装入立即数  
"LDI R31,0X00\n"     //z寄存器初始化  
"ijmp\n");         //跳转到Flash 0x0000处,执行用户应用程序  
}  
 
四、熔丝编程,烧写程序
设置BOOTRST熔丝位,上电重启从bootloader处开始运行,BOOTSZ1,、BOOTSZ2设置为0,,bootloader区1K大小,应用程序跳转到0x1c00处执行bootloader。
linux下mege88单片机的IAP在应用编程
while(1)   
{   
if(uart_getchar()== 'd') break;   
if(onesecond == 1)  
{  
onesecond = 0;  
my_count++;  
if(my_count == 3)  //延时3s  
{  
my_count = 0;  
quit();  
}  
}  
}
上电后3秒内按下'd' 进入IAP编程,在Linux使用minicom,波特率9600。
将编写好的应用程序通过Hex2bin程序将hex文件转换成二进制。在minicom下依次按ctrl-a-s 选择xmodem传输方式发送应用程序到mega88,自动烧录。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/24068.html