搜索
bottom↓
回复: 114

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

[复制链接]

出0入296汤圆

发表于 2008-9-1 17:07:57 | 显示全部楼层 |阅读模式
#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[FLASH_PAGE_SIZE],
            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

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入296汤圆

 楼主| 发表于 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[FLASH_PAGE_SIZE],
            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[FLASH_PAGE_SIZE],
                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[FLASH_PAGE_SIZE],
            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[FLASH_PAGE_SIZE],
                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[FLASH_PAGE_SIZE] = {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);
}

出0入296汤圆

 楼主| 发表于 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[FLASH_PAGE_SIZE],
            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[FLASH_PAGE_SIZE * 2] = {0};
    UINT16 chCounter = 0;

    System_INIT();                                          //代码初始化

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

出0入0汤圆

发表于 2008-9-1 17:28:34 | 显示全部楼层
谢谢,谢谢

出0入0汤圆

发表于 2008-9-1 17:55:54 | 显示全部楼层
说明很相近

出0入42汤圆

发表于 2008-9-1 18:14:14 | 显示全部楼层
记号.

出0入0汤圆

发表于 2008-9-1 20:11:16 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2008-9-1 20:49:46 | 显示全部楼层

出0入0汤圆

发表于 2008-9-1 21:14:10 | 显示全部楼层
记号备用

出0入0汤圆

发表于 2008-9-1 21:15:24 | 显示全部楼层
坚决收下,就是不知道跟AVRUBD有什么不同。

出0入296汤圆

 楼主| 发表于 2008-9-1 21:20:31 | 显示全部楼层
这是一个底层函数,方便你开发自己的Bootloader。
也就是说,这只算一个驱动Bootloader模块的驱动函数。你不需要过问具体的Bootloader
操作细节。如何去组织您的Bootloader,比如通过SPI、I2C还是串口、USB甚至从FAT32文
件系统来升级,就是您自己的工作了。

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

出0入0汤圆

发表于 2008-9-1 21:31:57 | 显示全部楼层
谢谢谢谢,等的就是肯定的解释,看来我的理解能力还行,哇哈哈~~

出0入296汤圆

 楼主| 发表于 2008-9-1 21:33:38 | 显示全部楼层
to 【11楼】 avenbbs
    最好有使用的反馈,如果你有什么修改的建议,最好分享一下,问题是越
辩越明哈。

出0入0汤圆

发表于 2008-9-1 21:37:22 | 显示全部楼层
不瞒您说,我的工作是控制方面的,这些都是业余爱好,有时间才能玩玩,兴许能找到一条新出路,呵呵~~~

出0入296汤圆

 楼主| 发表于 2008-9-1 21:38:06 | 显示全部楼层
to 【13楼】 avenbbs
    我也是搞控制的哈。主要是机器人运动控制之类的……

出0入0汤圆

发表于 2008-9-1 21:41:18 | 显示全部楼层
【14楼】 Gorgon Meducer 傻孩子

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

出0入296汤圆

 楼主| 发表于 2008-9-1 22:24:55 | 显示全部楼层
to 【15楼】 avenbbs
    别……你听说过半坛醋晃啊晃得说法吗?我的也就是大学生自己玩玩的自动机械。
其实算不得机器人哈……

出0入0汤圆

发表于 2008-9-2 09:00:48 | 显示全部楼层

出0入296汤圆

 楼主| 发表于 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[FLASH_PAGE_SIZE] = {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[FLASH_PAGE_SIZE] = {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;
}

出0入296汤圆

 楼主| 发表于 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)

出0入0汤圆

发表于 2008-9-3 11:30:42 | 显示全部楼层
请问:广告时间的那本书是你写的吗?

出0入296汤圆

 楼主| 发表于 2008-9-3 11:33:18 | 显示全部楼层
to 【20楼】 maxking
    是我和我的师兄一起写的。我是第二作者,主要负责软件部分的内容。

出0入0汤圆

发表于 2008-9-3 11:43:20 | 显示全部楼层
这本书对初学者适用不?

出0入22汤圆

发表于 2008-9-3 11:46:55 | 显示全部楼层
谢谢。

出0入296汤圆

 楼主| 发表于 2008-9-3 11:47:48 | 显示全部楼层
to 【22楼】 maxking  
    这本书完全就是面向初学者写的。^_^你可以问问论坛上已经看过书的人哈。

出0入0汤圆

发表于 2008-9-3 11:49:24 | 显示全部楼层
呵呵,这本书在卓越还便宜几毛钱。以前在卓越有个帐户的,已经下订单了,等待货到付款ing。

出0入296汤圆

 楼主| 发表于 2008-9-3 11:50:05 | 显示全部楼层
to 【25楼】 maxking
    期待您的反馈哈。

出0入0汤圆

发表于 2008-9-5 20:41:25 | 显示全部楼层
向楼主致敬, 我最近看了几个AVR BOOT的资料, 始终未理解BOOT时怎么自修改加密位及读出加密位, 请指点一下, 方便的话帮忙写个读写MAGE8和MAGE128的加密位函数.谢谢先啦!

出0入0汤圆

发表于 2008-9-5 21:09:17 | 显示全部楼层
好东西,现在还没有玩到那个深度,所以作个记号以备后用。

出0入0汤圆

发表于 2008-9-6 00:14:28 | 显示全部楼层
学习中,谢谢!

出0入296汤圆

 楼主| 发表于 2008-9-6 00:29:43 | 显示全部楼层
加密位的读取要查阅LPM指令,这个指令是允许带参数的,比如读取数据到指定的寄存器。写加密位一样,要借助SPM指令,不过之前要借助R 0来设置加密位。

出0入0汤圆

发表于 2008-9-6 15:42:48 | 显示全部楼层
很好

出0入0汤圆

发表于 2008-11-25 16:35:15 | 显示全部楼层
记下

出0入0汤圆

发表于 2008-11-25 16:41:45 | 显示全部楼层
不顶不厚道。

出0入0汤圆

发表于 2008-11-25 17:56:22 | 显示全部楼层
mark一个,谢谢LZ

出0入0汤圆

发表于 2008-11-26 19:39:57 | 显示全部楼层
强啦LZ

出0入0汤圆

发表于 2008-11-28 11:25:14 | 显示全部楼层
留记号,以后慢慢研究



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

出0入0汤圆

发表于 2008-11-28 11:42:40 | 显示全部楼层
顶一下高手,现在还没研究,备注下!

出0入0汤圆

发表于 2008-12-9 21:05:52 | 显示全部楼层
记一下

出0入0汤圆

发表于 2009-1-22 18:10:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-1-23 09:00:55 | 显示全部楼层
标记,谢谢分享!

出0入0汤圆

发表于 2009-1-23 10:04:45 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2009-7-22 11:12:00 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-9-7 09:17:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-18 13:58:39 | 显示全部楼层
强人强贴强坛

出0入0汤圆

发表于 2009-12-24 10:27:03 | 显示全部楼层
安啦!

出0入0汤圆

发表于 2009-12-24 11:15:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-24 12:49:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-29 17:57:44 | 显示全部楼层
傻孩子, 可惜你没有winavr/gcc的版本

出0入0汤圆

发表于 2009-12-29 19:21:27 | 显示全部楼层
有CV版本就好哦

出0入296汤圆

 楼主| 发表于 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
//! @}

出0入0汤圆

发表于 2009-12-29 22:48:13 | 显示全部楼层
顶下

出0入0汤圆

发表于 2009-12-30 08:52:12 | 显示全部楼层
傻孩子的大作一定要顶。MARK!!!

出0入0汤圆

发表于 2009-12-30 08:59:24 | 显示全部楼层
不错,鼎!

出0入0汤圆

发表于 2009-12-30 19:33:15 | 显示全部楼层
好!!!!!!!!!!!

出0入0汤圆

发表于 2009-12-30 20:23:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-30 20:43:40 | 显示全部楼层
很好的东西

出0入0汤圆

发表于 2009-12-30 21:49:05 | 显示全部楼层
thanks

出0入0汤圆

发表于 2009-12-30 22:35:30 | 显示全部楼层
好!

出0入0汤圆

发表于 2010-1-5 14:54:40 | 显示全部楼层
学习了,慢慢看

出0入0汤圆

发表于 2010-1-6 13:47:16 | 显示全部楼层
学习MARK

出0入0汤圆

发表于 2010-1-6 16:26:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-6 18:24:23 | 显示全部楼层
mark

出0入59汤圆

发表于 2010-1-6 22:46:53 | 显示全部楼层
记号!

出0入0汤圆

发表于 2010-1-7 12:45:47 | 显示全部楼层
记号!

出0入0汤圆

发表于 2010-2-3 11:29:43 | 显示全部楼层
我顶我顶我顶!

出0入0汤圆

发表于 2010-2-3 13:37:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-3 14:23:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-3 14:39:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-6 09:45:12 | 显示全部楼层
ding!

出0入0汤圆

发表于 2010-2-6 10:42:45 | 显示全部楼层
好东西

出0入0汤圆

发表于 2010-2-6 15:03:38 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2010-2-6 16:09:37 | 显示全部楼层
mark.

出0入0汤圆

发表于 2010-2-7 20:05:29 | 显示全部楼层
向楼主学习,再接再历争取早日搞懂!!

出0入0汤圆

发表于 2010-2-7 23:36:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-20 15:54:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-20 16:39:17 | 显示全部楼层
哇三,程序书写风格值得我多学习

顶一下。

出0入0汤圆

发表于 2010-2-20 21:16:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-20 23:07:16 | 显示全部楼层
ding  我顶

出0入0汤圆

发表于 2010-2-20 23:33:41 | 显示全部楼层
顶!MARK

出0入0汤圆

发表于 2010-2-21 05:20:27 | 显示全部楼层
非常感谢分享,学习中。。。

出0入0汤圆

发表于 2010-2-23 08:46:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-25 14:53:07 | 显示全部楼层
我很想用M8自升级,但一直都找不到例子,M48芯片我又没有,唉!

出0入0汤圆

发表于 2010-3-20 16:14:06 | 显示全部楼层
谢谢!!!!!!!!!!!!!

出0入0汤圆

发表于 2010-3-20 16:37:02 | 显示全部楼层
楼主非常强!

出0入0汤圆

发表于 2010-3-20 16:48:28 | 显示全部楼层
mark
非常感谢,正学习中、、、

出0入0汤圆

发表于 2010-3-20 17:23:51 | 显示全部楼层
先mark

出0入0汤圆

发表于 2010-3-30 17:31:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-31 20:19:35 | 显示全部楼层
SDM

出0入0汤圆

发表于 2010-4-2 09:41:23 | 显示全部楼层
mark~

出0入0汤圆

发表于 2010-4-15 22:01:09 | 显示全部楼层
嘿好~~

出0入0汤圆

发表于 2010-8-6 21:46:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-15 23:44:06 | 显示全部楼层
COOL

出0入0汤圆

发表于 2010-8-26 16:12:27 | 显示全部楼层
好东西!

出0入0汤圆

发表于 2010-9-6 16:16:14 | 显示全部楼层
留下

出0入0汤圆

发表于 2010-9-6 16:29:45 | 显示全部楼层
标记

出0入0汤圆

发表于 2010-9-6 18:33:19 | 显示全部楼层
收藏了!!

出0入0汤圆

发表于 2010-9-6 20:47:37 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-10-4 11:16:41 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-27 03:52

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

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