搜索
bottom↓
回复: 13

(求助超级高手)mega48的BOOT loader程序的问题

[复制链接]

出0入0汤圆

发表于 2007-4-9 16:56:26 | 显示全部楼层 |阅读模式
小弟这几天在用mega48做IAP,mega48本是不支持BOOT功能的;

用软件的方法实现BOOT区的划分(0x0B00开始为BOOT区)

APP程序(转为BIN格式)利用UART可以下载成功,但是程序却不能跳进APP程序区,还一直在执行BOOT区程序。

请高手帮帮忙啊!      



(ICC AVR中project->option->Target->other option设置为-bmy_text:0x0b00)



程序如下:

#include <iom48v.h>

#include <string.h>

#include <macros.h>



#define SPM_PAGESIZE 64              //M48的一个Flash页为64字节(32字)

#define BAUD 9600                //波特率采用9600bps

#define CRYSTAL 1000000            //系统时钟1MHz

//计算和定义M128的波特率设置参数



#define BAUD_H 0x00

#define BAUD_L 0x06



#define DATA_BUFFER_SIZE 128                 //定义接收缓冲区长度

//定义Xmoden控制字符

#define XMODEM_NUL 0x00

#define XMODEM_SOH 0x01

#define XMODEM_STX 0x02

#define XMODEM_EOT 0x04

#define XMODEM_ACK 0x06

#define XMODEM_NAK 0x15

#define XMODEM_CAN 0x18

#define XMODEM_EOF 0x1A

#define XMODEM_RECIEVING_WAIT_CHAR 'C'  



//主程序

#pragma text:my_text

//定义全局变量

char data[DATA_BUFFER_SIZE];

long address=0;



//擦除(code=0x03)和写入(code=0x05)一个Flash页



void boot_page_ew(long p_address,char code)

{

    asm("mov r30,r16
"

        "mov r31,r17
");        //将页地址放入Z寄存器和RAMPZ的Bit0中

    SPMCSR=code;                //寄存器SPMCSR中为操作码

    asm("spm
");                   //对指定Flash页进行操作



}         



//填充Flash缓冲页中的一个字

void boot_page_fill(unsigned int address,int data)

{

    asm("mov r30,r16
"

        "mov r31,r17
"             //Z寄存器中为填冲页内地址

        "mov r0,r18
"

        "mov r1,r19
");            //R0R1中为一个指令字

    SPMCSR=0x01;        

    asm("spm
");

}



void wait_page()                   //等待Flash写完

{

    while(SPMCSR&0X01);  

        SPMCSR=0X11;

        asm("spm
");

        while(SPMCSR&0X01);

}       

//更新一个Flash页的完整处理

void write_two_page(void)

{

    unsigned char i;

    boot_page_ew(address,0x03);   

        wait_page();

        boot_page_ew((address+SPM_PAGESIZE),0x03);           //擦除两个Flash页

    wait_page();                                      //等待擦除完成

    for(i=0;i<SPM_PAGESIZE;i+=2)                         //将数据填入Flash缓冲页中

     {

        boot_page_fill(i,data+(data[i+1]<<8));

     }

    boot_page_ew(address,0x05);                        //将缓冲页数据写入一个Flash页

        wait_page();

    for(i=0;i<SPM_PAGESIZE;i+=2)                         //将数据填入Flash缓冲页中

      {

        boot_page_fill(i,data[64+i]+(data[i+65]<<8));

      }      

        boot_page_ew((address+SPM_PAGESIZE),0X05);       //将缓冲页数据写入一个Flash页

    wait_page();                                  //等待写入完成

}  

      

//从RS232发送一个字节

void uart_putchar(char c)

{

    while(!(UCSR0A&0x20));

    UDR0=c;

}



//从RS232接收一个字节

int uart_getchar(void)

{

    unsigned char status,res;

    if(!(UCSR0A&0x80))return -1;        //no data to be received

    status=UCSR0A;

    res=UDR0;

    if (status&0x1c)return -1;        // If error, return -1

    return res;

}



//等待从RS232接收一个有效的字节

char uart_waitchar(void)

{

    int c;

    while((c=uart_getchar())==-1);

    return (char)c;

}



//计算CRC



int calcrc(char *ptr,int count)

{

    int crc=0;

    char i;

     

    while(--count>=0)

    {

        crc=crc^(int)*ptr++<<8;

        i=8;

        do

        {

        if(crc&0x8000)

            crc=crc<<1^0x1021;

        else

            crc=crc<<1;

        }while(--i);

    }

    return(crc);

}

void quit(void)

{

     uart_putchar('O');uart_putchar('K');

     uart_putchar(0x0d);uart_putchar(0x0a);

     while(!(UCSR0A&0x20));            //等待结束提示信息回送完成

                  

     asm("ldi r30,00
"

             "ldi r31,00
"

             "ijmp
");                //跳转到Flash的0x0000处,执行用户的应用程序

}

//退出Bootloader程序,从0x0000处执行应用程序





void main()

{

    unsigned char t=0;

    unsigned char b=0;

    unsigned char i=0;

    unsigned char timercount=0;

    unsigned char packNO=1;

    int bufferPoint=0;

    unsigned int crc;

        char startupString[]="Type'd'download,OR run app.
\r\0";

//初始化M128的USART0

    UBRR0H=BAUD_H;     

    UBRR0L=BAUD_L;            //Set baud rate

    UCSR0B=0x18;            //Enable Receiver and Transmitter

    UCSR0C=0x0E;            //Set frame format: 8data, 2stop bit



  DDRB=0xff;

  PORTB=0xff;

  

//向PC机发送开始提示信息

   while(startupString!='\0')

   {

     uart_putchar(startupString);

         i++;

    }

       

//3秒种等待PC下发“d”,否则退出Bootloader程序,从0x0064处执行应用程序

    while(1)

    {

        if(uart_getchar()=='d')break;

        for(t=0;t<255;t++); //if(TIFR0&0x02)                        //timer0 over flow

            t=0;

            if (++timercount>200)

                        {

                        timercount=0;

                        quit();

                        }                   //200*15ms = 3s

          //  TIFR0=TIFR0|0x02;

        

    }

    //每秒向PC机发送一个控制字符“C”,等待控制字〈soh〉

    while(uart_getchar()!=XMODEM_SOH)        //receive the start of Xmodem

    {

       for(t=0;t<255;t++); // if(TIFR0&0x02)                    //timer0 over flow

       t=0;

            

            if(++timercount>67)                        //wait about 1 second

            {

                uart_putchar(XMODEM_RECIEVING_WAIT_CHAR);    //send a "C"

                timercount=0;

            }

          //  TIFR0=TIFR0|0x02;

      

    }

    //开始接收数据块

    do

    {

       if((packNO==uart_waitchar())&&(packNO==(~uart_waitchar())))

          

               //核对数据块编号正确                        

       {

                  for(b=1;b<100;b++);

                  b=0;

              for(i=0;i<128;i++)                //接收128个字节数据

            {

                data[bufferPoint]=uart_waitchar();

                bufferPoint++;     

            }

            crc=(uart_waitchar()<<8);

            crc+=uart_waitchar();            //接收2个字节的CRC效验字

            if(calcrc(&data[bufferPoint-128],128)==crc)    //CRC校验验证

              {    //正确接收128个字节数据

               

                    write_two_page();            //收到128字节写入两页Flash中

                    address+=2*SPM_PAGESIZE;    //Flash页加2

                    bufferPoint=0;

                  

                uart_putchar(XMODEM_ACK);        //正确收到一个数据块

                packNO++;                        //数据块编号加1

              }

             else

              {

                uart_putchar(XMODEM_NAK);        //要求重发数据块

              }

        }

        else

        {

            uart_putchar(XMODEM_NAK);                //要求重发数据块

        }   

    }while(uart_waitchar()!=XMODEM_EOT);                //循环接收,直到全部发完

   

        uart_putchar(XMODEM_ACK);                        //通知PC机全部收到

     

    if(bufferPoint)write_two_page();                //把剩余的数据写入Flash中

    quit();                          //退出Bootloader程序,从0x0000处执行应用程序

}



#pragma text:text

-----此内容被zywang33于2007-04-09,17:03:04编辑过


-----此内容被zywang33于2007-04-09,17:52:26编辑过

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2007-4-9 17:09:23 | 显示全部楼层
asm("jmp 0x0000
");               //跳转到Flash的0x0000处,执行用户的应用程序

好象这句有问题.

ijmp
");                //跳转到Flash的0x0000处,执行用户的应用程序

出0入0汤圆

 楼主| 发表于 2007-4-9 17:16:40 | 显示全部楼层
不是这个问题



本来设想是,APP程序下载完后,重启,程序应当从0000处开始执行(此时0000—0aff程序已经更新为APP程序)。但是,还是会跳到BOOT区执行loader程序。

出0入0汤圆

发表于 2007-4-9 17:26:01 | 显示全部楼层
void quit(void)

{

     uart_putchar('O');uart_putchar('K');

     uart_putchar(0x0d);uart_putchar(0x0a);

     while(!(UCSR1A & 0x20));            //等待结束提示信息回送完成

     MCUCR = 0x01;

     MCUCR = 0x00;                    //将中断向量表迁移到应用程序区头部

     RAMPZ = 0x00;                    //RAMPZ清零初始化

     asm("jmp 0x0000
");               //跳转到Flash的0x0000处,执行用户的应用程序

         //Message(0x60,0x01);      // 回答ARM,表示电源板运行正常

}

出0入0汤圆

 楼主| 发表于 2007-4-9 17:34:53 | 显示全部楼层
mega48中实际上并没有BOOT区

所以中断向量不能迁移吧

出0入0汤圆

 楼主| 发表于 2007-4-9 17:59:52 | 显示全部楼层
另外:

采用XP系统自带的超级终端传输.BIN文件

下载成功率不是很高

出0入0汤圆

 楼主| 发表于 2007-4-9 20:33:07 | 显示全部楼层
有没有高手可以解啊?

出0入0汤圆

 楼主| 发表于 2007-4-10 14:19:19 | 显示全部楼层
我怀疑,其实APP程序并没有写入Flash中,但是不知道怎么才能验证到底由没有写进去。

出0入0汤圆

 楼主| 发表于 2007-4-11 16:13:25 | 显示全部楼层
问题解决了

出0入0汤圆

发表于 2007-4-11 16:51:16 | 显示全部楼层
如何解决的说说吧.

出0入0汤圆

 楼主| 发表于 2007-4-12 08:48:52 | 显示全部楼层
熔丝位 的第一项没开(就是一直都是不允许自编程)

APP程序一直都没有写进Flash里

出0入0汤圆

发表于 2008-7-26 18:49:38 | 显示全部楼层
顶下

出0入0汤圆

发表于 2009-12-10 16:47:18 | 显示全部楼层
不知道有没有工程文件呢?

出0入0汤圆

发表于 2014-11-5 23:32:53 | 显示全部楼层
atmega48的IAP还是不要研究了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 04:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表