搜索
bottom↓
回复: 6

bootloader引导程序问题

[复制链接]

出0入0汤圆

发表于 2012-2-9 17:52:35 | 显示全部楼层 |阅读模式
有没有人帮我看下我的bootloader引导程序怎么都没有成功,问题出在哪里了,BIN文件可以下载,但是程序一直没有运行APP区,一直在BOOT LOADER,难道程序没下载到APP区或者说下载的数据不对?经过ISP读取flash内容,发现地址0x0000开始的内容出来前两个字节为0x00,其余为0xff;我用CVAVR编译器,ATMEGA88V芯片;谢谢了;
//#include <tiny13.h>  
#include <mega88.h>
#include <delay.h>
#define uchar unsigned char
#define uint unsigned int   


#define SPM_PAGESIZE 128          //M16的一个Flash页为128字节(64字)
#define DATA_BUFFER_SIZE SPM_PAGESIZE        //定义接收缓冲区长度


//定义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'


//函数申明
void uart_putchar(char c);
int uart_getchar(void);  
void quit(void);
char uart_waitchar(void);

void boot_page_ew(int p_address,char code);
void boot_page_fill(uint address,int data);
void wait_page_rw_ok(void);
void write_one_page(void);
int calcrc(char *ptr, int count);

const uchar startupString[]="Type 'd' download, Others run app.\n\r\0";  
char data[DATA_BUFFER_SIZE] ={1,2,34,56,79,234,456,3321,3469};
int address = 0;
            

void main(void)
{  
   int i;
   //uchar m=0;;
   uint timercount = 0;
   uchar packNO = 1;
   int bufferPoint = 0;
   uint crc;
                     
   delay_ms(100);
   PORTD=0xff;
   DDRD=0x1e;
   /************mega88_USART_Init********/
   UBRR0H =0;
   UBRR0L =0x19;         //0x0C:波特率38400   0x19:19200
   //UCSR0A =0x20;
   UCSR0B =0x18;       //发送和接受使能   
   UCSR0C =0x0E;       //00001110 寄存器选择UCSRC 异步 无校验 2个停止位 8位数据
   /********TC2_CTC_Init***********************/
    OCR0A =0x75;   //15ms自动重载        0x75=117  117/(8000/1024)=117/7.8125=14.976ms
   
    TCCR0A=0x02;  //CTC 1024分频
    TCCR0B=0x05;
    //MCUCR =0x01;                                 //MCUCR:通用中断控制寄存器
    //MCUCR =0x10;
   while(1)
   {  
      while(startupString!='\0')
      {
         uart_putchar(startupString);
         i++;
      }
      while(1)  //3秒种等待PC下发“d”,否则退出Bootloader程序,从0x0000处执行应用程序
     {
        if(uart_getchar()== 'd') break;   //如果接收到PC发送来的"d"  就退出本while( )循环
        if(TIFR0 & 0x02)                         //如果定时器中断标志寄存器TIFR位OCF2被置位
        {
            if (++timercount > 200) quit();        //200*15ms = 3s 超过,就退出本while( )循环
           TIFR0 |=0x02;                      //清除标志位OCF2 继续等待
        }
     }
     //每秒向PC机发送一个控制字符“C”,等待控制字〈soh〉
     /*while(1)
     {
         uart_putchar(uart_getchar());
     } */
     
    while(uart_getchar()!=XMODEM_SOH)        //receive the start of Xmodem
    {     PORTD.4=0;
         if(TIFR0 & 0x02)                    //timer0 over flow
        {
            if(++timercount > 67)                        //wait about 1 second
            {   
               uart_putchar(XMODEM_RECIEVING_WAIT_CHAR);    //send a "C"
                //uart_putchar(0x22);
                timercount=0;
            }
            TIFR0=TIFR0 | 0x02;
        }
        //uart_putchar(1);
    }
   
  /*while(1)
  {     
  PORTD.3=0;
  } */
     //开始接收数据块
    do
    {      
        if ((packNO == uart_waitchar()) && (packNO ==(~uart_waitchar())))
        {    //核对数据块编号正确
            for(i=0;i<128;i++)                //接收128个字节数据
            {
                data[bufferPoint]= uart_waitchar();
                bufferPoint++;     
            }  
            //crc=0;
            crc = uart_waitchar();
            //crc = (uart_waitchar()<<8);
            crc<<=8;
            crc += uart_waitchar();            //接收2个字节的CRC效验字
            if(calcrc(&data[bufferPoint-128],128)==crc)    //CRC校验验证
            {   
                  while(bufferPoint >= SPM_PAGESIZE)         //正确接收128个字节数据
                  {     
                        write_one_page();                             //收到32字节写入一页Flash中
                                      //Flash页加1 (32字节/页)  等于是将 flash地址每次加128                     
                        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_one_page();                         //把剩余的数据写入Flash中
    quit();                //退出Bootloader程序,从0x0000处执行应用程序
      
   }  
}


//从RS232发送一个字节  
void uart_putchar(char c)  
{  
  while(!(UCSR0A & 0x20));  
  UDR0 = c;  
}

//从RS232接收一个字节
int uart_getchar(void)
{
    unsigned char status,res;  //status,
    if(!(UCSR0A & 0x80))return -1;      //接收缓冲器中有未读出的数据时RXC 置位
   
    status =UCSR0A;
    res =UDR0;
   
    /*while (UCSR0A & 0x80)
    {
       res =UDR0;
      
    }*/
    status =UCSR0A;
    if (status & 0x1c) return -1;      //EF DOR PE(帧错误 溢出错误 奇偶错误 )
    return res;
}  

//等待从RS232接收一个有效的字节
char uart_waitchar(void)
{
    int c;
    while((c=uart_getchar())==-1);
    return (char)c;
}

//退出Bootloader程序,从0x0000处执行应用程序   
void quit (void)                                                           
{   
     //#asm("cli");                                                                           
     uart_putchar('O');uart_putchar('K');   
                        
     uart_putchar(0x0d);uart_putchar(0x0a);   
     
     while(!(UCSR0A & 0x20));                //UDRE:1表示数据寄存器空 可以接收      
     MCUCR =0x01;                                 //MCUCR:通用中断控制寄存器
     MCUCR =0x00;                                 //将中断向量表迁移到应用程序区头部
     #asm  ("ldi r30,0x00")

     #asm("ldi r31,0x00")
  
     #asm("ijmp")                    //跳转到Flash的0x0000处,执行用户的应用程序     
}  

//擦除(code=0x03)和写入(code=0x05)一个Flash页
#pragma warn-
void boot_page_ew(int p_address,char code)
{     
    #asm(" LDD r30,Y+1");  //将页地址放入Z寄存器和RAMPZ的Bit0中
    #asm(" LDD r31,Y+2");   //除M128外,其他小flash芯片无RAMPZ

    SPMCSR = code;              //寄存器SPMCSR中为操作码
    #asm("spm ");               //对指定Flash页进行操作
}
#pragma warn+
         
//填充Flash缓冲页中的一个字
#pragma warn-
void boot_page_fill(unsigned int address,int data)
{   

    #asm("LDD r30,Y+2");      //(R30,R31)<--data,(--Y)<--R31,(--Y)<--R30;            //Z寄存器中为填冲页内地址
    #asm("LDD r31,Y+3");      //CVAVRz中,第一个参数存放在Y+2,Y+3的SRAM处
     
    #asm("LD r0,Y");        //因为编译器CVAVR在传递2个函数参数时,先传递第一个,后传递第2个!
    #asm("LDD r1,Y+1");        //(R30,R31)<--address,(--Y)<--R31,(--Y)<--R30;   
   
    //#asm("mov r0,r30");        //因为编译器CVAVR在传递2个函数参数时,先传递第一个,后传递第2个!
    //#asm("mov r1,r31");                                        //R0R1中为一个指令字  
                                          
   
    SPMCSR = 0x01;
    #asm("spm");
}   
#pragma warn+
//擦除(code=0x03)和写入(code=0x05)一个Flash页  
      
  
//等待一个Flash页的写完成
void wait_page_rw_ok(void)
{
      while(SPMCSR & 0x40)    //RWWSB: RWW区忙标志位
     {
         while(SPMCSR & 0x01); //SPMEN:操作flash使能位,忙时为1,要使能置1;不忙硬件自动清零
         SPMCSR = 0x11;        //使能读RWW区
         #asm("spm");
     }
}            

//更新一个Flash页的完整处理
void write_one_page(void)
{
    uint i;
    int  j;
    uint m;
    j=0;
    boot_page_ew(address,0x03);                 //擦除一个Flash页
    wait_page_rw_ok();                          //等待擦除完成
    for(i=0;i<SPM_PAGESIZE/2;i+=2)                //将数据填入Flash缓冲页中
    {   
        //j=(data[i+1]<<8);  
        j=data[i+1];
        j<<=8;
        j+=data;
        boot_page_fill(i, j);
    }
    boot_page_ew(address,0x05);                //将缓冲页数据写入一个Flash页
    wait_page_rw_ok();                         //等待写入完成
    address += SPM_PAGESIZE/2;
   
    j=0;
    boot_page_ew(address,0x03);                 //擦除一个Flash页
    wait_page_rw_ok();                          //等待擦除完成
    for(i=SPM_PAGESIZE/2;i<SPM_PAGESIZE;i+=2)                //将数据填入Flash缓冲页中
    {   
        //j=(data[i+1]<<8);  
        j=data[i+1];
        j<<=8;
        j+=data;
        m=i-SPM_PAGESIZE/2;
        boot_page_fill(m, j);  
        //PORTD.4=0;
    }
    boot_page_ew(address,0x05);                //将缓冲页数据写入一个Flash页
    wait_page_rw_ok();  
    address += SPM_PAGESIZE/2;                       //等待写入完成
}  


//计算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);
}

出0入0汤圆

发表于 2012-2-16 19:50:40 | 显示全部楼层
这段代码原本出于我的手,是用ICCAVR写的,配合M128。(原帖:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=156462&bbs_page_no=1&bbs_id=1003)


网上很多朋友在此基础上改写,用于其他型号的AVR。

改写是必须,因为芯片本身有不同的地方。

你搬了代码,至少要弄明白,做些稍微的改动,适合你用的型号,不能直接用。

我看到第5行就明白了;

#define SPM_PAGESIZE 128          //M16的一个Flash页为128字节(64字)  

至少你要知道ATMEGA88V的一个Flash页是几个字节吧?

自己认真的学习学习吧。

出0入0汤圆

发表于 2012-6-27 12:54:08 | 显示全部楼层
machao 发表于 2012-2-16 19:50
这段代码原本出于我的手,是用ICCAVR写的,配合M128。(原帖:http://www.ourdev.cn/bbs/bbs_content.jsp?b ...

马老师 请问你一个问题
我参照别人改写的AVR32的bootloader
现在可以下载程序到APP区了
可是好像现在AVR32没法从bootloader区跳到APP区运行程序
不知道哪里出了问题
所以想请教下
WINAVR2006
bootloader程序如下:
//        南京科力赛克安全设备有限公司
//                技术部:YKLSTUDENT
//                电话:18951759970
//        软件功能介绍:
//                本BOOTLOADER程序根据OURAVR忘得BOOTLOADER范例修改,
//        原为M8现改为M32使用;
//        时钟定为内部时钟8Mhz,F_CPU=8000000使用USART,19200bps
//        熔丝位设定:BOOTRST = 0 (复位地址设为BOOT区),
//                                BOOTSZ1 = 0,BOOTSZ0 = 0(BOOT区大小为2028字,4056字节)
//        Time:        2012年06月23日

#include<avr/io.h>
#include<avr/boot.h>
#include<util/crc16.h>
#include<util/delay.h>

//USART引脚定义
#define PIN_RXD         0        //PD0
#define PIN_TXD                1        //PD1

#define TXEN                3        //PC3

//常数定义
#ifndef SPM_PAGESIZE
#define SPM_PAGESIZE        128                //M32的一个FLASH页为128字节(64字)
#endif

#define PROG_START        0x0000
#define BAUDRATE         9600
       
//定义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_WAIT_CHAR        'C'

//定义全局变量
struct str_XMODEM
{
        unsigned char SOH;                        //起始字节
        unsigned char BlockNo;                //数据块编号
        unsigned char nBlockNo;                //数据块编号反码
        unsigned char Xdata[128];        //数据128字节
        unsigned char CRC16hi;                //CRC16校验码高位
        unsigned char CRC16lo;                //CRC16校验码低位
}strXMODEM;                                                //XMODEN的接受数据结构变量

unsigned int FlashAddress;                //FLASH地址

#define BootAdd                0x7000                //Boot区的首地址(运用区的最高地址)
//*        GCC-AVR里面地址使用32位长度,适用所有AVR的容量

unsigned char BlockCount;                //数据块累计(仅8位,无须考虑溢出)

unsigned char STATUS;                        //运行状态

#define ST_WAIT_START        0x00        //等待启动
#define ST_BLOCK_OK                0x01        //接受一个数据块完成
#define ST_BLOCK_FAIL        0x02        //接受一个数据块失败
#define ST_OK                        0x03        //完成

//长延时Max(65535ms)
void delay_ms(unsigned int t)
{
        while(t--)
        {
                _delay_ms(1);
        }
}

//更新一个Flash页的完整处理
void write_one_page(void)
{
        unsigned char i;
        unsigned int w;
        boot_page_erase(FlashAddress);                //擦出一个Flash页
        boot_spm_busy_wait();                                //等待页擦出完成
        for(i=0;i<SPM_PAGESIZE;i+=2)
        {
                w =  strXMODEM.Xdata|(strXMODEM.Xdata[i+1]<<8);
                boot_page_fill(i,w);                        //只是低7位(128字节/页)有效
        }
        boot_page_write(FlashAddress);                //将缓冲页数据写入一个Flash页
        boot_spm_busy_wait();                                //等待页编程完成
}
/*
void write_one_page(unsigned char buf_start)
{
        unsigned char i;
        unsigned char *buf;
        unsigned int w;
        boot_page_erase(FlashAddress);                //擦出一个Flash页
        boot_spm_busy_wait();                                //等待页擦出完成
        buf = &strXMODEM.Xdata[buf_start];
        for(i=0;i<SPM_PAGESIZE;i+=2)
        {
                w = *buf++;                                                //数据低位
                w += ((*buf++)<<8);                                //数据高位
                boot_page_fill(i,w);                        //只是低7位(128字节/页)有效
        }
        boot_page_write(FlashAddress);                //将缓冲页数据写入一个Flash页
        boot_spm_busy_wait();                                //等待页编程完成
}
*/

//跳转到用户程序
void quit(void)
{
        boot_rww_enable();                                                //RWW区读允许,否则无法马上执行用户的应用程序
        asm volatile("rjmp 0x0000"::);                        //跳转到Flash的0x0000处,执行用户的应用程序
}

//发送采用查询方式
void put_c(unsigned char c)                                //发送采用查询方式
{
        loop_until_bit_is_set(UCSRA,UDRE);
        UDR = c;
}

//发送字符串
void put_s(unsigned char *ptr)
{
        while(*ptr)
        {
                put_c(*ptr++);
        }
        put_c(0x0D);
        put_c(0x0A);                                                //结尾发送回车换行
}

//接收指定字节数据(带超时控制,Timer0的1ms时基)
//        *ptr                数据缓冲区
//        len                        数据长度
//        timeout                超时设定,最长65.526S
//        返回值                已接收字节数目
unsigned char get_data(unsigned char *ptr,unsigned char len,unsigned int timeout)
{
        unsigned char count = 0;
        do
        {
                if(UCSRA&(1<<RXC))                //缓冲区有数据未读出
                {
                        *ptr++ = UDR;                        //如果接收到数据,读出
                        count ++;
                        if(count>=len)
                        {
                                break;                        //够了?保存
                        }
                }
                if(TIFR&(1<<OCF2))                //T2溢出1ms
                {
                        TIFR |= (1<<OCF2);        //清除标志位
                        timeout --;                        //倒计时
                }
        }while(timeout);       
        return count;
}       

//计算CRC16
/*
Optimized CRC-XMODEM calculation.

    Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)<br>
    Initial value: 0x0

    This is the CRC used by the Xmodem-CRC protocol.

    The following is the equivalent functionality written in C.
*/
unsigned int calcrc(unsigned char *ptr,unsigned char count)
{
        unsigned int crc = 0;
        while(count--)
        {
                crc = _crc_xmodem_update(crc,*ptr++);
        }
        return(crc);
}

int main(void)
{
        unsigned char c;
        unsigned char i;
        unsigned int crc;
        //考虑到BootLoader可能由应用程序中跳转过来,所以所用到的模块需要全面初始化
        DDRB = 0x00;
        DDRC = 0x00;                                        //不用的管脚使能内部上拉电阻
        PORTB = 0xFF;
        PORTC = 0xFF;
        PORTD = 0xFF;
        DDRD = (1<<PIN_TXD);                        //串口的输出               
        GICR = (1<<IVCE);
        GICR = (0<<IVCE)|(1<<IVSEL);        //将中断向量表迁移到Boot区头部       
        asm volatile("cli"::);                        //关全局中断
        //这个BootLoader没有使用中断
        //初始化USART 19200 8,n,1        PC上位机软件(超级终端)也要设成同样的设置才能通信
        UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);        //异步,8位数据,无奇偶校验,一个停止位,无倍速
        UBRRL = (F_CPU/BAUDRATE/16-1)%256;        //
        UBRRH = (F_CPU/BAUDRATE/16-1)/256;
        UCSRA = 0x00;
        UCSRB = (1<<RXEN)|(1<<TXEN);
        //初始化T/C2,CTC模式,256分频,1ms自动重载
        TCNT2 = 0xE4;
        OCR2 = 0x1C;
        TCCR2 = (1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20);
        //CTC模式下,溢出标志是输出比较匹配0CF0,对应的中断是输出比较匹配中断;

        //向PC机发射开始提示信息
        //put_s("3秒内按下d键更新");
        put_s("It begin to Update in middle of three minutes!");
        //put_s("如果更新用户程序,请在3秒钟内按下[d]键,否则3秒后运行用户程序");
       
        //3秒钟等待PC下发"d",否则退出Bootloader程序,从0x0000处执行应用程序
        c = 0;
        get_data(&c,1,3000);                        //限时3秒,接收一个数据
        if((c=='d')||(c=='D'))
        {
                STATUS = ST_WAIT_START;                //并且数据=‘d’或‘D’,进入XMODEM
                //put_s("BIN文档最大14KB");
                put_s("the max of BIN is 14 KB!");
        }
        else
        {
                STATUS = ST_OK;                                //退出Bootloader程序
        }
        //进入XMODEM模式
        FlashAddress = 0x0000;
        BlockCount = 0x01;
        while(STATUS!=ST_OK)                        //循环接收,直到全部发完
        {
                if(STATUS==ST_WAIT_START)
                {
                        put_c(XMODEM_WAIT_CHAR);        //发射请求XMODEM_WAIT_CHAR
                }
                i = get_data(&strXMODEM.SOH,133,1000);        //限时1秒,接收133字节数据
                if(i)
                {
                        //分析数据包的第一个资料SOH/EOT/CAN
                        switch(strXMODEM.SOH)
                        {
                                case XMODEM_SOH:                                //收到开始符SOH
                                {
                                        if(i>=133)
                                        {
                                                STATUS = ST_BLOCK_OK;       
                                        }
                                        else
                                        {
                                                STATUS = ST_BLOCK_FAIL;                //如果数据不足,要求重发当前数据块
                                                put_c(XMODEM_NAK);
                                        }
                                        break;
                                }
                                case XMODEM_EOT:                                //收到结束符EOT
                                {
                                        put_c(XMODEM_ACK);                        //通知PC机全部收到
                                        STATUS = ST_OK;
                                        //put_s("升级OK");
                                        put_s("It is OK!");
                                        break;
                                }
                                case XMODEM_CAN:                                //收到取消符CAN
                                {
                                        put_c(XMODEM_ACK);                        //回应PC机
                                        STATUS = ST_OK;
                                        //put_s("升级fail");
                                        put_s("It is Fail!");
                                        //put_s("警告:用户取消升级,用户程序可能不完整");
                                        break;
                                }
                                default:
                                {
                                        put_c(XMODEM_NAK);                        //要求重发当前数据块
                                        STATUS = ST_BLOCK_FAIL;
                                        break;
                                }
                        }
                }
                if(STATUS==ST_BLOCK_OK)                                        //收到133字节OK,且起始字节正确
                {
                        if(BlockCount!=strXMODEM.BlockNo)        //核对数据块编号正确
                        {
                                put_c(XMODEM_NAK);                                //数据块编号错误,要求重发当前数据块
                                continue;
                        }
                        if(BlockCount!=(unsigned char)(~strXMODEM.nBlockNo))       
                        {
                                put_c(XMODEM_NAK);                                //数据块编号反码错误,要求重发当前数据
                                continue;
                        }
                        crc = strXMODEM.CRC16hi<<8;
                        crc += strXMODEM.CRC16lo;
                        //AVR的16位整数是低位在前,XMODEM的CRC16是高位在前
                        if(calcrc(&strXMODEM.Xdata[0],128)!=crc)
                        {
                                put_c(XMODEM_NAK);                                //CRC错误,要求重发当前数据块
                                continue;
                        }
                        //正确接收128个字节数据,刚好事M32的一页
                        if(FlashAddress<(BootAdd-SPM_PAGESIZE))
                        {
                                //如果地址在应用区内
                                write_one_page();                                //将接收的0-127字节写入一页Flash中
                                FlashAddress += SPM_PAGESIZE;
                        }
                        else
                        {
                                put_c(XMODEM_CAN);                                //程序已满,取消传送
                                put_c(XMODEM_CAN);
                                put_c(XMODEM_CAN);
                                STATUS = ST_OK;
                                //put_s("程序已满");
                                put_s("It is Full!");
                                break;
                        }
                        put_c(XMODEM_ACK);                                        //回应已正确收到一个数据块
                        BlockCount ++;                                                //数据块累计加1
                }
        }
        //退出Bootloader程序,从0x0000处执行应用程序
        put_s("GO");
        delay_ms(500);                                                                //很奇怪,见顶部的说明
        loop_until_bit_is_set(UCSRA,UDRE);                        //等待结束提示信息回送完成
        GICR = (1<<IVCE);
        GICR = (0<<IVCE)|(0<<IVSEL);                                //将中断向量表迁移到应用程序区头部
        //无论Bootloader是否使用中断,将中断向量表迁移到应用程序区头部,
        //会增强程序的健壮性
        //boot_rww_enable();                                                        //RWW区读允许,否则无法马上执行用户的应用程序
        //asm volatile("rjmp 0x0000"::);                                //跳转到Flash的0x0000处,执行用户的应用程序       
        quit();                                                                                //退出,返回到用户应用程序
        return(0);       
}

出0入0汤圆

发表于 2012-6-29 21:34:43 | 显示全部楼层
楼上的,你是抄“南京科力赛克安全设备有限公司”的代码,还是在这个公司工作?
2楼就是我的回复。


出0入0汤圆

发表于 2012-6-30 15:19:47 | 显示全部楼层
本帖最后由 yklstudent 于 2012-6-30 15:22 编辑
machao 发表于 2012-6-29 21:34
楼上的,你是抄“南京科力赛克安全设备有限公司”的代码,还是在这个公司工作?
2楼就是我的回复。


哦 那个是我公司
马老师 还能重新给个链接地址 那给的地址打不开

出0入0汤圆

发表于 2012-7-1 19:39:18 | 显示全部楼层
在本栏的精华帖中《自引导IAP(boot load)的应用设计--armok转贴》http://www.amobbs.com/forum.php? ... st%3D1%26digest%3D1

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-20 07:18

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

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