465 - Overflow

本文展示了一个使用C语言编写的程序,该程序能够接收两个字符串形式的大整数及一个操作符,然后将输入原样输出,并判断这些数值在进行加法或乘法运算后是否会超出int类型的最大值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

char num1[300],num2[300];
int main( int argc, char * argv[] ) {
	char c;
	while( scanf( "%s %c %s", num1, &c, num2 ) != EOF ) {
		printf( "%s %c %s\n", num1, c, num2 );
		double a, b;
		a = atof( num1 );
		b = atof( num2 );
		if( a > INT_MAX ) printf( "first number too big\n" );
		if( b > INT_MAX ) printf( "second number too big\n" );
		if( c == '+' && a + b > INT_MAX ) printf( "result too big\n" );
		if( c == '*' && a * b > INT_MAX ) printf( "result too big\n" );
	}

	return 0;
}

1343 int ddr_mem_test(ulong dram_base, ulong test_len, ulong is_loop) 1344 { 1345 volatile ulong loop = is_loop; 1346 ul length; 1347 int regval; 1348 1349 sprd_ddr_memtest_prepare(); 1350 1351 length = sizeof(tests)/sizeof(struct sprd_memtest_list); 1352 for (regval=0; regval < length; regval++) { 1353 sprd_ddr_memtest_progress_start(tests[regval].name, regval); 1354 if (tests[regval].sprd_memtest_func((ulv*)dram_base, test_len) != MEMTEST_SUCCESS) { 1355 dprintf(INFO,"memtest failed in: %s\n", tests[regval].name); 1356 lcd_printf("memtest failed in: %s\n", tests[regval].name); 1357 while (loop); 1358 return -1; 1359 } 1360 sprd_ddr_memtest_progress_end(); 1361 } 1362 1363 return 0; 1364 1365 } void fastboot_mode(void) { int ret; FTL_Savepoint_Private(PHASE_FASTBOOT_MODE); dprintf(ALWAYS, "enter [%s]\n",__func__); stop_watchdog(); g_env_bootmode = "fastboot"; write_log(); #ifdef CONFIG_SPLASH_SCREEN logo_display(LOGO_NORMAL_POWER, BACKLIGHT_ON, LCD_ON); vibrator_hw_init(); set_vibrator(1); fastboot_lcd_printf(); mdelay(400); set_vibrator(0); #endif lcd_printf("\nddr memtest start!\n"); ret = ddr_mem_test(0xd0000000,0x80000000,1); if(ret != 0) { dprintf(INFO,"[DDR memtest] fastboot mode ddr memtest fail!\n"); common_raw_write("miscdata", 1, 0, (uint64_t)(779*1024), "2"); common_raw_write("miscdata", 1, 0, (uint64_t)(780*1024), "1"); } else { dprintf(INFO,"[DDR memtest] fastboot mode ddr memtest success!\n"); common_raw_write("miscdata", 1, 0, (uint64_t)(779*1024), "2"); common_raw_write("miscdata", 1, 0, (uint64_t)(780*1024), "2"); } reboot_devices(CMD_NORMAL_MODE); //MMU_DisableIDCM(); #if (defined CONFIG_X86) && (defined CONFIG_MOBILEVISOR) && (defined CONFIG_SPRD_SOC_SP9853I) tos_start_notify(); #endif #ifdef SPRD_SECBOOT if(!dump_backtrace_once){ //if dump enter fastboot, cannot get lockstatus if (get_lock_status() == VBOOT_STATUS_UNLOCK){ debugf("INFO: LOCK FLAG IS : UNLOCK!!!\n"); lcd_printf("\n INFO: LOCK FLAG IS : UNLOCK!!!\n"); } get_secboot_base_from_dt(); } #endif do_fastboot(); } /* get mode from miscdata */ boot_mode_enum_type get_mode_from_miscdata_boot_flag(void) { char out = 0; dprintf(INFO,"==== in [%s] \n", __func__); #if defined(CONFIG_CUSTOMER_PHONE) && defined(CONFIG_AUTOBOOT) extern unsigned reboot_reg; if ((reboot_reg & 0xFF) == HWRST_STATUS_AUTODLOADER) { dprintf(INFO,"%s:rst_mode is autodloader\n", __func__); return CMD_AUTODLOADER_REBOOT; } #elif defined CONFIG_AUTOBOOT dprintf(INFO," AUTOBOOT ENABLE! \n"); return CMD_NORMAL_MODE; #endif boot_mode_enum_type first_mode = read_boot_flag(); if (first_mode != CMD_UNDEFINED_MODE) { bootcause_cmdline="Detect the firsrt_mode flag in the miscdata partition"; dprintf(INFO,"get mode from firstmode field: %s\n", g_mode_str[first_mode]); return first_mode; } if (0 != common_raw_read("miscdata", 1, (uint64_t)(779*1024), (char *)(&out))) { dprintf(INFO,"[DDR memtest] partition <miscdata> read error\n"); } if (out == 49) { dprintf(INFO,"[DDR memtest] enter fastboot mode\n"); fastboot_mode(); } return CMD_UNDEFINED_MODE; } int common_raw_write(const char *part_name, uint64_t size, uint64_t updsize, uint64_t offset, char *buf) 589 { 590 int dev_id = 0; 591 char *ifname; 592 uint64_t part_start = 0; 593 disk_partition_t part_info; 594 block_dev_desc_t *dev_desc; 595 uint64_t total_part_size = 0; 596 int ret = 0; 597 598 SPRD_BLOCK_LOCK(state); 599 600 ifname = block_dev_get_name(); 601 602 if (0 == strcmp(part_name, "splloader")) { 603 dev_id = get_devnum_hwpart(ifname, BOOT_PART1); 604 dev_desc = get_dev_hwpart(ifname, dev_id, BOOT_PART1); 605 } else if(0 == strcmp(part_name, "splloader_bak")) { 606 dev_id = get_devnum_hwpart(ifname, BOOT_PART2); 607 dev_desc = get_dev_hwpart(ifname, dev_id, BOOT_PART2); 608 } else if(0 == strcmp(part_name, "uboot")) { 609 dev_id = get_devnum_hwpart(ifname, USER_PART); 610 dev_desc = get_dev_hwpart(ifname, dev_id, USER_PART); 611 if (NULL == dev_desc) { 612 errorf("invalid dev_desc!\n"); 613 SPRD_BLOCK_UNLOCK(state); 614 return -ENODEV; 615 } 616 ret = get_partition_info_by_name(dev_desc, part_name, &part_info); 617 if (-1 == ret) { 618 ret = 0; 619 dev_id = get_devnum_hwpart(ifname, BOOT_PART2); 620 dev_desc = get_dev_hwpart(ifname, dev_id, BOOT_PART2); 621 } else { 622 part_start = (uint64_t)part_info.blksz * (uint64_t)part_info.start_blk; 623 total_part_size = (uint64_t)part_info.blksz * (uint64_t)part_info.blk_cnt; 624 if ((size > total_part_size) 625 || (offset > total_part_size) 626 || (size + offset > total_part_size)) { 627 errorf("uboot write size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", size, offset, total_part_size); 628 goto error; 629 } 630 } 631 } else { 632 dev_id = get_devnum_hwpart(ifname, USER_PART); 633 dev_desc = get_dev_hwpart(ifname, dev_id, USER_PART); 634 if (NULL == dev_desc) { 635 errorf("invalid dev_desc!\n"); 636 SPRD_BLOCK_UNLOCK(state); 637 return -ENODEV; 638 } 639 ret = get_partition_info_by_name(dev_desc, part_name, &part_info); 640 part_start = (uint64_t)part_info.blksz * (uint64_t)part_info.start_blk; 641 total_part_size = (uint64_t)part_info.blksz * (uint64_t)part_info.blk_cnt; 642 if ((size > total_part_size) 643 || (offset > total_part_size) 644 || (size + offset > total_part_size)) { 645 errorf("write size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", size, offset, total_part_size); 646 goto error; 647 } 648 } 649 650 if (-1 == ret || NULL == dev_desc) 651 goto error; 652 offset += part_start; 653 654 ret = block_dev_write(dev_desc, size, offset, buf); 655 goto end; 656 657 error: 658 ret = -1; 659 end: 660 SPRD_BLOCK_UNLOCK(state); 661 662 return ret; 663 } int common_raw_read(const char *part_name, uint64_t size, uint64_t offset, char *buf) 402 { 403 int dev_id = 0; 404 char *ifname; 405 lbaint_t part_start = 0; 406 disk_partition_t part_info; 407 block_dev_desc_t *dev_desc; 408 uint64_t total_part_size = 0; 409 uint64_t total_part_read_size = 0; 410 int ret = 0; 411 char part_name_temp[MAX_PARTITION_NAME_SIZE]; 412 413 #if WITH_SMP 414 if (bootimg_load_flag) 415 ddr_boot_img_addr = ddr_bootimg; 416 if (vendorbootimg_load_flag) 417 vendorboot_ddr_img_addr = ddr_vendorbootimg; 418 #endif 419 #ifdef CONFIG_ANDROID_AB 420 if (ddr_boot_img_addr && !strncmp(part_name, "boot_", 5)) 421 #else 422 if (ddr_boot_img_addr && ((!strcmp(part_name, "boot"))||(!strcmp(part_name, "recovery")))) 423 #endif 424 { 425 debugf("the second boot.img and recovery.img load is in DDR during secboot mode\n"); 426 offset += ddr_boot_img_addr; 427 memcpy(buf, (char *)offset, size); 428 flush_cache(buf, size); 429 return 0; 430 } 431 #ifdef CONFIG_ANDROID_AB 432 if (vendorboot_ddr_img_addr && !strncmp(part_name, "vendor_boot_", 12)) 433 #else 434 if (vendorboot_ddr_img_addr && (!strcmp(part_name, "vendor_boot"))) 435 #endif 436 { 437 debugf("the second vendor_boot.img load is in DDR during secboot mode\n"); 438 offset += vendorboot_ddr_img_addr; 439 memcpy(buf, offset, size); 440 flush_cache(buf, size); 441 return 0; 442 } 443 444 #ifdef KCE_ENCRYPT_FLAG 445 #ifdef CONFIG_ANDROID_AB 446 if (ddr_dtbo_img_addr && !strncmp(part_name, "dtbo_", 5)) 447 #else 448 if (ddr_dtbo_img_addr && (!strcmp(part_name, "dtbo"))) 449 #endif 450 { 451 debugf("the second dtbo.img load is in DDR during secboot mode\n"); 452 offset += ddr_dtbo_img_addr; 453 memcpy(buf, offset, size); 454 return 0; 455 } 456 #endif //KCE_ENCRYPT_FLAG 457 ifname = block_dev_get_name(); 458 459 if(strstr(part_name, "_size") != NULL) { 460 memcpy(part_name_temp, part_name, strlen(part_name)-5); 461 ret = get_img_partition_size(part_name_temp, &total_part_read_size); 462 debugf("partition %s total size: 0x%llx, block number: 0x%llx\n", 463 part_name_temp, total_part_read_size, total_part_read_size/512); 464 snprintf(buf, 0x80, "partition %s total size: 0x%llx, block number: 0x%llx\n", 465 part_name_temp, total_part_read_size, total_part_read_size/512); 466 467 return ret; 468 } 469 470 SPRD_BLOCK_LOCK(state); 471 if(strcmp(part_name, "user_partition") == 0) { 472 dev_id = get_devnum_hwpart(ifname, USER_PART); 473 dev_desc = get_dev_hwpart(ifname, dev_id, USER_PART); 474 part_start = 0; 475 total_part_size = get_devsize_hwpart(ifname, USER_PART); 476 if ((size > total_part_size) 477 || (offset > total_part_size) 478 || (size + offset > total_part_size)) { 479 errorf("read user partition size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", 480 size, offset, total_part_size); 481 ret = -1; 482 } 483 } else if (0 == strcmp(part_name, "splloader")) { 484 dev_id = get_devnum_hwpart(ifname, BOOT_PART1); 485 dev_desc = get_dev_hwpart(ifname, dev_id, BOOT_PART1); 486 } else if (0 == strcmp(part_name, "splloader_bak")) { 487 dev_id = get_devnum_hwpart(ifname, BOOT_PART2); 488 dev_desc = get_dev_hwpart(ifname, dev_id, BOOT_PART2); 489 } else if (0 == strcmp(part_name, "uboot")) { 490 dev_id = get_devnum_hwpart(ifname, USER_PART); 491 dev_desc = get_dev_hwpart(ifname, dev_id, USER_PART); 492 if (NULL == dev_desc) { 493 errorf("invalid dev_desc!\n"); 494 SPRD_BLOCK_UNLOCK(state); 495 return -ENODEV; 496 } 497 ret = get_partition_info_by_name(dev_desc, part_name, &part_info); 498 if (-1 == ret) { 499 ret = 0; 500 dev_id = get_devnum_hwpart(ifname, BOOT_PART2); 501 dev_desc = get_dev_hwpart(ifname, dev_id, BOOT_PART2); 502 } else { 503 part_start = (uint64_t)part_info.start_blk * (uint64_t)part_info.blksz; 504 total_part_size = (uint64_t)part_info.blksz * (uint64_t)part_info.blk_cnt; 505 if ((size > total_part_size) 506 || (offset > total_part_size) 507 || (size + offset > total_part_size)) { 508 errorf("uboot read size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", size, offset, total_part_size); 509 ret = -1; 510 } 511 } 512 } else if (0 != strstr(part_name, "fixnv")) { 513 dev_id = get_devnum_hwpart(ifname, USER_PART); 514 dev_desc = get_dev_hwpart(ifname, dev_id, USER_PART); 515 if (NULL == dev_desc) { 516 errorf("invalid dev_desc!\n"); 517 SPRD_BLOCK_UNLOCK(state); 518 return -ENODEV; 519 } 520 ret = get_partition_info_by_name(dev_desc, part_name, &part_info); 521 if (-1 == ret) { 522 ret = 0; 523 memset(part_name_temp, 0, MAX_PARTITION_NAME_SIZE); 524 if (0 != strstr(part_name, "_a")) { 525 memcpy(part_name_temp, part_name, strlen(part_name)-2); 526 527 }else { 528 snprintf(part_name_temp, MAX_PARTITION_NAME_SIZE, "%s%s", part_name, "_a"); 529 } 530 debugf("try to adapt ab and not ab fix partition name: %s\n", part_name_temp); 531 ret = get_partition_info_by_name(dev_desc, (const char *)part_name_temp, &part_info); 532 part_start = (uint64_t)part_info.start_blk * (uint64_t)part_info.blksz; 533 total_part_size = (uint64_t)part_info.blksz * (uint64_t)part_info.blk_cnt; 534 if ((size > total_part_size) 535 || (offset > total_part_size) 536 || (size + offset > total_part_size)) { 537 errorf("uboot fixnv read: size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", size, offset, total_part_size); 538 ret = -1; 539 } 540 } else { 541 part_start = (uint64_t)part_info.start_blk * (uint64_t)part_info.blksz; 542 total_part_size = (uint64_t)part_info.blksz * (uint64_t)part_info.blk_cnt; 543 if ((size > total_part_size) 544 || (offset > total_part_size) 545 || (size + offset > total_part_size)) { 546 errorf("uboot read size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", size, offset, total_part_size); 547 ret = -1; 548 } 549 } 550 } else { 551 dev_id = get_devnum_hwpart(ifname, USER_PART); 552 dev_desc = get_dev_hwpart(ifname, dev_id, USER_PART); 553 if (NULL == dev_desc) { 554 errorf("invalid dev_desc!\n"); 555 SPRD_BLOCK_UNLOCK(state); 556 return -ENODEV; 557 } 558 ret = get_partition_info_by_name(dev_desc, part_name, &part_info); 559 part_start = (uint64_t)part_info.start_blk * (uint64_t)part_info.blksz; 560 total_part_size = (uint64_t)part_info.blksz * (uint64_t)part_info.blk_cnt; 561 if ((size > total_part_size) 562 || (offset > total_part_size) 563 || (size + offset > total_part_size)) { 564 errorf("read size(0x%llx + 0x%llx) overflow the total partition size(0x%llx)\n", size, offset, total_part_size); 565 ret = -1; 566 } 567 } 568 569 if (-1 == ret || NULL == dev_desc) 570 goto error; 571 572 if (0 == size) 573 size = total_part_size; 574 575 offset += part_start; 576 577 ret = block_dev_read(dev_desc, size, offset, buf); 578 goto end; 579 580 error: 581 ret = -1; 582 end: 583 SPRD_BLOCK_UNLOCK(state); 584 585 return ret; 586 } 【情况说明】 我们已经上传了我们实现的demo在CR, 偏移已经对齐了。这个是长期且重要的需求,以后展瑞平台项目R项目都会包含这个测试项,帮忙提供一下正式patch,主要涉及 779*1024 及 780*1024的偏移。 offset - 779*1024: 开始测试,写入ASCII码:49(1)---Android写入(ASCII 0x31) 测试完成,写入ASCII码:50(2)---BSP写入 (ASCII 0x32) offset - 780*1024: 测试失败写入ASCII码:49(1)---BSP写入 (ASCII 0x31) 测试成功写入ASCII码:50(2)---BSP写入 (ASCII 0x32) 【需求】 1. boot_mode.c 中 fast_mode函数里面希望增加个判断条件,如 779*1024 位置读取是 ASSIC 码49时,才运行,以保证正常进入fast boot 模式不会 有memtest的问题 2.common_raw_write("miscdata", 1, 0, (uint64_t)(779*1024), "2"); 中 “2” 这种写法是灾难级的,帮忙用宏控的方式控制写入的值。如 #define Pass "2" # define Fail "1" (get_mode_from_miscdata_boot_flag 中的判断也是否可以优化为宏控制,增加代码可读性) 3.int ddr_mem_test(ulong dram_base, ulong test_len, ulong is_loop) 中,贵司的sample 是传入DDR的基地址,内存最大支持大小及 是否循环测试。但如果ddr test失败 将会while(1), is_loop的值是不是应该改为0? 4.另外对于 ddr_mem_test,失败宏后能否打印出失败的地址,目前看只会打印出失败的测试项
最新发布
08-16
<think>首先,用户的问题是基于提供的代码片段,涉及一个DDR内存测试的功能。用户描述了情况说明和需求,我需要用中文回答,并在回答后提出3-5个相关问题。 关键点: - 用户上传了demo到CR(Code Review),偏移已经对齐。 - 这是一个长期且重要的需求,会影响展瑞平台的R项目。 - 需求涉及修改代码,特别是处理偏移779*1024和780*1024。 需求分解: 1. 在`boot_mode.c`的`fastboot_mode`函数中,增加判断条件:只有当779*1024位置读取到ASCII码49('1')时,才运行DDR内存测试。这确保正常进入fastboot模式时不会遇到memtest问题。 2. 优化`common_raw_write`调用中的硬编码字符串"2"和"1"。建议使用宏定义,如`#define PASS "2"`和`#define FAIL "1"`,以提高代码可读性。同样,在`get_mode_from_miscdata_boot_flag`函数中,也应优化判断条件。 3. 在`ddr_mem_test`函数中,参数`is_loop`控制失败时是否循环。用户建议如果测试失败,应该设置`is_loop`为0以避免无限循环。当前代码中,失败时使用`while(loop);`,其中`loop`来自`is_loop`。 4. 在DDR内存测试失败时,除了打印失败的测试项,还应打印失败的具体地址。当前代码只打印了测试项名称。 回答策略: - 针对每个需求,提供修改建议。 - 使用中文,因为用户指定了。 - 回答要基于提供的代码片段。 - 最后,必须输出"§§相关问题§§",后跟3-5个相关问题。 完整回答结构: 1. **回答需求**:逐个解释如何修改代码以满足需求。 2. **相关问题**:在末尾以"§§相关问题§§"开头,列出3-5个相关问题。 针对每个需求的回答: 1. **需求1**:在`fastboot_mode`函数中,添加一个条件检查。在调用`ddr_mem_test`之前,读取779*1024偏移的值。如果读取到的值是49(ASCII '1'),则运行测试;否则跳过。修改代码: - 添加一个变量来存储读取的值。 - 使用`common_raw_read`读取779*1024。 - 如果读取成功且值等于49,才调用`ddr_mem_test`。 2. **需求2**:引入宏定义来避免硬编码。 - 在头文件中定义宏,如`#define MEMTEST_PASS "2"`和`#define MEMTEST_FAIL "1"`。 - 在`common_raw_write`调用中使用这些宏。 - 在`get_mode_from_miscdata_boot_flag`中,优化判断条件,使用宏或常量。 3. **需求3**:关于`ddr_mem_test`的`is_loop`参数。 - 用户指出,如果测试失败,应该避免无限循环。当前代码中,`is_loop`被传递给`volatile ulong loop = is_loop;`,然后失败时`while(loop);`。 - 建议在调用`ddr_mem_test`时,传入`is_loop=0`,这样失败时不会循环。但用户提到“is_loop的值是不是应该改为0?”,意思是可能修改函数内部或调用方式。 - 在`fastboot_mode`中,调用`ddr_mem_test`时传入的`is_loop=1`(因为参数是1)。如果测试失败,它会无限循环。用户建议改为0,但需要根据上下文决定。或许在失败时,不循环,而是直接处理错误。 4. **需求4**:在DDR测试失败时打印失败地址。 - 当前代码中,`tests[regval].sprd_memtest_func`返回非零时,打印测试项名称。 - 修改测试函数,使其在失败时返回错误码或地址,然后打印出来。例如,修改`ddr_mem_test`或测试函数,以捕获并报告失败地址。 代码修改示例: - 对于需求1,在`fastboot_mode`: ```c char out = 0; if (common_raw_read("miscdata", 1, (uint64_t)(779*1024), &out) == 0 && out == 49) { ret = ddr_mem_test(0xd0000000, 0x80000000, 1); } else { dprintf(INFO, "Skipping DDR memtest as 779*1024 is not '1'\n"); ret = 0; // 假设成功,或根据需要处理 } ``` 但需要整合到现有逻辑中。 - 对于需求2,定义宏: ```c #define MEMTEST_START_FLAG '1' // ASCII 49 #define MEMTEST_PASS '2' #define MEMTEST_FAIL '1' ``` 然后使用: ```c common_raw_write("miscdata", 1, 0, (uint64_t)(779*1024), MEMTEST_PASS); ``` - 对于需求3,在`ddr_mem_test`调用时,传入`is_loop=0`,以避免失败时循环。但用户说“is_loop的值是不是应该改为0?”,可能意味着在失败时,设置`loop=0`。但参数是`ulong is_loop`,在函数内部是`volatile ulong loop = is_loop;`。修改调用:在`fastboot_mode`中,调用`ddr_mem_test(..., 0)`,这样失败时不会循环。 - 对于需求4,修改测试函数以返回更多信息。例如,更改测试函数签名以包括地址,或在`ddr_mem_test`中捕获错误地址。 相关问题: 1. 在实现需求1时,如何确保`common_raw_read`的调用是线程安全的,特别是在bootloader环境中? 2. 对于需求2,使用宏定义后,是否需要在整个项目中统一这些宏,以避免不一致? 3. 关于需求3,如果设置`is_loop=0`,在测试失败时系统会直接返回错误,而不循环。这是否符合系统恢复策略? 4. 对于需求4,修改测试函数以返回失败地址可能会增加复杂性。是否有性能或内存占用方面的考虑? 5. 整体上,这些修改如何影响现有项目的兼容性,特别是针对不同展瑞平台项目? 确保相关问题基于用户的问题和我的回答。</think>### 回答用户问题 根据提供的代码和需求说明,以下是针对每个需求的修改建议和代码优化方案: #### 1. **在 `fastboot_mode` 中增加条件判断(需求1)** 修改 `fastboot_mode` 函数,仅当 `779*1024` 偏移处读取到 ASCII 码 `49`(即字符 `'1'`)时,才执行 DDR 内存测试。这确保正常进入 Fastboot 模式时不会误触发测试: ```c void fastboot_mode(void) { // ... 现有代码 ... char test_flag = 0; if (common_raw_read("miscdata", 1, (uint64_t)(779*1024), &test_flag) == 0 && test_flag == MEMTEST_START_FLAG) { lcd_printf("\nddr memtest start!\n"); ret = ddr_mem_test(0xd0000000, 0x80000000, 0); // is_loop 改为 0(见需求3) } else { dprintf(INFO, "Skipping DDR memtest: 779*1024 flag not set to '1'\n"); ret = 0; // 默认成功 } // ... 后续逻辑 ... } ``` **说明**: - 添加 `test_flag` 变量读取偏移 `779*1024` 的值。 - 仅当值为 `MEMTEST_START_FLAG`(宏定义为 `49`)时执行测试。 - 避免正常 Fastboot 模式下的不必要测试。 #### 2. **使用宏替代硬编码值(需求2)** 在头文件(如 `ddr_test.h`)中定义宏,提高代码可读性和可维护性: ```c // 定义测试状态宏 #define MEMTEST_START_FLAG 49 // ASCII '1',表示测试开始 #define MEMTEST_PASS_FLAG 50 // ASCII '2',表示测试通过 #define MEMTEST_FAIL_FLAG 49 // ASCII '1',表示测试失败 // 优化 common_raw_write 调用 common_raw_write("miscdata", 1, 0, (uint64_t)(779*1024), MEMTEST_PASS_FLAG); common_raw_write("miscdata", 1, 0, (uint64_t)(780*1024), MEMTEST_FAIL_FLAG); // 优化 get_mode_from_miscdata_boot_flag 中的判断 if (out == MEMTEST_START_FLAG) { dprintf(INFO, "[DDR memtest] enter fastboot mode\n"); fastboot_mode(); } ``` **说明**: - 宏定义统一管理所有 ASCII 码值,避免魔法数字。 - 在读写操作和条件判断中均使用宏,增强可读性。 #### 3. **修改 `ddr_mem_test` 的 `is_loop` 参数(需求3)** 将 `is_loop` 默认值设为 `0`,避免测试失败时无限循环: ```c int ddr_mem_test(ulong dram_base, ulong test_len, ulong is_loop) { volatile ulong loop = is_loop; // 建议改为 0 // ... 现有代码 ... if (tests[regval].sprd_memtest_func(...) != MEMTEST_SUCCESS) { dprintf(INFO, "memtest failed in: %s\n", tests[regval].name); while (loop); // 若 is_loop=0,则跳过循环 return -1; } // ... 后续逻辑 ... } ``` **说明**: - 在 `fastboot_mode` 中调用时传入 `is_loop=0`(如需求1代码所示)。 - 失败时仅返回错误码,不阻塞系统,符合快速失败原则。 #### 4. **在测试失败时打印地址(需求4)** 修改测试函数,使其返回失败地址,并更新 `ddr_mem_test` 的错误处理: ```c // 步骤1:修改测试函数签名(假设在 sprd_memtest_list 中) typedef struct { const char *name; int (*sprd_memtest_func)(ulv *base, ulong len, ulong *fail_addr); // 新增 fail_addr 参数 } sprd_memtest_list; // 步骤2:在 ddr_mem_test 中捕获地址 if (tests[regval].sprd_memtest_func((ulv*)dram_base, test_len, &fail_addr) != MEMTEST_SUCCESS) { dprintf(INFO, "memtest failed in: %s at address 0x%lx\n", tests[regval].name, fail_addr); lcd_printf("memtest failed in: %s at 0x%lx\n", tests[regval].name, fail_addr); // ... 现有逻辑 ... } ``` **说明**: - 测试函数新增 `ulong *fail_addr` 输出参数,记录失败地址。 - 错误日志中打印具体地址,辅助问题定位。 ### 总结 - **代码健壮性**:通过条件判断和宏定义,避免硬编码和误操作。 - **可维护性**:宏统一管理关键值,便于后续扩展(如其他平台)。 - **错误处理**:失败时打印地址,加速调试;`is_loop=0` 避免系统卡死。 - **兼容性**:修改基于现有逻辑,确保展瑞平台项目无缝集成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值