From c630582df538b74f283ff6f82716cf717afd2808 Mon Sep 17 00:00:00 2001 From: andy <1414772332@qq.com> Date: Mon, 14 Oct 2024 08:10:17 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=85=E8=AF=BBram.bin=20=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/build_flash_kl3.sh | 2 ++ inc/utils/iot_img_hdr.h | 6 +++--- mfgtool/ram/src/ram.c | 38 +++++++++++++++++++++++++++++++++++++- mfgtool/ram/src/xmodem.c | 1 + 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/build/build_flash_kl3.sh b/build/build_flash_kl3.sh index cb7ce98..074b808 100755 --- a/build/build_flash_kl3.sh +++ b/build/build_flash_kl3.sh @@ -714,6 +714,7 @@ build_obj_func() { plc_make_starttime=$(date +%s) export build_amp_type=2 else + # CUS? cus_make_starttime=$(date +%s) export build_amp_type=1 fi @@ -929,6 +930,7 @@ build_obj_func() { echo "start building: $0 $@ , $(date +%Y-%m-%d\ %H:%M:%S)" if [ "${DEF_CORE_TYPE}" == "ampplc" ]; then build_obj_func ${DEF_IMAGE_TYPE} ${DEF_CUS_APP} CUS + # 这里生成ld文件是为了plc程序可以调用 echo "build_flash_kl3.sh call make_ld.sh." ../tools/rom_img/make_ld.sh --addrs ../ap/.output/cus/lib/ht_${DEF_IMAGE_TYPE}.out \ ../startup/ldscripts/riscv3/amp_cus_symbol > ../startup/ldscripts/riscv3/cus.addrs.ld diff --git a/inc/utils/iot_img_hdr.h b/inc/utils/iot_img_hdr.h index 5b3c06a..8be81f0 100644 --- a/inc/utils/iot_img_hdr.h +++ b/inc/utils/iot_img_hdr.h @@ -258,7 +258,7 @@ typedef struct uint8_t layoutIdx; /* reserved */ uint8_t resv[3]; - /* reserved */ + /* 这个可能会用来存放压缩前img的crc */ uint32_t fwCRC; /* sha256 for payload */ uint8_t sha256[SHA256_SIZE]; @@ -287,12 +287,12 @@ typedef struct /* Psram/DDR size, reference for sizeType. */ uint8_t psramSize; /* Header version. reference for hdrVersion. */ - uint8_t hdrVer; + uint8_t hdrVer; // imgheader版本,V1和V0位置相同 uint32_t imgVer; /* CRC32 for 'payload + pad for aligning' */ uint32_t imgCRC; /* fixed, 0xa4e49a17 */ - uint32_t guard; + uint32_t guard; // 通过这个值来确定是不是imgheader,V1和V0位置相同 /* flash layout index */ uint8_t layoutIdx; /* reserved */ diff --git a/mfgtool/ram/src/ram.c b/mfgtool/ram/src/ram.c index 5fb90a7..ebc8f49 100644 --- a/mfgtool/ram/src/ram.c +++ b/mfgtool/ram/src/ram.c @@ -646,6 +646,7 @@ static int ramUartRecieve(rbuf *buf) return 0; /* Recieve from uart */ + // 这里每一个数据包都会发送字符 'C' size = xModemReciveframe(buf->write, curPkg&0xFF, newStart); if(xmRT_Finish == size ||xmRT_Error == size) @@ -697,8 +698,10 @@ static char* ramDataRead(rbuf *buf, int size) char *s, *p; int len; + // buf->read_step 是上一次读取的长度 if(buf->read + buf->read_step > buf->end) { + // 如果超出buf长度限制了,重定位到开始位置 buf->read = buf->start + (buf->read_step - (buf->end - buf->read)); } else @@ -706,6 +709,7 @@ static char* ramDataRead(rbuf *buf, int size) buf->read += buf->read_step; } + // 这部分已经被读取了,减去相应数据量 buf->data_len -= buf->read_step; buf->read_step =0; @@ -718,6 +722,7 @@ static char* ramDataRead(rbuf *buf, int size) if(buf->read +size > buf->end) { + // 如果本次读取长度超出限制,把开始位置的数据复制到末尾 len = size - (buf->end - buf->read); s = buf->start; p = buf->end; @@ -738,6 +743,7 @@ static int ramDeviceWrite(struct image_info *tb, rbuf* buf, int offset, int len) curOffset = offset; + // 除了 imgEFUSE 分区,都是包含imgheader一起写入 if(imgEFUSE == tb->type) { /* write all */ @@ -782,6 +788,7 @@ static int ramDeviceWrite(struct image_info *tb, rbuf* buf, int offset, int len) busy = 0; + // 一次最多只写入一个page的数据 tmp = (PAGE_PROGRAM_SIZE <= len) ? PAGE_PROGRAM_SIZE : len; if((RAM_RBUF_DATA_LEN(buf) < tmp)) @@ -799,6 +806,7 @@ static int ramDeviceWrite(struct image_info *tb, rbuf* buf, int offset, int len) } } +// 把参数和值存入 param static int ramParamGenerate(dev_param_t *param, const char *name, char *value) { int len = iot_strlen(name); @@ -823,6 +831,8 @@ static int ramParamGenerate(dev_param_t *param, const char *name, char *value) return 0; } +// 把参数存入全局变量 +// 如果存在这个变量名则覆盖其值,如果不存在则添加 static int ramParamSetValue(dev_param_t *param) { int i; @@ -846,6 +856,7 @@ static int ramParamSetValue(dev_param_t *param) return -1; } +// 设置并保存参数到flash中 static int ramSaveDevParam(const char *name, char *value) { int i; @@ -858,6 +869,7 @@ static int ramSaveDevParam(const char *name, char *value) iot_layout_get_part_offset(PART_NUM_PARAM, &offset); + // 从flash中读取参数存放到全局变量 for (i = 0; i < PARAM_MAX_LENGTH; i++) { os_mem_cpy(dev_param, (uint8_t*)(base+offset), sizeof(dev_param_t)); if (dev_param->end != PARAM_END_CHAR) { @@ -877,6 +889,7 @@ static int ramSaveDevParam(const char *name, char *value) flash_write_param.sw_mode = MOD_SW_MODE_DIS; iot_layout_get_part_offset(PART_NUM_PARAM, &offset); + // 把参数写入flash if (HAL_ERROR != flash_write(g_dev_param, offset, sizeof(g_dev_param), &flash_write_param)) {//todo return -1; /* flash write error. */ @@ -919,6 +932,7 @@ static int ramImageDecompressToFlash(int run_addr, int img_off) } if (iot_imghdr_get_hdrVer(&hdr) == hdrVer_10) { /* kl3 compressed image contain of image header */ + // 把原始bin的imgheader也压缩进去了,所以这里需要把imgheader的空间留出来 dst= (uint8_t*)(run_addr - HEADER_TOLTAL_SIZE); if (ramImageDecompress(src + HEADER_TOLTAL_SIZE, dst, iot_imghdr_get_imgSize(&hdr)) != 0 ) { @@ -926,6 +940,7 @@ static int ramImageDecompressToFlash(int run_addr, int img_off) ram_printf("\r\nfw image decompressed ERROR!\r\n"); return -1; } else { + // 校验解压后的img crc img_header_construct(&hdr, (char*)dst); imgSize = iot_imghdr_get_imgSize(&hdr); imgSize = IMAGE_LEN_FOR_CRC(imgSize); @@ -938,6 +953,8 @@ static int ramImageDecompressToFlash(int run_addr, int img_off) /* fw image decompressed into flash. */ } } else { + // kunlun1的layout中只有一个run_addr,所以解压一定是解压到这个地址 + // 这里获取这个地址 iot_layout_get_part_offset(PART_NUM_RUN, (uint32_t *)&run_addr); run_addr += base + HEADER_TOLTAL_SIZE; /* unzip the firmware to run address for kl1/kl2 */ @@ -946,11 +963,15 @@ static int ramImageDecompressToFlash(int run_addr, int img_off) /* fw image decompressed ERROR! */ return -1; } else { + // 如果存在crc则这里校验一下crc if (iot_imghdr_get_fwCRC(&hdr) != 0 ) { if (iot_getcrc32(dst, iot_imghdr_get_fwSize(&hdr)) != iot_imghdr_get_fwCRC(&hdr)) { /* fw crc error. */ + ram_printf("\r\nfw crc ERROR.\r\n"); return -1; } + }else{ + ram_printf("\r\nfw CRC not found.\r\n"); } /* fw image decompressed into flash. */ } @@ -1236,9 +1257,11 @@ static int ramDownloadPackage(void) xbuf.start = xbuf.read = xbuf.write = (char *)(RAM_SHA_IMAGE_ADDR); /* Reserve more than PAGE_PROGRAM_SIZE & aligned with xmFRMTYPE_1K */ + // 这里留足16k的余量,在数据截断的情况下,可以把start的数据直接复制到end而不会导致数组溢出 xbuf.end = xbuf.start + ((RAM_SHA_BUFFER_LEN - PAGE_PROGRAM_SIZE) / xmFRMTYPE_16K) * xmFRMTYPE_16K; xbuf.read_step = 0; + // xmodem 传输结束之后 xbuf.source_out_flag 会置位 xbuf.source_out_flag =0; xbuf.data_len =0; @@ -1250,6 +1273,8 @@ static int ramDownloadPackage(void) goto ERROR_OUT; } + // 传输结束的时候如果imgRemainSize比已接收的数据大,则发生了数据丢失 + // 因为imgRemainSize会随着写入的进行逐渐减小,所以最后应该是0 if ((RAM_RBUF_SOURCE_OUT(&xbuf)) && (imgRemainSize > RAM_RBUF_DATA_LEN(&xbuf))) { ram_error_no |= RAM_PKG_DATA_MISS_ERR; @@ -1258,6 +1283,7 @@ static int ramDownloadPackage(void) } if (imgRemainSize) { + // offset是在后文 解析imgheader的时候指定的 curWrite = ramDeviceWrite (&images[imgNo - 1], &xbuf, offset, imgRemainSize); if (-1 == curWrite) { @@ -1268,6 +1294,7 @@ static int ramDownloadPackage(void) imgRemainSize -= curWrite; } else { /* Search the next header */ + // 每次读取一个imgheader的长度 while (NULL != (pbuf = ramDataRead(&xbuf, IMAGE_ALIGNED_SIZE))) { /* Check if it is image header. */ if (0 == ramCheckImageHeader(pbuf)) { @@ -1337,6 +1364,8 @@ static int ramDownloadPackage(void) } /* reload burn table */ + // 根据layout重新加载烧录地址,烧录地址写在ram_hw.c中,这个可以根据layout更新 + // 对于fw来说,烧录地址和运行地址不同 if (!reload_table_done_flag) { if (iot_imghdr_get_hdrVer(&curHdr) > hdrVer_01) { layout_index = iot_imghdr_get_layout_idx(&curHdr); @@ -1355,6 +1384,7 @@ static int ramDownloadPackage(void) } imgRemainSize = iot_imghdr_get_imgSize(&curHdr); + // imgSize 要32字节对齐 imgRemainSize = IMAGE_LEN_FOR_CRC(imgRemainSize) + HEADER_TOLTAL_SIZE; packgeWrote += imgRemainSize; toltalRecieved += imgRemainSize; @@ -1368,11 +1398,12 @@ static int ramDownloadPackage(void) images[imgNo].zip_type = iot_imghdr_get_zipType(&curHdr); images[imgNo].run_offset = iot_imghdr_get_runAddr(&curHdr); imgNo++; - + // 找到imgheader之后退出循环,开始数据写入 break; } toltalRecieved += IMAGE_ALIGNED_SIZE; + // 接收了一个imgheader长度,能到这里来只能是pkgheader if (toltalRecieved == IMAGE_ALIGNED_SIZE) { pkg_hdr = (iot_pkg_hdr_t*)pbuf; if (IOT_MAGIC_NO != @@ -1392,6 +1423,7 @@ static int ramDownloadPackage(void) ram_error_no |= RAM_IMAGE_MISMATCH_ERR; goto ERROR_OUT; } + // 接收了3个imgheader长度,是pkgheader } else if (toltalRecieved == 3 * IMAGE_ALIGNED_SIZE) { pkg_hdr_fw_type = pkg_hdr->img_type; pkg_hdr_flash_size = (pkg_hdr->img_flag >> 4) & 0x0F; @@ -1523,10 +1555,12 @@ static int ramDownloadPackage(void) goto ERROR_OUT; } /* SP SHA256 stamp */ + // 把sp复制倒share_addr if (0 != ramImageCopy(images[offset].type, RAM_SHA_IMAGE_ADDR)) { ram_error_no |= RAM_IMAGE_HEADER_ERR; goto ERROR_OUT; } + // 这里好像是生成sha256 ramImageSecurityStamp(RAM_SHA_IMAGE_ADDR); } else if (imgEFUSE == images[offset].type) { /* CRC before writing */ @@ -1548,6 +1582,8 @@ static int ramDownloadPackage(void) for (offset = 0; offset < imgNo; offset++) { /* compressed image that run in flash, need decompress */ + // kunlun1中 imgType=imgCFRW1或imgCFRW4F 时需要解压 + // kunlun3中 不局限于imgType 只要 zip_type不为0 以及指定了run_addr时 就需要解压 if (imgCFRW1 == images[offset].type || \ imgCFRW4F == images[offset].type || \ ((images[offset].zip_type != 0) && FLASH_RUN_ADDR_CHECK(images[offset].run_offset))) { diff --git a/mfgtool/ram/src/xmodem.c b/mfgtool/ram/src/xmodem.c index db48088..04b3c0d 100644 --- a/mfgtool/ram/src/xmodem.c +++ b/mfgtool/ram/src/xmodem.c @@ -15,6 +15,7 @@ UINT32 xModemReciveframe(char *const pBuf, char frNO, int newFile) { tryTimes = xm1ST_RETRY_TIME; /* Raise CRC-check ONLY */ + // 多次尝试发送字符 'C' ch是收到的回复 xmTRY_CHECKSUM_MODE(tryTimes, tryLoopTime, xmCRC, ch); if(!tryTimes) {