Microchip单片机Flash地址说明及hexmate工具使用
dsPIC33单片机地址说明

按小端模式保存:低地址保存数据低位,高地址保存数据高位。
dsPIC的程序存储器是按照word(2个字节)对齐而hex文件中则是按照字节对齐的。在MPLAB X IDE的Program Memory窗口中地址是按word对齐,所以dsPIC33EP256MU810的指令占用的存储空间范围:87552*2 = 175104 words,所以地址范围为0x00-0x2AC00


Flash地址(字对齐)转换成hex地址(字节对齐)
hex文件中地址 = 需要包含的Flash地址的下1个地址值*2-1,如:我们需要获取0x00-0x5EFA(包含边界0x5EFA存储区域内容)则其对应的hex地址范围:0x00-(0x5EFC*2-1)即0x00-0xBDF7

编译后生成的Hex文件地址分布与dsPIC33CK32MP502的地址分布对应关系如下所示,配置字开始地址是0x5F00在hex文件中对应的地址是0x5F00*2 = 0xBE00

hex文件中配置字地址和dsPIC33CK32MP502手册中对应关系

CRC32算法说明
多项式方向:使用 MSB-first(左移算法),通常为 crc = (crc << 8) ^ table[(crc >> 24) ^ byte]。使用查表法,相应的C代码如下:
#define IMAGE_HEX_START_ADDRESS (0x0UL)#define IMAGE_HEX_END_ADDRESS (0x5EFEUL)#define IMAGE_HEX_SIZE (IMAGE_HEX_END_ADDRESS - IMAGE_HEX_START_ADDRESS + 1)#define POLYNOMIAL_VALUE (0x814141ABUL)#define INIT_VALUE (0x00000000UL)// flash range include endAddrByteuint32_tCRCFlash_Fast(uint32_t crc, uint32_t startAddrByte, uint32_t endAddrByte){uint32_t flashWord;while(startAddrByte <= endAddrByte){flashWord = FLASH_ReadWord24(startAddrByte);// byte 0crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (uint8_t)(flashWord & 0xFF)) & 0xFF];// byte 1crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (uint8_t)((flashWord >> 8) & 0xFF)) & 0xFF];// byte 2crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (uint8_t)((flashWord >> 16) & 0xFF)) & 0xFF];// byte 3crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (uint8_t)((flashWord >> 24) & 0xFF)) & 0xFF];startAddrByte += 2; // word align}return crc;}
注意:当MCU中CRC32校验算法计算dsPIC33CK32MP502整个flash(0x00-0x5EFE)的CRC32值与hexmate命令计算得到的CRC32值不一样时,检查因为多项式方向是否不同,hexmate中使用的CRC32算法是MSB-First的多项式。
编译生成的Hex文件说明
使用MPLAB X IDE编译生成的hex文件中会删除没有使用的Flash区域内容,这样可以节省下载时间。但是在一些情况下,我们需要完整的Flash内容,比如验证Flash是否有损坏时需要使用CRC32算法计算整个Flash的CRC32值,这时就可以使用-FILL选项来实现将没有使用的Flash区域填充为Flash擦除后的值。如下所示:
hexmate ${ImagePath} -o${ImagePath} -FILL=w1:0xFF,0xFF,0xFF,0x00@0x0000:0xBDFF +-CK=0-BDF7@0xBDFCw-4g5p814141AB -LOGFILE=finaldsPIC.hxl
hexmate工具使用
hexmate ${ImagePath} -o${ImagePath}_crc.hex +-CK=0-BDFF@0w-4g5p814141AB -LOGFILE=finaldsPIC.hxl

因为从hex文件中可以看出来最大的flash地址只到0-0x30D6(包含边界),而实际flash范围0-0x5EFE(包含边界)。


QT中CRC32表生成代码
// Microchip的CRC32表voidMainWindow::generateCRC32Table_MSB(uint32_t polynomial, uint32_t table[256]){for (uint32_t i = 0; i < 256; ++i) {uint32_t crc = i << 24; // 将字节放到最高8位for (int bit = 0; bit < 8; ++bit) {if (crc & 0x80000000) // 检查最高位crc = (crc << 1) ^ polynomial;elsecrc <<= 1;}table[i] = crc;}}uint32_t table[256];generateCRC32Table_MSB(POLY, table);QDebug debug = qDebug();debug << "uint32_t CRC32_814141AB_table[256] = {";for (int i = 0; i < 256; ++i) {debug << QString::asprintf("0x%08X", table[i]);if (i != 256 - 1) debug << ", ";}debug << "};";
.${_/_}generate_hex$(ShExtension) $(MP_CC_DIR) ${ProjectDir} ${ImageDir} ${ImageName} ${IsDebug} && cd ${ProjectDir}

使用hexmate修改配置字中读保护位
hexmate ${ImagePath} -find=0xFFFFBD@0xBE00:0xBE03,replace=0xFFFFFF -o${ImagePath}




将编译生成的hex文件放置于hexmate工具同一目录下,如果hexmate路径已经添加到环境变量中了就不用这么麻烦了。

hexmate ./crc32_flash.X.production.hex -find=FFFFBD@BE00-BE03,replace=0xFFFFFF -o./crc32_flash.X.production.hex



PIC16系列单片机地址说明
PIC16F1717手册中的Flash地址是按照字对齐的,8192 = 0x2000对应的地址范围为0x0000-0x1FFF。


PIC18系列单片机地址说明
从PIC18F47Q84的数据手册Memory Map图中可知其地址是按字节对齐的。64KW = 64 * 1024 *2 = 131,072 = 0x20000,地址范围为:0x00000-0x1FFFF。

在MPLAB X IDE的Program Memory窗口中显示的地址也是按字节对齐的。

AVR系列单片机地址说明
AVR的Flash也是按照字对齐的,128KByte大小的Flash存储器地址范围:0x0000-0xFFFF。

static __prog__ uint8_t flashTestPage[15*2] __attribute__((space(prog), aligned(15*2), address(0x18800))) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};



链接: https://pan.baidu.com/s/19FgFxgPVpVVQBpS1LRIRVw


夜雨聆风