求读取AVR中唯一序列号的函数,加密用的.....
从手册上看ATMEGA48PA,88PA,168AP是有一个序列号可以在程序空间的代码中进行读取用来加密的.搞了两天了也没成功读取....求这样的函数....
谢谢大家. 不知道的頂一下。 顶一下... 顶一下. 读14开始的10个字节…… Gorgon_Meducer 发表于 2012-7-12 15:44 static/image/common/back.gif
读14开始的10个字节……
大神来啦!
求大神给个代码的例子.....我写了两天多了.......无法搞定..... 关注中…… boot.h的头文件有。boot_signature_byte_get(addr) 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)
Gorgon_Meducer 发表于 2012-7-12 15:44 static/image/common/back.gif
读14开始的10个字节……
大师级的还没讲话,都不要急
weuser 发表于 2012-7-12 18:27 static/image/common/back.gif
boot.h的头文件有。boot_signature_byte_get(addr)
翻了N久的手删没有看到SIGRD这个位的定义在哪个地方.手册中那里是第一次出现这个词.前面也没有描述过.求大侠指点. R_OSCCAL =OSCCAL; 本帖最后由 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应该是不支持内部读的。
跟着走,找感觉 我有个产品,先给客户使用,全部付款以后,发短信给一串数字,输入数字就可以解除使用次数的限制。我想用这个序列号,实现这个功能,希望大家探讨一下。 weuser 发表于 2012-7-13 12:08 static/image/common/back.gif
MEGA48的 SIGRD位作为保留位了,我把这个位跳过去试读。
我修改了boot.h文件
#define __BOOT_SIGROW_READ...
48没有,你读48PA试试!
以后做产品一定要用PA后缀的,强大的一B,有唯一序列号,还内建温度传感器!!!!! guolun 发表于 2012-7-13 20:23 static/image/common/back.gif
我有个产品,先给客户使用,全部付款以后,发短信给一串数字,输入数字就可以解除使用次数的限制。我想用这 ...
不需要你去 要涨(账)了 feiben 发表于 2012-7-12 21:25 static/image/common/back.gif
大师级的还没讲话,都不要急
还是那句话:只要芯片数据手册说能通过bootloader读取Signature Byte,就能通过这个手段读14开始的10个字节……这就是芯片的唯一ID。
如果你知道如何通过ISP时序读取Signature Byte,那么同样道理,你肯定能读取到地址14开始的10个字节…… 喔,,,avr也有这功能
sibtck 发表于 2012-7-13 21:03 static/image/common/back.gif
以后做产品一定要用PA后缀的,强大的一B,有唯一序列号,还内建温度传感器!!!!! ...
mega88PA 真有温度内部传感器么?
我原来一直以为只加了唯一序列号。 我是替换原来的老型号,加的功能基本没有注意。 .我跟楼上刚好相反,我只注意到有内部温度传感器,没注意到唯一序列号。 看来真有内部温度传感器。
原来手头有一份更新英文文档,英文不好,就没有仔细看。 下载了,非常感谢 Gorgon_Meducer 发表于 2012-7-13 23:59
还是那句话:只要芯片数据手册说能通过bootloader读取Signature Byte,就能通过这个手段读14开始的10个字 ...
在ICCAVR下如何读出来呢,请大师指点一下 1139193886 发表于 2014-12-19 19:43
在ICCAVR下如何读出来呢,请大师指点一下
用asm() 写在线汇编 {:titter:} Gorgon_Meducer 发表于 2014-12-20 16:14
用asm() 写在线汇编
求大神指点啊,汇编下如何写呢,不懂汇编,可以帮忙写这个代码吗?谢谢。 1139193886 发表于 2014-12-22 21:42
求大神指点啊,汇编下如何写呢,不懂汇编,可以帮忙写这个代码吗?谢谢。 ...
我没有写过ICC的汇编…… 无衣师伊 发表于 2014-12-20 16:31
只要能读这个,就可以继续向后读取隐藏的signature row,里面有很多有趣的信息。我记得大约偏移量是14的地方,连续10个字节就是UID Gorgon_Meducer 发表于 2014-12-22 22:27
我没有写过ICC的汇编……
汇编应该是通用的吧,其它编译器下面的汇编也应该可以编过去吧。 1139193886 发表于 2014-12-22 22:29
汇编应该是通用的吧,其它编译器下面的汇编也应该可以编过去吧。
不同编译器语法不同的。 Gorgon_Meducer 发表于 2014-12-22 22:37
不同编译器语法不同的。
哦,谢谢。我再想想办法吧 Gorgon_Meducer 发表于 2014-12-22 22:37
不同编译器语法不同的。
可以请再帮个忙吗,其它编译环境下的汇编代码可以帮忙写下吗,我转到icc下用。实在不知道这个SN读的顺序和操作方法。,主要看指令和执行的流程,或者让画个时序图都行。 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
Gorgon_Meducer 发表于 2014-12-26 13:29
万分感谢! {:victory:}好东西 楼主,这个序列号是唯一的吗?
页:
[1]