[feat] add fw_header
This commit is contained in:
parent
6afed2f349
commit
38dec013f8
@ -3,7 +3,11 @@
|
|||||||
|
|
||||||
#include "reg.h"
|
#include "reg.h"
|
||||||
|
|
||||||
|
#define FW_ADDRESS (64 * 1024)
|
||||||
|
#define MAGIC_HEAD (0x64616568) /* ASCII of "head" */
|
||||||
|
|
||||||
struct fw_header_s {
|
struct fw_header_s {
|
||||||
|
uint32_t magic;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t jump_address;
|
uint32_t jump_address;
|
||||||
/* syspll config */
|
/* syspll config */
|
||||||
@ -18,10 +22,10 @@ struct fw_header_s {
|
|||||||
uint8_t usbpll_postdiv2; /* must be in 1~7 */
|
uint8_t usbpll_postdiv2; /* must be in 1~7 */
|
||||||
/* system clock div */
|
/* system clock div */
|
||||||
uint32_t sysclk_div; /* 1~2^24-1 is available */
|
uint32_t sysclk_div; /* 1~2^24-1 is available */
|
||||||
|
uint8_t regulator_voltage; /* 5~15 is available, Voltage = 0.05 * regulator_voltage + 0.55V */
|
||||||
|
uint8_t resv;
|
||||||
/* flash config */
|
/* flash config */
|
||||||
uint16_t flash_div; /* 0 is for disable, 2~65534 is available, must be even value */
|
uint16_t flash_div; /* 0 is for disable, 2~65534 is available, must be even value */
|
||||||
uint16_t flash_resv;
|
|
||||||
uint32_t resv;
|
|
||||||
/* checksum */
|
/* checksum */
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +1,25 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
__attribute__((section(".fw_header"))) struct fw_header_s fw_header = {
|
||||||
|
.magic = MAGIC_HEAD,
|
||||||
|
.size = sizeof(struct fw_header_s),
|
||||||
|
.jump_address = 0x10010000 + sizeof(struct fw_header_s),
|
||||||
|
/* syspll config */
|
||||||
|
.syspll_refdiv = 1, /* must be in 1~63, fref/refdiv must >= 5MHz */
|
||||||
|
.syspll_feedback = 125, /* must be in 16~320, fvco must be in 750MHz~1600MHz */
|
||||||
|
.syspll_postdiv1 = 6, /* must be in 1~7 */
|
||||||
|
.syspll_postdiv2 = 1, /* must be in 1~7 */
|
||||||
|
/* usbpll config */
|
||||||
|
.usbpll_refdiv = 1, /* must be in 1~63, fref/refdiv must >= 5MHz */
|
||||||
|
.usbpll_feedback = 96, /* must be in 16~320, fvco must be in 750MHz~1600MHz */
|
||||||
|
.usbpll_postdiv1 = 4, /* must be in 1~7 */
|
||||||
|
.usbpll_postdiv2 = 2, /* must be in 1~7 */
|
||||||
|
/* system clock div */
|
||||||
|
.sysclk_div = 1, /* 1~2^24-1 is available */
|
||||||
|
.regulator_voltage = 15, /* 5~15 is available, Voltage = 0.05 * regulator_voltage + 0.55V */
|
||||||
|
.resv = 0,
|
||||||
|
/* flash config */
|
||||||
|
.flash_div = 4, /* 0 is for disable, 2~65534 is available, must be even value */
|
||||||
|
/* checksum */
|
||||||
|
.checksum = 0,
|
||||||
|
};
|
||||||
|
|||||||
@ -52,19 +52,20 @@ void __attribute__((section(".text.boot2_pre"))) boot2_copy_self(void)
|
|||||||
ioqspi_hw->io[1].ctrl = GPIO_OVER_OUT_HIGH;
|
ioqspi_hw->io[1].ctrl = GPIO_OVER_OUT_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "resets.h"
|
#include "resets.h"
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "stdio.h"
|
#include "jump.h"
|
||||||
|
|
||||||
uint8_t uart_tx_buffer[512];
|
uint8_t tx_buffer[512] __attribute__((aligned(4)));
|
||||||
uint8_t uart_rx_buffer[512];
|
uint8_t rx_buffer[512] __attribute__((aligned(4)));
|
||||||
|
|
||||||
struct uart_cfg_s uart_cfg = {
|
struct uart_cfg_s uart_cfg = {
|
||||||
.baudrate = 2 * 1000 * 1000,
|
.baudrate = 750 * 1000,
|
||||||
.mode = UART_MODE_TX_RX,
|
.mode = UART_MODE_TX_RX,
|
||||||
.data_bits = UART_DATABITS_8,
|
.data_bits = UART_DATABITS_8,
|
||||||
.parity = UART_PARITY_NONE,
|
.parity = UART_PARITY_NONE,
|
||||||
@ -141,7 +142,7 @@ void uart_process(uint16_t code, uint16_t length)
|
|||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint32_t v1, v2;
|
uint32_t v1, v2;
|
||||||
|
|
||||||
p = uart_rx_buffer + 8;
|
p = rx_buffer + 8;
|
||||||
if ((length > 0) && (length <= 4)) {
|
if ((length > 0) && (length <= 4)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -168,7 +169,7 @@ void uart_process(uint16_t code, uint16_t length)
|
|||||||
process_return_ok();
|
process_return_ok();
|
||||||
} else if (code == 0x0003) {
|
} else if (code == 0x0003) {
|
||||||
process_return_ok();
|
process_return_ok();
|
||||||
process_flash_read(v1, uart_tx_buffer, v2);
|
process_flash_read(v1, tx_buffer, v2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,10 +188,10 @@ void uart_state_machine(uint8_t id)
|
|||||||
uart_rx_length = 0;
|
uart_rx_length = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
code = ((uint16_t)uart_rx_buffer[0] << 8) | (uint16_t)uart_rx_buffer[1];
|
code = ((uint16_t)rx_buffer[0] << 8) | (uint16_t)rx_buffer[1];
|
||||||
code_inv = ((uint16_t)uart_rx_buffer[2] << 8) | (uint16_t)uart_rx_buffer[3];
|
code_inv = ((uint16_t)rx_buffer[2] << 8) | (uint16_t)rx_buffer[3];
|
||||||
length = ((uint16_t)uart_rx_buffer[4] << 8) | (uint16_t)uart_rx_buffer[5];
|
length = ((uint16_t)rx_buffer[4] << 8) | (uint16_t)rx_buffer[5];
|
||||||
length_inv = ((uint16_t)uart_rx_buffer[6] << 8) | (uint16_t)uart_rx_buffer[7];
|
length_inv = ((uint16_t)rx_buffer[6] << 8) | (uint16_t)rx_buffer[7];
|
||||||
if ((code != (uint16_t)~code_inv) || (length != (uint16_t)~length_inv)) {
|
if ((code != (uint16_t)~code_inv) || (length != (uint16_t)~length_inv)) {
|
||||||
uart_rx_length = 0;
|
uart_rx_length = 0;
|
||||||
return;
|
return;
|
||||||
@ -198,28 +199,23 @@ void uart_state_machine(uint8_t id)
|
|||||||
uart_process(code, length);
|
uart_process(code, length);
|
||||||
uart_rx_length = 0;
|
uart_rx_length = 0;
|
||||||
} else {
|
} else {
|
||||||
uart_rx_buffer[uart_rx_length++] = uart0_hw->dr & 0xFF;
|
rx_buffer[uart_rx_length++] = uart0_hw->dr & 0xFF;
|
||||||
time_fifo_empty = timer_count_read();
|
time_fifo_empty = timer_count_read();
|
||||||
if (uart_rx_length >= sizeof(uart_rx_buffer)) {
|
if (uart_rx_length >= sizeof(rx_buffer)) {
|
||||||
uart_rx_length = 0;
|
uart_rx_length = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked)) void jump_to_address(uint32_t address) {
|
|
||||||
__asm volatile (
|
|
||||||
"bx %0\n"
|
|
||||||
:
|
|
||||||
: "r" (address)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
uint32_t boot_pin_low, boot_pin_high;
|
uint32_t boot_pin_low, boot_pin_high;
|
||||||
|
struct fw_header_s *header;
|
||||||
|
|
||||||
system_clock_config(SYSTEM_CLOCK_FREQ_120MHZ);
|
clock_ref_set(CLOCK_REF_SRC_XOSC_GLITCHLESS, 1);
|
||||||
|
clock_sys_set(CLOCK_SYS_SRC_REF_GLITCHLESS, 1);
|
||||||
|
clock_peri_set(ENABLE, CLOCK_PERI_SRC_XOSC);
|
||||||
|
|
||||||
reset_unreset_blocks_wait(RESETS_BLOCK_IO_BANK0 | RESETS_BLOCK_PADS_BANK0 | RESETS_BLOCK_UART0 | RESETS_BLOCK_TIMER);
|
reset_unreset_blocks_wait(RESETS_BLOCK_IO_BANK0 | RESETS_BLOCK_PADS_BANK0 | RESETS_BLOCK_UART0 | RESETS_BLOCK_TIMER);
|
||||||
gpio_init(0, GPIO_FUNC_UART | GPIO_PULL_UP | GPIO_DRIVE_4MA); /* UART_TX pin */
|
gpio_init(0, GPIO_FUNC_UART | GPIO_PULL_UP | GPIO_DRIVE_4MA); /* UART_TX pin */
|
||||||
@ -239,12 +235,23 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (boot_pin_high > boot_pin_low) {
|
if (boot_pin_high > boot_pin_low) {
|
||||||
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
|
tx_buffer[i] = 0x55;
|
||||||
|
}
|
||||||
|
uart_write_block(UART_ID_0, tx_buffer, 4);
|
||||||
while (1) {
|
while (1) {
|
||||||
uart_state_machine(UART_ID_0);
|
uart_state_machine(UART_ID_0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flash_enter_quad_xip(6);
|
flash_read(FW_ADDRESS, rx_buffer, FLASH_READ_SIZE);
|
||||||
jump_to_address(0x10010000 | 1);
|
header = (struct fw_header_s *)rx_buffer;
|
||||||
|
if (jump_check_is_failed(header)) {
|
||||||
|
flash_enter_quad_xip(6);
|
||||||
|
jump_to_address((uint32_t)(uintptr_t *)(FW_ADDRESS | XIP_BASE | 1));
|
||||||
|
} else {
|
||||||
|
jump_pre_config(header);
|
||||||
|
jump_to_address(((struct fw_header_s *)header)->jump_address | 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
file(GLOB FILELIST
|
file(GLOB FILELIST
|
||||||
flash.c
|
flash.c
|
||||||
|
jump.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(TARGET src)
|
set(TARGET src)
|
||||||
|
|||||||
56
example/boot2/src/jump.c
Normal file
56
example/boot2/src/jump.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "jump.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "clock.h"
|
||||||
|
#include "flash.h"
|
||||||
|
|
||||||
|
int jump_check_is_failed(void *addr)
|
||||||
|
{
|
||||||
|
uint32_t size, sum;
|
||||||
|
uint32_t *p;
|
||||||
|
struct fw_header_s *header;
|
||||||
|
|
||||||
|
header = (struct fw_header_s *)addr;
|
||||||
|
if (header->magic != MAGIC_HEAD) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (header->size != sizeof(struct fw_header_s)) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
sum = 0;
|
||||||
|
size = header->size;
|
||||||
|
p = (uint32_t *)header;
|
||||||
|
for (uint32_t i = 0; i < size / 4; i++) {
|
||||||
|
sum += p[i];
|
||||||
|
}
|
||||||
|
if (sum != 0xFFFFFFFF) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void jump_pre_config(void *addr)
|
||||||
|
{
|
||||||
|
struct fw_header_s *header;
|
||||||
|
|
||||||
|
header = (struct fw_header_s *)addr;
|
||||||
|
clock_ref_set(CLOCK_REF_SRC_XOSC_GLITCHLESS, 1);
|
||||||
|
clock_sys_set(CLOCK_SYS_SRC_REF_GLITCHLESS, 1);
|
||||||
|
system_regulator_set(header->regulator_voltage);
|
||||||
|
clock_syspll_init(header->syspll_refdiv, \
|
||||||
|
header->syspll_feedback, \
|
||||||
|
header->syspll_postdiv1, \
|
||||||
|
header->syspll_postdiv2);
|
||||||
|
clock_usbpll_init(header->usbpll_refdiv, \
|
||||||
|
header->usbpll_feedback, \
|
||||||
|
header->usbpll_postdiv1, \
|
||||||
|
header->usbpll_postdiv2);
|
||||||
|
clock_sys_set(CLOCK_SYS_SRC_SYSPLL, header->sysclk_div);
|
||||||
|
clock_peri_set(ENABLE, CLOCK_PERI_SRC_SYSPLL);
|
||||||
|
flash_enter_quad_xip(header->flash_div);
|
||||||
|
}
|
||||||
|
|
||||||
|
void jump_to_address(uint32_t addr)
|
||||||
|
{
|
||||||
|
((void (*)(void))(addr | 1))();
|
||||||
|
}
|
||||||
18
example/boot2/src/jump.h
Normal file
18
example/boot2/src/jump.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef __JUMP_H__
|
||||||
|
#define __JUMP_H__
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int jump_check_is_failed(void *addr);
|
||||||
|
void jump_pre_config(void *addr);
|
||||||
|
void jump_to_address(uint32_t addr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __JUMP_H__ */
|
||||||
11
flash.ld
11
flash.ld
@ -11,7 +11,8 @@ _stack_top_core1 = 0x20041000 + 4 * 1024;
|
|||||||
|
|
||||||
PHDRS
|
PHDRS
|
||||||
{
|
{
|
||||||
fw_header PT_LOAD FLAGS(5); /* R + X */
|
fw_header PT_LOAD FLAGS(6); /* R + X */
|
||||||
|
isr_reset PT_LOAD FLAGS(6); /* R + X */
|
||||||
text PT_LOAD FLAGS(5); /* R + X */
|
text PT_LOAD FLAGS(5); /* R + X */
|
||||||
rodata PT_LOAD FLAGS(6); /* R + W */
|
rodata PT_LOAD FLAGS(6); /* R + W */
|
||||||
data PT_LOAD FLAGS(6); /* R + W */
|
data PT_LOAD FLAGS(6); /* R + W */
|
||||||
@ -24,10 +25,16 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
KEEP(*(.fw_header))
|
KEEP(*(.fw_header))
|
||||||
KEEP(*(.text.isr_reset))
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >FLASH :fw_header
|
} >FLASH :fw_header
|
||||||
|
|
||||||
|
.isr_reset :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.text.isr_reset))
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH :isr_reset
|
||||||
|
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|||||||
@ -23,6 +23,9 @@ LDFLAGS += -Wl,--gc-sections
|
|||||||
LDFLAGS += -nostartfiles
|
LDFLAGS += -nostartfiles
|
||||||
LDFLAGS += -Wl,-Map=$(EXAMPLE_NAME).map
|
LDFLAGS += -Wl,-Map=$(EXAMPLE_NAME).map
|
||||||
LDFLAGS += -Wl,--print-memory-usage
|
LDFLAGS += -Wl,--print-memory-usage
|
||||||
|
ifndef BOOT2_PRE_CRC
|
||||||
|
LDFLAGS += -ufw_header
|
||||||
|
endif
|
||||||
|
|
||||||
CMAKE := cmake
|
CMAKE := cmake
|
||||||
ELF2UF2 := $(SDK_BASE_DIR)/tools/elf2uf2
|
ELF2UF2 := $(SDK_BASE_DIR)/tools/elf2uf2
|
||||||
@ -54,12 +57,19 @@ cmake_definition+= -DEXAMPLE_BASE_DIR=$(EXAMPLE_BASE_DIR)
|
|||||||
|
|
||||||
FINAL_NAME_PRE := $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME)
|
FINAL_NAME_PRE := $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME)
|
||||||
|
|
||||||
|
FW_HEADER_CHECKSUM ?= fw_header_checksum.bin
|
||||||
|
|
||||||
post:build
|
post:build
|
||||||
ifdef BOOT2_PRE_CRC
|
ifdef BOOT2_PRE_CRC
|
||||||
@$(CROSS_COMPILE)objcopy -O binary --only-section=.boot2_pre $(FINAL_NAME_PRE).elf $(BOOT2_PRE_CRC)
|
@$(CROSS_COMPILE)objcopy -O binary --only-section=.boot2_pre $(FINAL_NAME_PRE).elf $(BOOT2_PRE_CRC)
|
||||||
@python3 $(SDK_BASE_DIR)/tools/boot2_pre_crc.py $(BOOT2_PRE_CRC)
|
@python3 $(SDK_BASE_DIR)/tools/boot2_pre_crc.py $(BOOT2_PRE_CRC)
|
||||||
@$(CROSS_COMPILE)objcopy --update-section .boot2_pre=$(BOOT2_PRE_CRC) $(FINAL_NAME_PRE).elf
|
@$(CROSS_COMPILE)objcopy --update-section .boot2_pre=$(BOOT2_PRE_CRC) $(FINAL_NAME_PRE).elf
|
||||||
@rm $(BOOT2_PRE_CRC)
|
@rm $(BOOT2_PRE_CRC)
|
||||||
|
else
|
||||||
|
@$(CROSS_COMPILE)objcopy -O binary --only-section=.fw_header $(FINAL_NAME_PRE).elf $(FW_HEADER_CHECKSUM)
|
||||||
|
@python3 $(SDK_BASE_DIR)/tools/checksum.py $(FW_HEADER_CHECKSUM)
|
||||||
|
@$(CROSS_COMPILE)objcopy --update-section .fw_header=$(FW_HEADER_CHECKSUM) $(FINAL_NAME_PRE).elf
|
||||||
|
@rm $(FW_HEADER_CHECKSUM)
|
||||||
endif
|
endif
|
||||||
@$(CROSS_COMPILE)objcopy -O binary $(FINAL_NAME_PRE).elf $(FINAL_NAME_PRE).bin
|
@$(CROSS_COMPILE)objcopy -O binary $(FINAL_NAME_PRE).elf $(FINAL_NAME_PRE).bin
|
||||||
@$(CROSS_COMPILE)objdump -d -S $(FINAL_NAME_PRE).elf > $(FINAL_NAME_PRE).asm
|
@$(CROSS_COMPILE)objdump -d -S $(FINAL_NAME_PRE).elf > $(FINAL_NAME_PRE).asm
|
||||||
|
|||||||
73
tools/checksum.py
Normal file
73
tools/checksum.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import struct
|
||||||
|
|
||||||
|
def calculate_checksum(data):
|
||||||
|
"""计算小端序校验和:每4字节相加后取反(32位无符号)"""
|
||||||
|
if len(data) % 4 != 0:
|
||||||
|
raise ValueError("Data length must be multiple of 4")
|
||||||
|
|
||||||
|
sum_val = 0
|
||||||
|
# 遍历所有4字节块(最后4字节除外)
|
||||||
|
for i in range(0, len(data)-4, 4):
|
||||||
|
chunk = data[i:i+4]
|
||||||
|
value = struct.unpack('<I', chunk)[0] # 小端序解析
|
||||||
|
sum_val = (sum_val + value) & 0xFFFFFFFF # 32位溢出保护
|
||||||
|
|
||||||
|
return (~sum_val) & 0xFFFFFFFF # 取反并保持32位
|
||||||
|
|
||||||
|
def process_file(filename):
|
||||||
|
"""处理文件的主函数"""
|
||||||
|
try:
|
||||||
|
# 读取文件内容(二进制模式)
|
||||||
|
with open(filename, 'rb+') as f:
|
||||||
|
original_data = f.read()
|
||||||
|
data_len = len(original_data)
|
||||||
|
|
||||||
|
# ========== 验证阶段 ==========
|
||||||
|
# 1. 检查文件长度是否为4的倍数
|
||||||
|
if data_len % 4 != 0:
|
||||||
|
raise ValueError(f"文件长度 {data_len} 不是4的倍数")
|
||||||
|
|
||||||
|
# 2. 检查第二个4字节是否等于文件长度
|
||||||
|
if data_len >= 8:
|
||||||
|
declared_length = struct.unpack('<I', original_data[4:8])[0]
|
||||||
|
if declared_length != data_len:
|
||||||
|
raise ValueError(
|
||||||
|
f"长度声明不匹配:文件头声明={declared_length},实际={data_len}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# ========== 计算校验和 ==========
|
||||||
|
checksum = calculate_checksum(original_data)
|
||||||
|
|
||||||
|
# ========== 写入校验和 ==========
|
||||||
|
# 定位到文件最后4字节
|
||||||
|
f.seek(-4, os.SEEK_END)
|
||||||
|
f.write(struct.pack('<I', checksum)) # 小端序写入
|
||||||
|
|
||||||
|
print(f"[成功] 文件 {filename} 已更新校验码:0x{checksum:08X}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[错误] 处理文件 {filename} 失败:{str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 参数检查
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("用法: python checksum.py <文件名>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
input_file = sys.argv[1]
|
||||||
|
|
||||||
|
# 文件存在性检查
|
||||||
|
if not os.path.isfile(input_file):
|
||||||
|
print(f"[错误] 文件不存在: {input_file}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 执行处理
|
||||||
|
if not process_file(input_file):
|
||||||
|
sys.exit(1)
|
||||||
Loading…
Reference in New Issue
Block a user