Gorgon_Meducer 发表于 2008-9-1 17:07:57

[开源][交流]AVR Bootloader底层驱动函数库,送给ICCAVR的用户 2009最后一次更新

#ifndef _USE_BOOT_LOADER_H_
#define _USE_BOOT_LOADER_H_
/***********************************************************
*   声明库说明:Bootloader底层操作函数声明库               *
*   版本:      v1.00beta                                  *
*   作者:      王卓然                                     *
*   创建日期:2008年8月31日                              *
* -------------------------------------------------------- *
*[支 持 库]                                              *
*   支持库名称:                                           *
*   需要版本:                                             *
*   声明库说明:                                           *
* -------------------------------------------------------- *
*[版本更新]                                              *
*   修改:                                                 *
*   修改日期:                                             *
*   版本:                                                 *
* -------------------------------------------------------- *
*[版本历史]                                              *
* -------------------------------------------------------- *
*[使用说明]                                              *
***********************************************************/

/********************
* 头 文 件 配 置 区 *
********************/

/********************
*   系 统 宏 定 义*
********************/

/*------------------*
*   常 数 宏 定 义*
*------------------*/

/*------------------*
*   动 作 宏 定 义*
*------------------*/
# define PUT_INT_VECTOR_INTO_BLS    Bootloader_Put_INT_Vector_Into_BLS();
# define PUT_INT_VECTOR_INTO_APPS   Bootloader_Put_INT_Vector_Into_APPS();

/********************
*用户变量类型定义 *
********************/

/********************
*    结构体定义区   *
********************/

/********************
*   函 数 引 用 区*
********************/
extern BOOL Bootloader_Flash_Page_Verify
      (
            BYTE *pchDataBuffer,
            UINT16 wAddress
      );
#ifdef BL_USE_LOAD_PAGE
#if defined(BOOTLOADER_USE_CRC16)
extern UINT16 Bootloader_Load_Page_Buffer
#elif defined(BOOTLOADER_USE_XOR)
extern UINT8 Bootloader_Load_Page_Buffer
#else
extern void Bootloader_Load_Page_Buffer
#endif
      (
            BYTE chDataBuffer,
            UINT16 wAddress
      );
#endif
extern BOOL Bootloader_Write_Page
            (
                void *pData,
                uint16 wLength,
                UINT16 wAddress
            );
extern void Bootloader_Put_INT_Vector_Into_APPS(void);
extern void Bootloader_Put_INT_Vector_Into_BLS(void);

/********************
*   全局变量引用区*
********************/

#endif

Gorgon_Meducer 发表于 2008-9-1 17:09:10

/***********************************************************
*   函数库说明:Bootloader底层操作函数库                   *
*   版本:      v1.00beta                                  *
*   作者:      王卓然                                     *
*   创建日期:2008年8月31日                              *
* -------------------------------------------------------- *
*[支 持 库]                                              *
*   支持库名称:                                           *
*   需要版本:                                             *
*   声明库说明:                                           *
* -------------------------------------------------------- *
*[版本更新]                                              *
*   修改:                                                 *
*   修改日期:                                             *
*   版本:                                                 *
* -------------------------------------------------------- *
*[版本历史]                                              *
* -------------------------------------------------------- *
*[使用说明]                                              *
***********************************************************/


/********************
* 头 文 件 配 置 区 *
********************/
# include "RD_MacroAndConst.h"
# include "BL_Config.h"
# include "PF_Config.h"

/********************
*   系 统 宏 定 义*
********************/

/*------------------*
*   常 数 宏 定 义*
*------------------*/
# define SPM_ENBALE_RWW   (BIT(RWWSRE)|BIT(SPMEN))
# define SPM_PAGE_WRITE   (BIT(PGWRT)|BIT(SPMEN))
# define SPM_PAGE_ERASE   (BIT(PGERS)|BIT(SPMEN))
# define SPM_WRITE_BUFFER   BIT(SPMEN)

#ifndef FLASH_PAGE_SIZE
    # define FLASH_PAGE_SIZE    64
#endif

#ifdef BOOTLOADER_USE_CRC16
    # define    CRC_INIT      0xFFFF
    # define    CRC(__CRCVAL,__NEWCHAR) CRC16_Check(&(__CRCVAL),(__NEWCHAR));
#endif

/*------------------*
*   动 作 宏 定 义*
*------------------*/

/********************
*模块结构体定义区 *
********************/

/********************
*   函 数 声 明 区*
********************/
BOOL Bootloader_Flash_Page_Verify
      (
            BYTE *pchDataBuffer,
            UINT16 wAddress
      );
#ifdef BL_USE_LOAD_PAGE
#if defined(BOOTLOADER_USE_CRC16)
UINT16 Bootloader_Load_Page_Buffer
#elif defined(BOOTLOADER_USE_XOR)
UINT8 Bootloader_Load_Page_Buffer
#else
void Bootloader_Load_Page_Buffer
#endif
      (
            BYTE chDataBuffer,
            UINT16 wAddress
      );
#endif   
BOOL Bootloader_Write_Page
            (
                void *pData,
                uint16 wLength,
                UINT16 wAddress
            );
void Bootloader_Put_INT_Vector_Into_APPS(void);
void Bootloader_Put_INT_Vector_Into_BLS(void);

/********************
*   模块函数声明区*
********************/
static void Do_Boot_Loader_Action(UINT8 chFunction);
static UINT16 CRC16_Check(UINT16 *pwCRCValue,BYTE chData);
static BOOL Fill_Page_Buffer
            (
                BYTE chDataBuffer,
                UINT16 wAddress
            );
   
/********************
*   模块变量声明区*
********************/

/********************
*   全局变量声明区*
********************/

#ifdef BOOTLOADER_USE_CRC16
/***********************************************************
*   函数说明:CRC16单数据处理函数                        *
*   输入:      保存CRC校验值的地址,新的数据            *
*   输出:      CRC交验                                    *
*   调用函数:无                                       *
***********************************************************/
static UINT16 CRC16_Check(UINT16 *pwCRCValue,BYTE chData)
{
    UINT16 wCRC = (*pwCRCValue);
   
    chData ^= (UINT8)((UINT16)wCRC & 0x00FF);
    chData ^= chData << 4;
    (*pwCRCValue) = ((((uint16)chData << 8) | (wCRC >> 8)) ^ (uint8)(chData >> 4)
               ^ ((uint16)chData << 3));
               
    return (*pwCRCValue);
}
#endif


/***********************************************************
*   函数说明:等待SPM指令执行结束函数                  *
*   输入:      需要执行的功能                           *
*   输出:      无                                       *
*   调用函数:无                                       *
***********************************************************/
static void Do_Boot_Loader_Action(UINT8 chFunction)
{
    /* 等待上次操作结束 */
    while(SPMCSR & BIT(SPMEN));
   
    SAFE_CODE_PERFORMANCE
    (
      while(EECR & BIT(EEWE));
      SPMCSR = chFunction;
      asm("spm");
    )
}

#ifdef BL_USE_LOAD_PAGE
/***********************************************************
*   函数说明:读取指定的页面到指定的缓冲区               *
*   输入:      缓冲区地址,页面地址                     *
*   输出:      无/CRC校验/XOR校验                         *
*   调用函数:无                                       *
* -------------------------------------------------------- *
*   [ 说明 ]                                             *
*               如果输入的缓冲区指针为空,则只进行校验操作 *
***********************************************************/
#if defined(BOOTLOADER_USE_CRC16)
UINT16 Bootloader_Load_Page_Buffer
#elif defined(BOOTLOADER_USE_XOR)
UINT8 Bootloader_Load_Page_Buffer
#else
void Bootloader_Load_Page_Buffer
#endif
      (
            BYTE chDataBuffer,
            UINT16 wAddress
      )
{
    UINT16 wCounter = FLASH_PAGE_SIZE;
    #if defined(BOOTLOADER_USE_CRC16)
    UINT16 wTempCRC = CRC_INIT;
    UINT8 chData = 0;
    #elif defined(BOOTLOADER_USE_XOR)
    UINT8 chXOR = 0;
    #endif
   
    #if !defined(BOOTLOADER_USE_CRC16) && !defined(BOOTLOADER_USE_XOR)
    if (chDataBuffer == NULL)
    {
      /* 在无校验的情况下,给与空指针传递,无意义 */
      return ;
    }
    #endif
   
    /* 开启RWW区的读取功能 */
    while(SPMCSR & BIT(RWWSB))
    {
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
    }
   
    /* 将地址保存到Z寄存器 */
    asm("movw r30,r18");
    /* 将地址保存到X寄存器 */
    asm("movw r26,r16");

    if (chDataBuffer != NULL)
    {
      /* 将地址保存到Z寄存器 */
      //asm("movw r30,r18");
      /* 遍历整个Flash 页面 */
      while(wCounter--)
      {
            /* 读取数据并复制到SRAM中 */
            asm("lpm r0,z+");
            asm("st x+,r0");
            
            /* 进行校验 */
            #if defined(BOOTLOADER_USE_CRC16)
            asm("mov %chData,r0");
            CRC(wTempCRC,chData);
            #elif defined (BOOTLOADER_USE_XOR)
            asm("mov r1,%chXOR");
            asm("eor r1,r0");
            asm("mov %chXOR,r1");
            #endif
      }
    }
    else
    {
      /* 将地址保存到Z寄存器 */
      //asm("movw r30,r18");
      /* 仅仅进行校验 */
      #if defined(BOOTLOADER_USE_CRC16)
      /* 遍历整个Flash 页面 */
      while(wCounter--)
      {
            asm("lpm r0,z+");
            asm("mov %chData,r0");
            CRC(wTempCRC,chData);
      }
      #elif defined (BOOTLOADER_USE_XOR)
      /* 遍历整个Flash 页面 */
      while(wCounter--)
      {
            asm("lpm r0,z+");
            asm("mov r1,%chXOR");
            asm("eor r1,r0");
            asm("mov %chXOR,r1");
      }
      #endif
    }
   
    #if defined(BOOTLOADER_USE_CRC16)
    return wTempCRC;
    #elif defined(BOOTLOADER_USE_XOR)
    return chXOR;
    #endif
}
#endif

/***********************************************************
*   函数说明:向页缓冲区写入数据函数                     *
*   输入:      缓冲区指针,要写入的地址                   *
*   输出:      写入是否成功                               *
*   调用函数:无                                       *
***********************************************************/
static BOOL Fill_Page_Buffer
            (
                BYTE chDataBuffer,
                UINT16 wAddress
            )
{
    UINT8 chCounter = (FLASH_PAGE_SIZE>>1);
   
    if (chDataBuffer == NULL)
    {
      return FALSE;
    }

    /* 给Z寄存器写入地址 */
    asm("ldi r30,0");
    //asm("ldi r31,0");
    asm("movw r26,r16");
    /* 循环将数据写入页缓冲区 */
    while(chCounter--)
    {
      asm("ld r0,x+");
      asm("ld r1,x+");
      Do_Boot_Loader_Action(SPM_WRITE_BUFFER);
      asm("adiw r30,2");
    }
    /* 将地址保存到Z寄存器 */
    asm("movw r30,r18");

    return TRUE;
}

/***********************************************************
*   函数说明:页面校验函数                               *
*   输入:      源页面缓冲区,目标地址                     *
*   输出:      校验是否成功                               *
*   调用函数:无                                       *
***********************************************************/
BOOL Bootloader_Flash_Page_Verify
      (
            BYTE *pchDataBuffer,
            UINT16 wAddress
      )
{
    UINT16 wCounter = FLASH_PAGE_SIZE;
    UINT8 chDataA = 0;
    UINT8 chDataB = 0;
   
    if (pchDataBuffer == NULL)
    {
      return FALSE;
    }
   
    /* 将地址保存到Z寄存器 */
    asm("movw r30,r18");
    asm("movw r26,r16");
    while(wCounter--)
    {
      asm("lpm r0,z+");
      asm("mov %chDataA,r0");
      asm("ld r0,x+");
      asm("mov %chDataB,r0");
      if (chDataA != chDataB)
      {
            return FALSE;      
      }
    }
   
    return TRUE;
}

/***********************************************************
*   函数说明:写入页面函数                               *
*   输入:      缓冲区地址,目标地址                     *
*   输出:      操作是否成功                               *
*   调用函数:                                             *
***********************************************************/
BOOL Bootloader_Write_Page
            (
                void *pData,
                uint16 wLength,
                UINT16 wAddress
            )
{
    BYTE *pchData = pData;
    BYTE *pchBuffer = NULL;
   
    if (pData == NULL)
    {
      return FALSE;
    }
   
    /* 写多页 */
    while(wLength > FLASH_PAGE_SIZE)
    {
      /* Bootloader 写入时序 */
      Fill_Page_Buffer(pchData,wAddress);
      Do_Boot_Loader_Action(SPM_PAGE_ERASE);
      Do_Boot_Loader_Action(SPM_PAGE_WRITE);
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
   
      /* 进行校验 */
      if (
            !Bootloader_Flash_Page_Verify
                (
                  pchData,
                  wAddress
                )
         )
      {
            /* 校验失败 */
            return FALSE;
      }
      
      pchData += FLASH_PAGE_SIZE;
      wAddress += FLASH_PAGE_SIZE;
      wLength -= FLASH_PAGE_SIZE;
    }
   
   
    if (wLength < FLASH_PAGE_SIZE)
    {
      /* 需要读取页面缓冲 */
      BYTE chBuffer = {0};
      pchBuffer = chBuffer;
      
      #ifdef BL_USE_LOAD_PAGE
      Bootloader_Load_Page_Buffer
            (
                chBuffer,
                wAddress
            );
      #endif
      
      /* 进行数据复制 */   
      while(wLength--)
      {
            *pchBuffer++ = *pchData++;
      }
      pchBuffer = chBuffer;
    }
    else
    {
      pchBuffer = pchData;
    }
   
    /* Bootloader 写入时序 */
    Fill_Page_Buffer(pchBuffer,wAddress);
    Do_Boot_Loader_Action(SPM_PAGE_ERASE);
    Do_Boot_Loader_Action(SPM_PAGE_WRITE);
    Do_Boot_Loader_Action(SPM_ENBALE_RWW);
   
    /* 进行校验 */
    if (
      !Bootloader_Flash_Page_Verify
            (
                pchBuffer,
                wAddress
            )
       )
    {
      /* 校验失败 */
      return FALSE;
    }
   
    return TRUE;
}

/***********************************************************
*   函数说明:将中断向量表放置到Bootloader Section       *
*   输入:      无                                       *
*   输出:      无                                       *
*   调用函数:无                                       *
***********************************************************/
void Bootloader_Put_INT_Vector_Into_BLS(void)
{
    MCUCR |= BIT(IVCE);
    MCUCR |= BIT(IVSEL);
}

/***********************************************************
*   函数说明:将中断向量表放置到Application Section      *
*   输入:      无                                       *
*   输出:      无                                       *
*   调用函数:无                                       *
***********************************************************/
void Bootloader_Put_INT_Vector_Into_APPS(void)
{
    MCUCR |= BIT(IVCE);
    MCUCR &= ~BIT(IVSEL);
}

Gorgon_Meducer 发表于 2008-9-1 17:10:11

>>测试工程

推荐使用M32以上设备,ICC7.16A以上版本编译测试

点击此处下载 ourdev_397493.rar(文件大小:141K) (原文件名:Board_Test.rar)

>>使用方法和范例

1、基本功能将指定的数据写入到指定的FLASH地址中
    调用函数
    extern BOOL Bootloader_Write_Page
            (
                void *pData,
                uint16 wLength,
                UINT16 wAddress
            );
    需要传递的参数有三个:保存有要写入FLASH指定位置的数据。要写入数据的长度。要写入的地址。
    强调一下,这个地址无论是不是落在每个FLASH页面的起始位置,都会被当作起始位置对待。这里
    数据的长度可以大于,也可以小于一个FLASH页的大小。

2、校验功能 对比指定缓冲区与指定地址FLASH内容是否相同
    调用函数
    extern BOOL Bootloader_Flash_Page_Verify
      (
            BYTE *pchDataBuffer,
            UINT16 wAddress
      );
   需要传递的参数有两个:保存了整页数据的缓冲区指针。目标地址。这里的地址不会自动对齐到
   地址所在页面的起始位置。

3、可选的功能 从指定的地址读取FLASH数据,放到对应的缓冲区内,可以要求在读取的同时,返回指
            定的校验信息,如无校验、XOR校验、CRC16校验
   我们必须首先在配置文件BL_Config.h或者SYS_Config.h中通过宏来开启这一函数
   # define BL_USE_LOAD_PAGE
   默认情况下,不会返回任何校验信息,当我们定义了对因的宏以后,就会返回指定的校验信息。详
   细情况,请参照下面的函数声明:

#ifdef BL_USE_LOAD_PAGE
#if defined(BOOTLOADER_USE_CRC16)
extern UINT16 Bootloader_Load_Page_Buffer
#elif defined(BOOTLOADER_USE_XOR)
extern UINT8 Bootloader_Load_Page_Buffer
#else
extern void Bootloader_Load_Page_Buffer
#endif
      (
            BYTE chDataBuffer,
            UINT16 wAddress
      );
#endif   

   需要参数:大小为一个FLASH页面的缓冲区的首地址,要读取的位置(没有被自动对其到页首地址)。

4、在Bootloader中使用中断
   要在Bootloader中使用中断,需要将中断向量放置到Bootloader Section中,ICC编译器会自动帮我们
   完成这一工作——包括设置MCUCR寄存器。但是,当Bootloader工作完成以后,需要将控制权交给用户
   程序,那么我们就需要手工将有效的中断向量,指向用户程序的中断向量表:

   通过功能宏,我们可以完成这一工作
   PUT_INT_VECTOR_INTO_APPS

全局配置文件SYS_Config.h中包含的相关配置信息

# define FLASH_PAGE_SIZE    256                  //页面大小256个字节
# define BL_USE_LOAD_PAGE                        //加入页面读取模块。当要写入的内容不满一个页面
                                                   //的时候,先读取原先的内容,再写入,以保护原有
                                                   //数据,默认情况下不返回任何校验信息
//# define BOOTLOADER_USE_XOR                      //读取指定页面的时候,返回XOR交验信息
//# defien BOOTLOADER_USE_CRC16                  //读取指定页面的时候,返回CRC16校验信息

<font color=blue>系统主程序文件System.c
……
    UINT8 chBuffer = {0};
    UINT16 chCounter = 0;

    System_INIT();                                          //代码初始化

    //给要写入的缓冲区写入随意的数据用于测试
    for (chCounter = 0;chCounter < FLASH_PAGE_SIZE+5;chCounter++)
    {
      chBuffer = FLASH_PAGE_SIZE - chCounter;
    }
   
    //调用Bootloader,指定缓冲区内的数据(长度任意),写入到指定地址
    //如果校验失败,返回FALSE。
    if (Bootloader_Write_Page(chBuffer,FLASH_PAGE_SIZE + 5,0x0000))
    {
      g_bFlag = TRUE;
    }
……
</font>

ba_wang_mao 发表于 2008-9-1 17:28:34

谢谢,谢谢

wswh2o 发表于 2008-9-1 17:55:54

说明很相近

n0831 发表于 2008-9-1 18:14:14

记号.

liuxia19872003 发表于 2008-9-1 20:11:16

顶一下

knight_avr 发表于 2008-9-1 20:49:46

hahahou2008 发表于 2008-9-1 21:14:10

记号备用

avenbbs 发表于 2008-9-1 21:15:24

坚决收下,就是不知道跟AVRUBD有什么不同。

Gorgon_Meducer 发表于 2008-9-1 21:20:31

这是一个底层函数,方便你开发自己的Bootloader。
也就是说,这只算一个驱动Bootloader模块的驱动函数。你不需要过问具体的Bootloader
操作细节。如何去组织您的Bootloader,比如通过SPI、I2C还是串口、USB甚至从FAT32文
件系统来升级,就是您自己的工作了。

给一个有意思的用途——自改写AI系统……就是若干个处理器组成的阵列,某些处理器根据
需要重新改写另外的处理器的程序,最终适应周围的环境,达到进化之类……

avenbbs 发表于 2008-9-1 21:31:57

谢谢谢谢,等的就是肯定的解释,看来我的理解能力还行,哇哈哈~~

Gorgon_Meducer 发表于 2008-9-1 21:33:38

to 【11楼】 avenbbs
    最好有使用的反馈,如果你有什么修改的建议,最好分享一下,问题是越
辩越明哈。

avenbbs 发表于 2008-9-1 21:37:22

不瞒您说,我的工作是控制方面的,这些都是业余爱好,有时间才能玩玩,兴许能找到一条新出路,呵呵~~~

Gorgon_Meducer 发表于 2008-9-1 21:38:06

to 【13楼】 avenbbs
    我也是搞控制的哈。主要是机器人运动控制之类的……

avenbbs 发表于 2008-9-1 21:41:18

【14楼】 Gorgon Meducer 傻孩子

哇~~您那个高级啊~~我的低级的都不意思说~~~总有一天我要拜您为师!

Gorgon_Meducer 发表于 2008-9-1 22:24:55

to 【15楼】 avenbbs
    别……你听说过半坛醋晃啊晃得说法吗?我的也就是大学生自己玩玩的自动机械。
其实算不得机器人哈……

bluerain 发表于 2008-9-2 09:00:48

Gorgon_Meducer 发表于 2008-9-2 11:25:33

我更新了版本,通过宏 BL_CANCEL_AUTO_FORMAT_ADDRESS 我可以选择
关闭自动页面地址对齐功能。

点击此处下载 ourdev_398173.rar(文件大小:145K) (原文件名:Board_Test.rar)



/***********************************************************
*   函数说明:写入页面函数                               *
*   输入:      缓冲区地址,目标地址                     *
*   输出:      操作是否成功                               *
*   调用函数:                                             *
***********************************************************/
BOOL Bootloader_Write_Page
            (
                void *pData,
                uint16 wLength,
                UINT16 wAddress
            )
{
    BYTE *pchData = pData;
    BYTE *pchBuffer = NULL;
   
    if (pData == NULL)
    {
      return FALSE;
    }
   
   
    #ifdef BL_CANCEL_AUTO_FORMAT_ADDRESS
    /* 地址没有自动对齐到页面的首地址 */
    if ((wAddress & (FLASH_PAGE_SIZE - 1)) != 0)
    {
      BYTE chBuffer = {0};
      /* 计算出要写入的内容有多少 */
      UINT8 chTempCounter = FLASH_PAGE_SIZE - (wAddress & (FLASH_PAGE_SIZE - 1));
      
      if (wLength < chTempCounter)
      {
            chTempCounter = wLength;
      }
      wLength -= chTempCounter;
      
      /* 需要读取页面缓冲 */
      pchBuffer = chBuffer + (FLASH_PAGE_SIZE - chTempCounter);
      #ifdef BL_USE_LOAD_PAGE
      Bootloader_Load_Page_Buffer
            (
                chBuffer,
                wAddress & (~((UINT16)FLASH_PAGE_SIZE - 1)) /* 自动对齐到页面地址 */
            );
      #endif
      
      /* 进行数据复制 */   
      while(chTempCounter--)
      {
            *pchBuffer++ = *pchData++;
      }
      
      Fill_Page_Buffer(chBuffer,wAddress);
      Do_Boot_Loader_Action(SPM_PAGE_ERASE);
      Do_Boot_Loader_Action(SPM_PAGE_WRITE);
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
      
      wAddress += FLASH_PAGE_SIZE;
      wAddress &= (~((UINT16)FLASH_PAGE_SIZE - 1));
      
    }
    #endif
   
    /* 写多页 */
    while(wLength > FLASH_PAGE_SIZE)
    {
      /* Bootloader 写入时序 */
      Fill_Page_Buffer(pchData,wAddress);
      Do_Boot_Loader_Action(SPM_PAGE_ERASE);
      Do_Boot_Loader_Action(SPM_PAGE_WRITE);
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
   
      /* 进行校验 */
      if (
            !Bootloader_Flash_Page_Verify
                (
                  pchData,
                  wAddress
                )
         )
      {
            /* 校验失败 */
            return FALSE;
      }
      
      pchData += FLASH_PAGE_SIZE;
      wAddress += FLASH_PAGE_SIZE;
      wLength -= FLASH_PAGE_SIZE;
    }
   
   
    if (wLength < FLASH_PAGE_SIZE)
    {
      /* 需要读取页面缓冲 */
      BYTE chBuffer = {0};
      pchBuffer = chBuffer;
      
      #ifdef BL_USE_LOAD_PAGE
      Bootloader_Load_Page_Buffer
            (
                chBuffer,
                wAddress
            );
      #endif
      
      /* 进行数据复制 */   
      while(wLength--)
      {
            *pchBuffer++ = *pchData++;
      }
      pchBuffer = chBuffer;
    }
    else
    {
      pchBuffer = pchData;
    }
   
    /* Bootloader 写入时序 */
    Fill_Page_Buffer(pchBuffer,wAddress);
    Do_Boot_Loader_Action(SPM_PAGE_ERASE);
    Do_Boot_Loader_Action(SPM_PAGE_WRITE);
    Do_Boot_Loader_Action(SPM_ENBALE_RWW);
   
    /* 进行校验 */
    if (
      !Bootloader_Flash_Page_Verify
            (
                pchBuffer,
                wAddress
            )
       )
    {
      /* 校验失败 */
      return FALSE;
    }
   
    return TRUE;
}

Gorgon_Meducer 发表于 2008-9-3 11:24:45

[版本更新]
1、修正了写入地址不对其时,Bootloader成功,但是校验失败的错误。
2、增加了对Bootloader成功以后,跳转到用户程序区的功能宏。
   # define RUN_APPLICATION            (*((APP_RST_VECTOR*)0x00))();
   在Bootloader成功以后,一个典型的操作是:
   PUT_INT_VECTOR_INTO_APPS         /* 设置应用程序区的中断向量表为当前有效中断向量表 */
   RUN_APPLICATION                  /* 软件reset */


点击此处下载ourdev_399176.rar(文件大小:144K) (原文件名:Board_Test.rar)

maxking 发表于 2008-9-3 11:30:42

请问:广告时间的那本书是你写的吗?

Gorgon_Meducer 发表于 2008-9-3 11:33:18

to 【20楼】 maxking
    是我和我的师兄一起写的。我是第二作者,主要负责软件部分的内容。

maxking 发表于 2008-9-3 11:43:20

这本书对初学者适用不?

zxq6 发表于 2008-9-3 11:46:55

谢谢。

Gorgon_Meducer 发表于 2008-9-3 11:47:48

to 【22楼】 maxking
    这本书完全就是面向初学者写的。^_^你可以问问论坛上已经看过书的人哈。

maxking 发表于 2008-9-3 11:49:24

呵呵,这本书在卓越还便宜几毛钱。以前在卓越有个帐户的,已经下订单了,等待货到付款ing。

Gorgon_Meducer 发表于 2008-9-3 11:50:05

to 【25楼】 maxking
    期待您的反馈哈。

lyly8 发表于 2008-9-5 20:41:25

向楼主致敬, 我最近看了几个AVR BOOT的资料, 始终未理解BOOT时怎么自修改加密位及读出加密位, 请指点一下, 方便的话帮忙写个读写MAGE8和MAGE128的加密位函数.谢谢先啦!

lanfeng007 发表于 2008-9-5 21:09:17

好东西,现在还没有玩到那个深度,所以作个记号以备后用。

heizi302 发表于 2008-9-6 00:14:28

学习中,谢谢!

Gorgon_Meducer 发表于 2008-9-6 00:29:43

加密位的读取要查阅LPM指令,这个指令是允许带参数的,比如读取数据到指定的寄存器。写加密位一样,要借助SPM指令,不过之前要借助R 0来设置加密位。

FlashNuk 发表于 2008-9-6 15:42:48

很好

mfkqqw 发表于 2008-11-25 16:35:15

记下

xk2yx 发表于 2008-11-25 16:41:45

不顶不厚道。

zk18too 发表于 2008-11-25 17:56:22

mark一个,谢谢LZ

xu2006 发表于 2008-11-26 19:39:57

强啦LZ

mypostwmw 发表于 2008-11-28 11:25:14

留记号,以后慢慢研究



同时对楼主的无私精神而深受感触

tangqianqian 发表于 2008-11-28 11:42:40

顶一下高手,现在还没研究,备注下!

mfkqqw 发表于 2008-12-9 21:05:52

记一下

Alvinwang 发表于 2009-1-22 18:10:10

mark

luweixuancl 发表于 2009-1-23 09:00:55

标记,谢谢分享!

hecb999 发表于 2009-1-23 10:04:45

谢谢

vv3g 发表于 2009-7-22 11:12:00

学习

tong7127 发表于 2009-9-7 09:17:45

mark

sudan1981 发表于 2009-11-18 13:58:39

强人强贴强坛

lu_zq 发表于 2009-12-24 10:27:03

安啦!

tong7127 发表于 2009-12-24 11:15:23

mark

gxy508 发表于 2009-12-24 12:49:22

mark

vr2whf 发表于 2009-12-29 17:57:44

傻孩子, 可惜你没有winavr/gcc的版本

lv998127 发表于 2009-12-29 19:21:27

有CV版本就好哦

Gorgon_Meducer 发表于 2009-12-29 21:44:34

最后一次更新ICC版本……
点击此处下载 ourdev_520432.rar(文件大小:22K) (原文件名:Flash_EEP.rar)

支持大于64K 的flash读写。
使用新的库函数标准。

使用的时候请保证文件夹结构及其顺序的完整,这样就不存在头文件包含的问题。

使用方法,
#include "HAL\Driver\Flash\Flash.h"

配置文件:
HAL\Driver\Flash\flash_cfg.h

/*! \name ICCAVR bootloader section setting
*/
//! @{
#if defined(_AVR)
# define FLASH_PAGE_SIZE                  256                                 //!< 一个芯片的page大小,单位Byte不是word
# define BL_SPM_FUNCTION_ABS_BLS_ADDR       0x1FFC0                               //!< Bootloader空间内一个任意的地址

# define BL_USE_LOAD_PAGE                   ES_ENABLED                            //!< 控制是否在写一个page之前读出原有内容
# define BL_USE_READ_FUSE_AND_LOCK_BITS   ES_DISABLED                           //!< 是否开启fuse和lock bits的读取功能
# define BL_USE_READ_SIGNATURE            ES_DISABLED                           //!< 是否开启signature的读取功能
# define BL_USE_WRITE_LOCK_BITS             ES_DISABLED                           //!< 在单片机支持的情况下,开启lockbits的写功能
# define BL_CRC16_SERVICE_SUPPORT         ES_DISABLED                           //!< 是否开启CRC16校验函数
# define BL_XOR_SERVICE_SUPPORT             ES_DISABLED                           //!< 开启异或校验函数,与CRC16不能同时开启
# define BL_CANCEL_AUTO_FORMAT_ADDRESS      ES_ENABLED                            //!< 关闭地址对齐,也就是说允许操作任意地址
# define BL_USE_CHIP_ERASE                  ES_DISABLED                           //!< 开启片擦除功能
# define BL_USE_PAGE_VERIFY               ES_ENABLED                            //!< 开启写入后自动校验的功能
# define BL_USE_EXTEND_ADDRESS_SPACE      ES_ENABLED                            //!< 开启对大于64K空间操作的支持
#endif
//! @}

yunlong 发表于 2009-12-29 22:48:13

顶下

plc_avr 发表于 2009-12-30 08:52:12

傻孩子的大作一定要顶。MARK!!!

kouxiangtang 发表于 2009-12-30 08:59:24

不错,鼎!

zhuyi2576 发表于 2009-12-30 19:33:15

好!!!!!!!!!!!

ljqlaq 发表于 2009-12-30 20:23:56

mark

kingsabbit 发表于 2009-12-30 20:43:40

很好的东西

chinamanzhong 发表于 2009-12-30 21:49:05

thanks

Dream_catcher 发表于 2009-12-30 22:35:30

好!

omni 发表于 2010-1-5 14:54:40

学习了,慢慢看

skyxjh 发表于 2010-1-6 13:47:16

学习MARK

wcm_e 发表于 2010-1-6 16:26:37

mark

smartzou 发表于 2010-1-6 18:24:23

mark

sonna 发表于 2010-1-6 22:46:53

记号!

ju748 发表于 2010-1-7 12:45:47

记号!

zek_sj 发表于 2010-2-3 11:29:43

我顶我顶我顶!

lv998127 发表于 2010-2-3 13:37:42

mark

swan1225 发表于 2010-2-3 14:23:51

mark

wkxu 发表于 2010-2-3 14:39:12

mark

sunmy 发表于 2010-2-6 09:45:12

ding!

281229961 发表于 2010-2-6 10:42:45

好东西

zhuimeng08 发表于 2010-2-6 15:03:38

学习一下

beer 发表于 2010-2-6 16:09:37

mark.

hamipeter 发表于 2010-2-7 20:05:29

向楼主学习,再接再历争取早日搞懂!!

motion_ctrl 发表于 2010-2-7 23:36:36

mark

skyue4me 发表于 2010-2-20 15:54:58

mark

suzhwt 发表于 2010-2-20 16:39:17

哇三,程序书写风格值得我多学习

顶一下。

zhuwei310600 发表于 2010-2-20 21:16:37

mark

liyfmc 发表于 2010-2-20 23:07:16

ding我顶

damoplus 发表于 2010-2-20 23:33:41

顶!MARK

51mcu2008 发表于 2010-2-21 05:20:27

非常感谢分享,学习中。。。

382383706 发表于 2010-2-23 08:46:01

mark

weiqiumei 发表于 2010-2-25 14:53:07

我很想用M8自升级,但一直都找不到例子,M48芯片我又没有,唉!

hpdell 发表于 2010-3-20 16:14:06

谢谢!!!!!!!!!!!!!

huanhuan 发表于 2010-3-20 16:37:02

楼主非常强!

ddapw 发表于 2010-3-20 16:48:28

mark
非常感谢,正学习中、、、

moon0213 发表于 2010-3-20 17:23:51

先mark

382383706 发表于 2010-3-30 17:31:39

mark

gdmfq 发表于 2010-3-31 20:19:35

SDM

smartzou 发表于 2010-4-2 09:41:23

mark~

smartzou 发表于 2010-4-15 22:01:09

嘿好~~

wangwish 发表于 2010-8-6 21:46:51

mark

wenfeiexe 发表于 2010-8-15 23:44:06

COOL

sunmeng29 发表于 2010-8-26 16:12:27

好东西!

hungalan 发表于 2010-9-6 16:16:14

留下

gale 发表于 2010-9-6 16:29:45

标记

danielmi 发表于 2010-9-6 18:33:19

收藏了!!

andrew_dj 发表于 2010-9-6 20:47:37

记号

yywin 发表于 2010-10-4 11:16:41

mark

worldly_guest 发表于 2010-10-4 20:26:33

mark
页: [1] 2
查看完整版本: [开源][交流]AVR Bootloader底层驱动函数库,送给ICCAVR的用户 2009最后一次更新