sibtck 发表于 2012-7-12 12:12:31

求读取AVR中唯一序列号的函数,加密用的.....

从手册上看ATMEGA48PA,88PA,168AP是有一个序列号可以在程序空间的代码中进行读取用来加密的.搞了两天了也没成功读取....
求这样的函数....
谢谢大家.

cos 发表于 2012-7-12 12:19:55

不知道的頂一下。

sibtck 发表于 2012-7-12 12:33:52

sibtck 发表于 2012-7-12 13:34:34

顶一下...

sibtck 发表于 2012-7-12 15:15:15

顶一下.

Gorgon_Meducer 发表于 2012-7-12 15:44:41

读14开始的10个字节……

sibtck 发表于 2012-7-12 16:07:03

Gorgon_Meducer 发表于 2012-7-12 15:44 static/image/common/back.gif
读14开始的10个字节……

大神来啦!
求大神给个代码的例子.....我写了两天多了.......无法搞定.....

qhshilin 发表于 2012-7-12 18:11:00

关注中……

weuser 发表于 2012-7-12 18:27:32

boot.h的头文件有。boot_signature_byte_get(addr)

sibtck 发表于 2012-7-12 20:51:17

weuser 发表于 2012-7-12 18:27 static/image/common/back.gif
boot.h的头文件有。boot_signature_byte_get(addr)

试了.不行啊...
直接提示../main.c:191: error: 'SIGRD' undeclared (first use in this function)

feiben 发表于 2012-7-12 21:25:09

Gorgon_Meducer 发表于 2012-7-12 15:44 static/image/common/back.gif
读14开始的10个字节……

大师级的还没讲话,都不要急

sibtck 发表于 2012-7-12 21:53:21

weuser 发表于 2012-7-12 18:27 static/image/common/back.gif
boot.h的头文件有。boot_signature_byte_get(addr)

翻了N久的手删没有看到SIGRD这个位的定义在哪个地方.手册中那里是第一次出现这个词.前面也没有描述过.求大侠指点.

robot77 发表于 2012-7-12 22:50:35

R_OSCCAL        =OSCCAL;

weuser 发表于 2012-7-13 12:08:08

本帖最后由 weuser 于 2012-7-13 12:39 编辑

MEGA48的 SIGRD位作为保留位了,我把这个位跳过去试读。
我修改了boot.h文件
#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
改成下面的。

#if defined(__AVR_ATmega48__)
#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE))
#else
#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
#endif

然后
       Signature = boot_signature_byte_get(0);
        Signature = boot_signature_byte_get(2);
        Signature = boot_signature_byte_get(4);
        Signature = boot_signature_byte_get(1);

读出来 0x19 0xD9 0x32 0xC0这个和ISP读出来的不一样。
MEGA48应该是不支持内部读的。


feiben 发表于 2012-7-13 19:44:21

跟着走,找感觉

guolun 发表于 2012-7-13 20:23:26

我有个产品,先给客户使用,全部付款以后,发短信给一串数字,输入数字就可以解除使用次数的限制。我想用这个序列号,实现这个功能,希望大家探讨一下。

sibtck 发表于 2012-7-13 20:51:31

weuser 发表于 2012-7-13 12:08 static/image/common/back.gif
MEGA48的 SIGRD位作为保留位了,我把这个位跳过去试读。
我修改了boot.h文件
#define __BOOT_SIGROW_READ...

48没有,你读48PA试试!

sibtck 发表于 2012-7-13 21:03:46

以后做产品一定要用PA后缀的,强大的一B,有唯一序列号,还内建温度传感器!!!!!

feiben 发表于 2012-7-13 21:11:43

guolun 发表于 2012-7-13 20:23 static/image/common/back.gif
我有个产品,先给客户使用,全部付款以后,发短信给一串数字,输入数字就可以解除使用次数的限制。我想用这 ...

       不需要你去   要涨(账)了

Gorgon_Meducer 发表于 2012-7-13 23:59:53

feiben 发表于 2012-7-12 21:25 static/image/common/back.gif
大师级的还没讲话,都不要急

还是那句话:只要芯片数据手册说能通过bootloader读取Signature Byte,就能通过这个手段读14开始的10个字节……这就是芯片的唯一ID。
如果你知道如何通过ISP时序读取Signature Byte,那么同样道理,你肯定能读取到地址14开始的10个字节……

robocon 发表于 2012-7-14 00:52:22

喔,,,avr也有这功能

wangfriend 发表于 2012-7-14 17:49:18

sibtck 发表于 2012-7-13 21:03 static/image/common/back.gif
以后做产品一定要用PA后缀的,强大的一B,有唯一序列号,还内建温度传感器!!!!! ...

mega88PA 真有温度内部传感器么?
我原来一直以为只加了唯一序列号。 我是替换原来的老型号,加的功能基本没有注意。

wzyllgx 发表于 2012-7-14 18:02:49

.我跟楼上刚好相反,我只注意到有内部温度传感器,没注意到唯一序列号。

wangfriend 发表于 2012-7-14 20:25:29

看来真有内部温度传感器。
原来手头有一份更新英文文档,英文不好,就没有仔细看。

1139193886 发表于 2014-12-19 19:36:02

下载了,非常感谢

1139193886 发表于 2014-12-19 19:43:47

Gorgon_Meducer 发表于 2012-7-13 23:59
还是那句话:只要芯片数据手册说能通过bootloader读取Signature Byte,就能通过这个手段读14开始的10个字 ...

在ICCAVR下如何读出来呢,请大师指点一下

Gorgon_Meducer 发表于 2014-12-20 16:14:48

1139193886 发表于 2014-12-19 19:43
在ICCAVR下如何读出来呢,请大师指点一下

用asm() 写在线汇编

无衣师伊 发表于 2014-12-20 16:31:55

{:titter:}

1139193886 发表于 2014-12-22 21:42:58

Gorgon_Meducer 发表于 2014-12-20 16:14
用asm() 写在线汇编

求大神指点啊,汇编下如何写呢,不懂汇编,可以帮忙写这个代码吗?谢谢。

Gorgon_Meducer 发表于 2014-12-22 22:27:41

1139193886 发表于 2014-12-22 21:42
求大神指点啊,汇编下如何写呢,不懂汇编,可以帮忙写这个代码吗?谢谢。 ...

我没有写过ICC的汇编……

Gorgon_Meducer 发表于 2014-12-22 22:28:43

无衣师伊 发表于 2014-12-20 16:31


只要能读这个,就可以继续向后读取隐藏的signature row,里面有很多有趣的信息。我记得大约偏移量是14的地方,连续10个字节就是UID

1139193886 发表于 2014-12-22 22:29:13

Gorgon_Meducer 发表于 2014-12-22 22:27
我没有写过ICC的汇编……

汇编应该是通用的吧,其它编译器下面的汇编也应该可以编过去吧。

Gorgon_Meducer 发表于 2014-12-22 22:37:03

1139193886 发表于 2014-12-22 22:29
汇编应该是通用的吧,其它编译器下面的汇编也应该可以编过去吧。

不同编译器语法不同的。

1139193886 发表于 2014-12-22 22:47:06

Gorgon_Meducer 发表于 2014-12-22 22:37
不同编译器语法不同的。

哦,谢谢。我再想想办法吧

1139193886 发表于 2014-12-26 10:58:13

Gorgon_Meducer 发表于 2014-12-22 22:37
不同编译器语法不同的。

可以请再帮个忙吗,其它编译环境下的汇编代码可以帮忙写下吗,我转到icc下用。实在不知道这个SN读的顺序和操作方法。,主要看指令和执行的流程,或者让画个时序图都行。

Gorgon_Meducer 发表于 2014-12-26 13:29:28

1139193886 发表于 2014-12-26 10:58
可以请再帮个忙吗,其它编译环境下的汇编代码可以帮忙写下吗,我转到icc下用。实在不知道这个SN读的顺 ...


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


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

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

/*------------------*
*   常 数 宏 定 义*
*------------------*/
#ifndef SIGRD
    # define SIGRD            5
#endif

# 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_FUSE_AND_LOCK_BITS (BIT(BLBSET)|BIT(SPMEN))
# define SPM_WRITE_BUFFER       BIT(SPMEN)
# define SPM_READ_SIGNATURE   (BIT(SIGRD)|BIT(SPMEN))


#ifndef FLASH_PAGE_SIZE
    # error No define FLASH_PAGE_SIZE
#endif



#ifndef SPMCSR
    # define SPMCSR   SPMCR
#endif
#ifndef EEPE
   # define EEPE      EEWE
#endif

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

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

/********************
*   函 数 声 明 区*
********************/
#if BL_USE_PAGE_VERIFY == ENABLE
BOOL Bootloader_Flash_Page_Verify
      (
            BYTE *pchDataBuffer,
            #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
            UINT32 dwAddress
            #else
            UINT16 wAddress
            #endif
      );
#endif
#if BL_USE_LOAD_PAGE == ENABLE
#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,
            #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
            UINT32 dwAddress
            #else
            UINT16 wAddress
            #endif
      );
#endif   
BOOL Bootloader_Write_Page
            (
                void *pData,
                UINT16 wLength,
                #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                UINT32 dwAddress
                #else
                UINT16 wAddress
                #endif
            );
void Bootloader_Put_INT_Vector_Into_APPS(void);
void Bootloader_Put_INT_Vector_Into_BLS(void);

#if BL_USE_READ_FUSE_AND_LOCK_BITS == ENABLE
UINT8 Bootloader_Read_Fuse(UINT16 wIndex);
#endif
#if BL_USE_READ_FUSE_AND_LOCK_BITS == ENABLE
UINT8 Bootloader_Read_Signature(UINT16 wIndex);
#endif
#if BL_USE_WRITE_LOCK_BITS == ENABLE
void Bootloader_Write_Lock_Bits(UINT8 chLockBits);
#endif
#if defined(BOOTLOADER_USE_CRC16) || (BL_CRC16_SERVICE_SUPPORT == ENABLE)
UINT16 CRC16_Check(UINT16 *pwCRCValue,BYTE chData);
#endif
#if BL_USE_CHIP_ERASE == ENABLE
#if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
void Bootloader_Chip_Erase(UINT32 dwMaxAddress);
#else
void Bootloader_Chip_Erase(UINT16 wMaxAddress);
#endif
#endif
/********************
*   模块函数声明区*
********************/
static void Do_Boot_Loader_Action(UINT8 chFunction);

static BOOL Fill_Page_Buffer
            (
                BYTE chDataBuffer,
                #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                UINT32 dwAddress
                #else
                UINT16 wAddress
                #endif
            );
   
/********************
*   模块变量声明区*
********************/

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

#if defined(BOOTLOADER_USE_CRC16) || (BL_CRC16_SERVICE_SUPPORT == ENABLE)
/***********************************************************
*   函数说明:CRC16单数据处理函数                        *
*   输入:      保存CRC校验值的地址,新的数据            *
*   输出:      CRC交验                                    *
*   调用函数:无                                       *
***********************************************************/
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))
    {
      asm("wdr");
    }
   
    SAFE_CODE_PERFORMANCE
    (
      while(EECR & BIT(EEWE))
      {
            asm("wdr");
      }
      SPMCSR = chFunction;
      asm("spm");
    )
}

#if BL_USE_CHIP_ERASE == ENABLE
/***********************************************************
*   函数说明:片擦除函数                                 *
*   输入:      擦除时不能越过的地址                     *
*   输出:      无                                       *
*   调用函数:Do_Boot_Loader_Action                      *
***********************************************************/
#if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
void Bootloader_Chip_Erase(UINT32 dwMaxAddress)
#else
void Bootloader_Chip_Erase(UINT16 wMaxAddress)
#endif
{
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    UINT32 dwAddress;
    UINT8 TRAMPZ = RAMPZ;
    for (
            dwAddress = 0;
            dwAddress < dwMaxAddress;
            dwAddress += FLASH_PAGE_SIZE
      )
    {
      UINT16 wAddress = dwAddress;
      RAMPZ = dwAddress>>16;
      asm("movw r30,%wAddress");      
      Do_Boot_Loader_Action(SPM_PAGE_ERASE);
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
      WDR();
    }
    RAMPZ = TRAMPZ;
   
    #else
    UINT16 wAddress;   
    for (
            wAddress = 0;
            wAddress < wMaxAddress;
            wAddress += FLASH_PAGE_SIZE
      )
    {
      /* 将地址保存到Z寄存器 */
      asm("movw r30,%wAddress");
      WDR();
      Do_Boot_Loader_Action(SPM_PAGE_ERASE);
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
    }
    #endif
}
#endif

#if BL_USE_LOAD_PAGE == ENABLE
/*-----------------------------------------------------------------------------*
*Function Description:                                                      *
*      Load a specified page to a page buffer.                              *
*Parameters:                                                                *
*      chDataBuffer      the page buffer.                                 *
*      dwAddress/wAddressthe target page address.                           *
*Return                                                                     *
*      CRC16 / XOR / None                                                   *
*----------------------------------------------------------------------------*/
#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
      (
            UINT8 chDataBuffer,
            #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
            UINT32 dwAddress
            #else
            UINT16 wAddress
            #endif
      )
{
    UINT16 wCounter = FLASH_PAGE_SIZE;
    #if defined(BOOTLOADER_USE_CRC16)
    UINT16 wTempCRC = CRC_INIT;
    UINT8 chData;
    #elif defined(BOOTLOADER_USE_XOR)
    UINT8 chXOR = 0;
    #endif
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    UINT8 TRAMPZ = RAMPZ;
    #endif
   
    #if !defined(BOOTLOADER_USE_CRC16) && !defined(BOOTLOADER_USE_XOR)
    if (chDataBuffer == NULL)
    {
      //! in none checking model, a null buffer means nothing.
      return ;
    }
    #endif
   
    //! Enable RWW write
    while(SPMCSR & BIT(RWWSB))
    {
      Do_Boot_Loader_Action(SPM_ENBALE_RWW);
    }
    asm("push r30");
    asm("push r31");
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    RAMPZ = dwAddress >> 16;
    #endif
    //! load address to z register
    asm("movw r30,r18");
    //! load buffer address to x register
    asm("movw r26,r16");
#if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
   
    if (chDataBuffer != NULL)
    {
      #ifdef BOOTLOADER_USE_XOR
      //! Initialize the xor checking result register
      asm("ldi r1,0");
      #endif
      if (RAMPZ)
      {
            while(wCounter--)
            {
                WDR();
                //! load value from flash (addressed by z register)
                asm("elpm r0,z+");
                //! save the value to sram (address by x register)
                asm("st x+,r0");
                //! do checking function if necessary
                #if defined(BOOTLOADER_USE_CRC16)
                //! use chData as a temporary variable
                asm("mov %chData,r0");
                //! calculate the crc16 value
                CRC(wTempCRC,chData);
                #elif defined (BOOTLOADER_USE_XOR)
                //! xor
                asm("eor r1,r0");
                #endif
            }
      }
      else
      {
            while(wCounter--)
            {
                WDR();
                //! load value from flash (addressed by z register)
                asm("lpm r0,z+");
                //! save the value to sram (address by x register)
                asm("st x+,r0");
                //! do checking function if necessary
                #if defined(BOOTLOADER_USE_CRC16)
                //! use chData as a temporary variable
                asm("mov %chData,r0");
                //! calculate the crc16 value
                CRC(wTempCRC,chData);
                #elif defined (BOOTLOADER_USE_XOR)
                //! xor
                asm("eor r1,r0");
                #endif
            }
      }
      #ifdef BOOTLOADER_USE_XOR
      //! save the xor checking result to variable chXOR
      asm("mov %chXOR,r1");
      #endif
    }
    else
    {
      //! do checking function if necessary
      #if defined(BOOTLOADER_USE_CRC16)
      if (RAMPZ)
      {
            while(wCounter--)
            {
                WDR();
                //! load value from flash (addressed by z register)
                asm("elpm r0,z+");
                //! use chData as a temporary variable
                asm("mov %chData,r0");
                //! calculate the crc16 value
                CRC(wTempCRC,chData);
            }
      }
      else
      {
            while(wCounter--)
            {
                WDR();
                //! load value from flash (addressed by z register)
                asm("lpm r0,z+");
                //! use chData as a temporary variable
                asm("mov %chData,r0");
                //! calculate the crc16 value
                CRC(wTempCRC,chData);
            }
      }
      #elif defined (BOOTLOADER_USE_XOR)
      //! Initialize the xor checking result register
      if (RAMPZ)
      {
            asm("ldi r1,0");
            while(wCounter--)
            {
                WDR();
                //! load a byte from flash to r0 (addressed by z register)
                asm("elpm r0,z+");
                //! xor
                asm("eor r1,r0");
            }
            //! save the xor checking result to variable chXOR
            asm("mov %chXOR,r1");
      }
      else
      {
            asm("ldi r1,0");
            while(wCounter--)
            {
                WDR();
                //! load a byte from flash to r0 (addressed by z register)
                asm("lpm r0,z+");
                //! xor
                asm("eor r1,r0");
            }
            //! save the xor checking result to variable chXOR
            asm("mov %chXOR,r1");
      }
      #endif
    }
    RAMPZ = TRAMPZ;
   
#else
    if (chDataBuffer != NULL)
    {
      #ifdef BOOTLOADER_USE_XOR
      //! Initialize the xor checking result register
      asm("ldi r1,0");
      #endif
      while(wCounter--)
      {
            WDR();
            //! load value from flash (addressed by z register)
            asm("lpm r0,z+");
            //! save the value to sram (address by x register)
            asm("st x+,r0");
            //! do checking function if necessary
            #if defined(BOOTLOADER_USE_CRC16)
            //! use chData as a temporary variable
            asm("mov %chData,r0");
            //! calculate the crc16 value
            CRC(wTempCRC,chData);
            #elif defined (BOOTLOADER_USE_XOR)
            //! xor
            asm("eor r1,r0");
            #endif
      }
      #ifdef BOOTLOADER_USE_XOR
      //! save the xor checking result to variable chXOR
      asm("mov %chXOR,r1");
      #endif
    }
    else
    {
      //! do checking function if necessary
      #if defined(BOOTLOADER_USE_CRC16)
      while(wCounter--)
      {
            WDR();
            //! load value from flash (addressed by z register)
            asm("lpm r0,z+");
            //! use chData as a temporary variable
            asm("mov %chData,r0");
            //! calculate the crc16 value
            CRC(wTempCRC,chData);
      }
      #elif defined (BOOTLOADER_USE_XOR)
      //! Initialize the xor checking result register
      asm("ldi r1,0");
      while(wCounter--)
      {
            WDR();
            //! load a byte from flash to r0 (addressed by z register)
            asm("lpm r0,z+");
            //! xor
            asm("eor r1,r0");
      }
      //! save the xor checking result to variable chXOR
      asm("mov %chXOR,r1");
      #endif
    }
#endif
    asm("pop r31");
    asm("pop r30");
   
    #if defined(BOOTLOADER_USE_CRC16)
    return wTempCRC;
    #elif defined(OOTLOADER_USE_XOR)
    return chXOR;
    #endif
}
#endif


//#pragma abs_address: BL_VECTOR_FREE_TEXT_ADDRESS

/***********************************************************
*   函数说明:向页缓冲区写入数据函数                     *
*   输入:      缓冲区指针,要写入的地址                   *
*   输出:      写入是否成功                               *
*   调用函数:无                                       *
***********************************************************/
static BOOL Fill_Page_Buffer
            (
                BYTE chDataBuffer,
                #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                UINT32 dwAddress
                #else
                UINT16 wAddress
                #endif
            )
{
    UINT8 chCounter = (FLASH_PAGE_SIZE>>1);
   
    if (chDataBuffer == NULL)
    {
      return FALSE;
    }
   
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    dwAddress &= ~((UINT32)(FLASH_PAGE_SIZE - 1));
    #else
    wAddress &= ~((UINT16)(FLASH_PAGE_SIZE - 1));
    #endif
    //! load zero value to z register
    asm("ldi r30,0");
    //! load the page buffer address to x register
    asm("movw r26,r16");
    while(chCounter--)
    {
      WDR();
      //! load half word(2bytes) from sram to R0 register (addressed by x register)
      asm("ld r0,x+");
      asm("ld r1,x+");
      //! save the half word to flash page buffer
      Do_Boot_Loader_Action(SPM_WRITE_BUFFER);
      //! increase the flash page buffer writing pointer.
      asm("adiw r30,2");
    }
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    RAMPZ = dwAddress >> 16;
    #endif
    //! save a address to z register
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    {
      UINT8 A = ((UINT8 *)&dwAddress);
      UINT8 B = ((UINT8 *)&dwAddress);
      asm("mov r30,%A");
      asm("mov r31,%B");
    }
    #else
    asm("movw r30,r18");
    #endif

    return TRUE;
}
//#pragma end_abs_address

#if BL_USE_PAGE_VERIFY == ENABLE
/***********************************************************
*   函数说明:页面校验函数                               *
*   输入:      源页面缓冲区,目标地址                     *
*   输出:      校验是否成功                               *
*   调用函数:无                                       *
***********************************************************/
BOOL Bootloader_Flash_Page_Verify
      (
            BYTE *pchDataBuffer,
            #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
            UINT32 dwAddress
            #else
            UINT16 wAddress
            #endif
      )
{
    UINT16 wCounter = FLASH_PAGE_SIZE;
    UINT8 chDataA;
    UINT8 chDataB;
   
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    UINT8 TRAMPZ = RAMPZ;
    #endif
    if (pchDataBuffer == NULL)
    {
      //! have nothing to do with...
      return FALSE;
    }
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    RAMPZ = dwAddress >> 16;
    #endif
    //! load the address to z register
    asm("movw r30,r18");
    //! load the buffer address to x register
    asm("movw r26,r16");
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    if (RAMPZ)
    {
      while(wCounter--)
      {
            //! load a byte from flash (addressed by z register)
            asm("elpm r0,z+");
            //! employ a temporary variable chDataA
            asm("mov %chDataA,r0");
            //! load a byte from sram (addressed by x register)
            asm("ld r0,x+");
            //! employ a temporary variable chDataB
            asm("mov %chDataB,r0");
            //! checking...
            if (chDataA != chDataB)
            {
                RAMPZ = TRAMPZ;
                return FALSE;      
            }
            WDR();
      }
    }
    else
    {
      while(wCounter--)
      {
            //! load a byte from flash (addressed by z register)
            asm("lpm r0,z+");
            //! employ a temporary variable chDataA
            asm("mov %chDataA,r0");
            //! load a byte from sram (addressed by x register)
            asm("ld r0,x+");
            //! employ a temporary variable chDataB
            asm("mov %chDataB,r0");
            //! checking...
            if (chDataA != chDataB)
            {
                RAMPZ = TRAMPZ;
                return FALSE;      
            }
            WDR();
      }
    }
    RAMPZ = TRAMPZ;
    #else
    while(wCounter--)
    {
      //! load a byte from flash (addressed by z register)
      asm("lpm r0,z+");
      //! employ a temporary variable chDataA
      asm("mov %chDataA,r0");
      //! load a byte from sram (addressed by x register)
      asm("ld r0,x+");
      //! employ a temporary variable chDataB
      asm("mov %chDataB,r0");
      //! checking...
      if (chDataA != chDataB)
      {
            return FALSE;      
      }
    }
    #endif
    return TRUE;
}
#endif

/***********************************************************
*   函数说明:写入页面函数                               *
*   输入:      缓冲区地址,目标地址                     *
*   输出:      操作是否成功                               *
*   调用函数:                                             *
***********************************************************/
BOOL Bootloader_Write_Page
            (
                void *pData,
                UINT16 wLength,
                #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                UINT32 dwAddress
                #else
                UINT16 wAddress
                #endif
            )
{
    BYTE *pchData = pData;
    BYTE *pchBuffer = NULL;
    #if BL_USE_LOAD_PAGE != ENABLE
    UINT16 wCounter;
    #endif
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    UINT8 TRAMPZ = RAMPZ;
    #endif
    if (pData == NULL)
    {
      return FALSE;
    }
   
    asm("wdr");
   
    #if BL_CANCEL_AUTO_FORMAT_ADDRESS == ENABLE
    //! do not snap the input flash address to page address
    #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
    if ((dwAddress & (FLASH_PAGE_SIZE - 1)) != 0)
    #else
    if ((wAddress & (FLASH_PAGE_SIZE - 1)) != 0)
    #endif
    {
      UINT8 chBuffer;
      
      //! get to know how many bytes are there before a normal page accessing.
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      UINT8 chTempCounter = FLASH_PAGE_SIZE - (dwAddress & (FLASH_PAGE_SIZE - 1));
      #else
      UINT8 chTempCounter = FLASH_PAGE_SIZE - (wAddress & (FLASH_PAGE_SIZE - 1));
      #endif
      if (wLength < chTempCounter)
      {
            chTempCounter = wLength;
      }
      wLength -= chTempCounter;
      
      #if BL_USE_LOAD_PAGE == ENABLE
      Bootloader_Load_Page_Buffer
            (
                chBuffer,
                #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                dwAddress & (~((UINT32)FLASH_PAGE_SIZE - 1))
                #else
                wAddress & (~((UINT16)FLASH_PAGE_SIZE - 1))
                #endif
            );
      #else
      for (wCounter = 0;wCounter < UBOUND(chBuffer);wCounter++)
      {
            chBuffer = 0xFF;
      }
      #endif
      //! copy the data
      //! need to read the page before writing
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      pchBuffer = chBuffer + (dwAddress & (FLASH_PAGE_SIZE - 1));
      #else
      pchBuffer = chBuffer + (wAddress & (FLASH_PAGE_SIZE - 1));
      #endif
      while(chTempCounter--)
      {
            *pchBuffer = *pchData;
            pchBuffer++;
            pchData++;
      }
      
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      SAFE_CODE_PERFORMANCE
      (
            Fill_Page_Buffer(chBuffer,dwAddress);
            Do_Boot_Loader_Action(SPM_PAGE_ERASE);
            Do_Boot_Loader_Action(SPM_PAGE_WRITE);
            Do_Boot_Loader_Action(SPM_ENBALE_RWW);            
      )
      RAMPZ = TRAMPZ;
      #else
      SAFE_CODE_PERFORMANCE
      (
            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);            
      )
      
      #endif
      
      
      WDR();
      #if BL_USE_PAGE_VERIFY == ENABLE
      //! verify the page
      if (
            !Bootloader_Flash_Page_Verify
                (
                  chBuffer,
                  #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                  dwAddress & (~((UINT32)FLASH_PAGE_SIZE - 1))
                  #else
                  wAddress & (~((UINT16)FLASH_PAGE_SIZE - 1))
                  #endif
                )
         )
      {
            //! failed in verifying...
            return FALSE;
      }
      #endif
      
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      dwAddress += FLASH_PAGE_SIZE;
      dwAddress &= (~((UINT32)FLASH_PAGE_SIZE - 1));      
      #else
      wAddress += FLASH_PAGE_SIZE;
      wAddress &= (~((UINT16)FLASH_PAGE_SIZE - 1));
      #endif
      
    }
    #endif

    //! normal page writing access
    while(wLength > FLASH_PAGE_SIZE)
    {
      //! do a page write sequence...
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      SAFE_CODE_PERFORMANCE
      (
            Fill_Page_Buffer(pchData,dwAddress);
            Do_Boot_Loader_Action(SPM_PAGE_ERASE);
            Do_Boot_Loader_Action(SPM_PAGE_WRITE);
            Do_Boot_Loader_Action(SPM_ENBALE_RWW);            
      )
      RAMPZ = TRAMPZ;
      #else
      SAFE_CODE_PERFORMANCE
      (
            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);            
      )
      #endif
      
      #if BL_USE_PAGE_VERIFY == ENABLE
      //! verify the page
      if (
            !Bootloader_Flash_Page_Verify
                (
                  pchData,
                  #if BL_CANCEL_AUTO_FORMAT_ADDRESS == ENABLE
                  #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                  dwAddress
                  #else
                  wAddress
                  #endif
                  #else
                  #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                  dwAddress & (~((uint32_t)FLASH_PAGE_SIZE - 1))
                  #else
                  wAddress & (~((uint16_t)FLASH_PAGE_SIZE - 1))
                  #endif
                  #endif
                )
         )
      {
            //! failed in verifying
            return FALSE;
      }
      #endif
      pchData += FLASH_PAGE_SIZE;
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      dwAddress += FLASH_PAGE_SIZE;
      #else
      wAddress += FLASH_PAGE_SIZE;
      #endif
      wLength -= FLASH_PAGE_SIZE;
    }
   
    if (wLength)
    {
      #if BL_USE_LOAD_PAGE == ENABLE
      UINT8 chBuffer;
      #else
      UINT8 chBuffer;
      #endif
      if (wLength < FLASH_PAGE_SIZE)
      {
            //! need to read the page before writing
            pchBuffer = chBuffer;
      
            #if BL_USE_LOAD_PAGE == ENABLE
            Bootloader_Load_Page_Buffer
                (
                  chBuffer,
                  #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                  dwAddress
                  #else
                  wAddress
                  #endif
                );
            #else
            for (wCounter = 0;wCounter < UBOUND(chBuffer);wCounter++)
            {
                chBuffer = 0xFF;
            }
            #endif
      
            //! copy the data
            while(wLength--)
            {
                *pchBuffer = *pchData;
                pchBuffer++;
                pchData++;
            }
            pchBuffer = chBuffer;
      }
      else
      {
            pchBuffer = pchData;
      }
   
      //! bootloader sequence
      #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
      SAFE_CODE_PERFORMANCE
      (
            Fill_Page_Buffer(pchBuffer,dwAddress);
            Do_Boot_Loader_Action(SPM_PAGE_ERASE);
            Do_Boot_Loader_Action(SPM_PAGE_WRITE);
            Do_Boot_Loader_Action(SPM_ENBALE_RWW);            
      )
      RAMPZ = TRAMPZ;
      #else
      SAFE_CODE_PERFORMANCE
      (
            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);            
      )
      #endif
      #if BL_USE_PAGE_VERIFY == ENABLE
      //! verify the page
      if (
            !Bootloader_Flash_Page_Verify
                (
                        pchBuffer,
                        #if BL_CANCEL_AUTO_FORMAT_ADDRESS == ENABLE
                        #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                        dwAddress
                        #else
                        wAddress
                        #endif
                        #else
                        #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
                        dwAddress & (~((uint32_t)FLASH_PAGE_SIZE - 1))
                        #else
                        wAddress & (~((uint16_t)FLASH_PAGE_SIZE - 1))
                        #endif
                        #endif
                )
      )
      {
            //! failed in verifying
            return FALSE;
      }
      #endif
    }


    return TRUE;
}


/***********************************************************
*   函数说明:将中断向量表放置到Bootloader Section       *
*   输入:      无                                       *
*   输出:      无                                       *
*   调用函数:无                                       *
***********************************************************/
void Bootloader_Put_INT_Vector_Into_BLS(void)
{
#if defined(ATMega32) || defined(ATMega16)
    GICR |= BIT(IVCE);
    GICR = (GICR & (~BIT(IVCE))) | BIT(IVSEL);
#else
    MCUCR |= BIT(IVCE);
    MCUCR = (MCUCR & (~BIT(IVCE))) | BIT(IVSEL);
#endif
}

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

#if BL_USE_WRITE_LOCK_BITS == ENABLE
/***********************************************************
*   函数说明:写Lockbits指令                           *
*   输入:      要写入Lockbits的内容                     *
*   输出:      无                                       *
*   调用函数:Do_Boot_Loader_Action()                  *
***********************************************************/
void Bootloader_Write_Lock_Bits(UINT8 chLockBits)
{
    // 读取LockBits到r0
    asm("mov r0,r16");
    //向Z指针写入0x0001,以保持兼容性
    asm("ldi r30,0x01");
    asm("ldi r31,0x00");
   
    Do_Boot_Loader_Action(SPM_FUSE_AND_LOCK_BITS);
}
#endif

#if BL_USE_READ_SIGNATURE == ENABLE
/***********************************************************
*   函数说明:读取芯片Signature                        *
*   输入:      Signature地址                              *
*   输出:      读取到的字节                               *
*   调用函数:无                                       *
***********************************************************/
UINT8 Bootloader_Read_Signature(UINT16 wIndex)
{
    UINT8 chData;
   
    //将地址保存到Z指针
    asm("movw r30,r16");
   
    /* 等待上次操作结束 */
    while(SPMCSR & BIT(SPMEN))
    {
      asm("wdr");
    }
   
    SAFE_CODE_PERFORMANCE
    (
      while(EECR & BIT(EEWE))
      {
            asm("wdr");
      }
      SPMCSR = SPM_READ_SIGNATURE;
      asm("lpm %chData,z");
    )
   
    return chData;
}
#endif

#if BL_USE_READ_FUSE_AND_LOCK_BITS == ENABLE
/***********************************************************
*   函数说明:Fuse和Lock Bits读取函数                  *
*   输入:      Fuse和Lock Bits的地址                      *
*   输出:      读取到的字节                               *
*   调用函数:无                                       *
***********************************************************/
UINT8 Bootloader_Read_Fuse(UINT16 wIndex)
{
    UINT8 chData;
   
    //将地址保存到Z指针
    asm("movw r30,r16");
   
    /* 等待上次操作结束 */
    while(SPMCSR & BIT(SPMEN))
    {
      asm("wdr");
    }
   
    SAFE_CODE_PERFORMANCE
    (
      while(EECR & BIT(EEWE))
      {
            asm("wdr");
      }
      SPMCSR = SPM_FUSE_AND_LOCK_BITS;
      asm("lpm %chData,z");
    )
   
    return chData;
}
#endif


1139193886 发表于 2014-12-26 23:14:44

Gorgon_Meducer 发表于 2014-12-26 13:29


万分感谢!

liaoze22 发表于 2014-12-28 08:58:45

{:victory:}好东西

yadong90 发表于 2015-3-2 11:32:45

楼主,这个序列号是唯一的吗?
页: [1]
查看完整版本: 求读取AVR中唯一序列号的函数,加密用的.....