⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootldr.c

📁 ATMEGA128自己用的BOOT程序
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "bootcfg.h"
#include "bootldr.h"
#include "bord_sel.h"

unsigned long int FlashAddr;
unsigned long int pgm_addr_start;
unsigned long int pgm_addr_end;

#define RX_BUFFER_SIZE 150
volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
volatile uint8_t rx_wr_index,rx_rd_index,rx_counter;
volatile uint8_t rx_buffer_overflow;

SIGNAL(SIG_USART0_RECV)
{
    uint8_t status,data;
    status=UCSR0A;
    data=UDR0;
    //if ((status & (_BV(FE) | _BV(DOR) | _BV(UPE)))==0)
    {
        rx_buffer[rx_wr_index]=data;
        if (++rx_wr_index == RX_BUFFER_SIZE)
        {
            rx_wr_index=0;
        }
		
        if (++rx_counter == RX_BUFFER_SIZE)
        {
            rx_counter=0;
            rx_buffer_overflow=1;
        }
    }
}

#define wait_char() (rx_counter)
unsigned char get_char(void)
{
	uint8_t data;
    uint8_t sreg;
	
    while (rx_counter==0);
	
    data=rx_buffer[rx_rd_index];
	
    if (++rx_rd_index == RX_BUFFER_SIZE)
    {
        rx_rd_index=0;
    }
	
    sreg = SREG;
    cli();
    --rx_counter;
    sei();    
    SREG = sreg;
	
    return (data);
}

//更新一个Flash页
unsigned char write_one_page_addr(unsigned long int addr,unsigned char *wbuf)
{
  unsigned int tmp_cnt;
  
  if(addr<pgm_addr_start||addr>pgm_addr_end){return 2;}//不在地此范围
  
  boot_page_erase(addr);                   //擦除一个Flash页
  boot_spm_busy_wait();
  for(tmp_cnt = 0; tmp_cnt < 256; tmp_cnt += 2) //数据填入Flash缓冲页
  {
    boot_page_fill(tmp_cnt,((wbuf[tmp_cnt + 1] << 8)+wbuf[tmp_cnt]));
  }
  boot_page_write(addr);                    //将缓冲页数据写入一个Flash页
  boot_spm_busy_wait();                   //等待页编程完成
  
  //检验
  boot_rww_enable();                       //允许读用户程序

  for(tmp_cnt = 0; tmp_cnt < 256; tmp_cnt++)
  {
	if(pgm_read_byte_far(addr+ tmp_cnt) != wbuf[tmp_cnt])
	{
	  return 1;
	}
  }
  return 0;
}

//写入数据到串口
void WriteCom(unsigned char dat)
{
  UDR0=dat;
  while(!(UCSR0A&(1<<5)));
}

#if VERBOSE
void putstr(const char *str)
{
  while(*str)
  WriteCom(*str++);
}

unsigned char hex_to_ascii(unsigned char i)
{
	i=i&0xf;
	if(i<10)return i+'0';
	else return i+'A'-10;	
}

#endif

void put_data_to_arm(unsigned char *xor_buf,unsigned char size)//与ARM通信数据包
{
	  unsigned char i;
	  unsigned char check;
	  
	  WriteCom(0x7e);
	  WriteCom(0x81);
	  WriteCom(size);
	  WriteCom(size);	  
	  
	  check=0;	  
	  for(i=0;i<size;i++)
	  {
	  	WriteCom(xor_buf[i]);
	  	check^=xor_buf[i];
	  }
	  
	  WriteCom(check);
}

//当前Flash地址指针

unsigned char boot_first;
unsigned char cmd_long;

#define cmd_buf_size 256
unsigned char cmd_buf[cmd_buf_size];
unsigned char cmd_buf_check;
unsigned int  cmd_buf_i;


#define pgm_buf_size 256
unsigned int  pgm_ptr;
unsigned char pgm_cnt;
unsigned char pgm_buf[pgm_buf_size];

unsigned char xiazai_mode;

unsigned char read_flag_pgm(void)
{
	int i;
	boot_rww_enable();                       //允许读用户程序
	for(i = 0; i < 256; i++)
	{
		pgm_buf[i]=pgm_read_byte_far(0x1df00+ i);
	}
	
	if( pgm_buf[0]==0x55&& 
	    pgm_buf[1]==0xaa&& 
		pgm_buf[2]==0x11&& 
		pgm_buf[3]==0x22&& 
		pgm_buf[4]==0x33&& 
		pgm_buf[5]==0x44&& 
		pgm_buf[6]==0x55
	)//有应用程序,直接运行程序
	{
		return 0x0;//延时后运行程序
	}
	else//没有程序一直运行BOOT
	{
		return 0x1;		
	}
}

unsigned char write_flag_pgm(void)
{
	FlashAddr = 0x1df00;
	pgm_addr_start=FlashAddr;
	pgm_addr_end=0x1e000;
	return write_one_page_addr(FlashAddr,pgm_buf);
}

//跳转到用户程序
void quit(void)
{  
		boot_rww_enable();     //允许用户程序区读写
		cli();
		MCUCR = 0x80|0x01; 
		MCUCR = 0x80|0x00;           //将中断向量表迁移到应用程序区头部
		RAMPZ = 0x00;                //RAMPZ清零初始化
		(*((void(*)(void))0))();            //跳转,这样比'jmp 0'节省空间
}

//UART0 initialize
// desired baud rate: 38400
// actual: baud rate:38400 (0.0%)
// char size: 8 bit
// parity: Even
void uart0_init(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00;
 UCSR0C = 0x26;
 UBRR0L = 0x0B; //set baud rate lo
 UBRR0H = 0x00; //set baud rate hi
 UCSR0B = 0x98;
}

void uart0_init1(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00;
 UCSR0C = 0x06;
 UBRR0L = 0x0B; //set baud rate lo
 UBRR0H = 0x00; //set baud rate hi
 UCSR0B = 0x98;
}

//char boot_xmoden_buf[10];
//char boot_xmoen_cnt;

int main(void)
{
	int led_cnt;	
	int uart_reset_cnt;
	int boot_start_cnt;
	
	unsigned char data_tmp;
	unsigned char boot_flag;
	unsigned int  pack_down=0,pack_save=0;
		
    unsigned char cnt;
	unsigned char error_tmp;
	
	unsigned char ch,cl,pack_no;
    //--------------------------------------------
    //禁止看门狗
	#ifndef MCUSR
	#define MCUSR    MCUCSR
	#endif
	MCUSR = 0;
	wdt_disable();
	//--------------------------------------------
	//关闭中断,异常情况下的保护
    cli();	
	
	MCUCR = 0x80|0x01;
    MCUCR = 0x80|0x02;                    //将中断向量表迁移到Boot区头部
	cpuinit();
	//串口初始化

	uart0_init();

	sei();
	    
	boot_flag=read_flag_pgm();
	
	xiazai_mode=0;	
	led_cnt=0;
	uart_reset_cnt=0;
	boot_start_cnt=0;
	boot_first=0;
	
	while(1)
	{
		if(++led_cnt>=20000)
		{	led_cnt=0;						
		
			RUN_lED_CPL;
			if(++boot_start_cnt>=100)
			{    boot_start_cnt=0;
				 break;
			}
		}
		
		if(wait_char())
		{   uart_reset_cnt=0;
			
			data_tmp=get_char();
			
			if(data_tmp=='d'||data_tmp=='D')
			{
				goto xmoden_down_loop;
			}
			
			if(data_tmp==0x7e)
			{
				goto xhj_arm_boot;
			}
		}
	}
	
	while(1)
	{				
		if(++led_cnt>=20000)
		{	led_cnt=0;						
			if(boot_first!=0)
			{				
				if(++uart_reset_cnt>=20)
				{    uart_reset_cnt=0;
					 boot_first=0;							 
				}
			}
			
			RUN_lED_CPL;
			
			if(boot_flag==0)//启动运行程序
			{
				if(++boot_start_cnt>=80)
				{    boot_start_cnt=0;
					 quit();//程序运行不成功则运行BOOT
				}
			}
		}
		
		if(wait_char())
		{   uart_reset_cnt=0;
		    boot_start_cnt=0;
			
			data_tmp=get_char();
			
			if(boot_first==4)
			{		
				cmd_buf[cmd_buf_i++]=data_tmp;				
				if(cmd_buf_i>cmd_long)
				{
					boot_first=0;
					if(cmd_buf_check==data_tmp)
					{
						switch(cmd_buf[0])
						{
							case 0xcb://数据包 128
							    pack_down=cmd_buf[1];
			            	 	pack_down<<=8;
			            	 	pack_down|=cmd_buf[2];
								if(pack_down==(pack_save+1))
								{
								   pack_save=pack_down;		
								   
								   for(pgm_cnt=0;pgm_cnt<128;pgm_cnt++)
								   {
									   pgm_buf[pgm_ptr++]=cmd_buf[3+pgm_cnt];
								   }

								   if(pgm_ptr>128)
								   {
										//unsigned char wr_tmp;
									    pgm_loop1:;
									    pgm_ptr=0;
										error_tmp=write_one_page_addr(FlashAddr,pgm_buf);
										FlashAddr+=256;
										//cmd_buf[0]=0xcb;
										if(error_tmp==0)
										{											
										  cmd_buf[1]=0x80;//写对
										}
										else
										{
										  cmd_buf[1]=0x8f;//写错
										}
										cmd_buf[2]=pack_save>>8;
										cmd_buf[3]=pack_save;
										put_data_to_arm(cmd_buf,4);
										
										if(xiazai_mode==0x55)
										{
											pgm_buf[0]=0x55; 
											pgm_buf[1]=0xaa; 
											pgm_buf[2]=0x11; 
											pgm_buf[3]=0x22;
											pgm_buf[4]=0x33;
											pgm_buf[5]=0x44;
											pgm_buf[6]=0x55;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -