初始创建FTP服务器

This commit is contained in:
2026-07-21 22:08:11 +08:00
parent d48be81478
commit 6d404d136e
10 changed files with 265 additions and 357 deletions

View File

@@ -152,10 +152,10 @@ HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init()
| 分区名 | 偏移 | 大小 | 块范围 | 用途 |
|--------|------|------|--------|------|
| ftl_fatfs | 128MB | 128MB | Block 1024~2047 | dhara FTL + FatFS 文件系统 |
| ftl_fatfs | 0 | 256MB | Block 0~2047 | dhara FTL + FatFS 文件系统 |
- FatFS 通过 dhara FTL 访问 `ftl_fatfs` 分区`nand_ftl.c``FTL_START_BLOCK = FTL_FATFS_OFFSET / GD5F_BLOCK_SIZE`
- Block 0~1023128MB预留可供后续扩展
- FatFS 通过 dhara FTL 访问全部 2048 个块`nand_ftl.c``FTL_START_BLOCK = 0`
- dhara FTL 自动管理坏块(`dhara_nand_is_bad` / `dhara_nand_mark_bad`
## TPAFE5160 驱动关键点

View File

@@ -74,31 +74,7 @@ void net_task_func(void const *arg)
DBG_ERROR("net init: FAIL");
}
/* ==================== TCP Server Echo 测试 ==================== */
{
int listen_sock = net_socket(NET_AF_INET, NET_SOCK_STREAM, 0);
DBG_INFO("TCP listen socket: %d", listen_sock);
struct net_sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = NET_AF_INET;
serv_addr.sin_port = net_htons(8080);
serv_addr.sin_addr.s_addr = NET_INADDR_ANY;
if (net_bind(listen_sock, (struct net_sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
DBG_INFO("TCP bind: OK (port 8080)");
} else {
DBG_ERROR("TCP bind: FAIL");
}
if (net_listen_locked(listen_sock, NET_TCP_SERVER_MAX_CLIENTS) == 0) {
DBG_INFO("TCP listen: OK (max_clients=%d)", NET_TCP_SERVER_MAX_CLIENTS);
} else {
DBG_ERROR("TCP listen: FAIL");
}
}
DBG_INFO("netTask: started, processing messages");
DBG_INFO("netTask: started, processing messages (FTP mode)");
/* ==================== 主轮询循环 ==================== */
for (;;) {

View File

@@ -16,8 +16,8 @@
#include "nand.h"
#include "map.h"
/* FTL 分区起始地址(块 1024偏移 128MB */
#define FTL_FATFS_OFFSET (128U * 1024U * 1024U)
/* FTL 分区起始地址(块 0偏移 0占用全部 256MB */
#define FTL_FATFS_OFFSET 0U
/* 调试输出配置 */
#define DBG_TAG "[NAND_FTL]"

View File

@@ -37,6 +37,7 @@
static net_sock_t s_net_socks[NET_MAX_SOCKETS]; /* Socket 控制块数组 */
static int s_net_errno = 0; /* 最后错误码 */
static uint8_t s_net_initialized = 0; /* 初始化标志 */
static uint8_t s_local_ip[4]; /* 本机 IP 缓存网络序net_getsockname 用) */
/*
* 消息队列 - 线程安全核心
@@ -131,6 +132,8 @@ int net_init(const char *ip, const char *mask, const char *gateway) {
parse_ip_string(mask, mask_arr);
parse_ip_string(gateway, gw_arr);
memcpy(s_local_ip, ip_arr, 4);
ch395f_set_ip_addr(ip_arr);
ch395f_set_gwip_addr(gw_arr);
ch395f_set_mask_addr(mask_arr);
@@ -1337,9 +1340,28 @@ static int alloc_socket(void) {
* 函数功能处理连接事<E68EA5>? */
static void handle_connect_event(net_sock_t *p_sock) {
if (p_sock->state == NET_SOCK_STATE_LISTENING) {
/* 多连接模式:监听 Socket 收到 CONNECT 中断 = 有新连接被分配到数据 Socket
* Socket 0 自身保持 LISTENING不需要改变状<E58F98>?*/
if (p_sock->standalone_accept) {
/* 独立监听模式PASV收到 CONNECT 中断 = 自身有连接到达,转为 ESTABLISHED */
DBG_INFO("sock%d standalone accept", p_sock->ch395_sock);
uint8_t remote[6];
ch395f_get_remot_ipp(p_sock->ch395_sock, remote);
memcpy(p_sock->remote_ip_arr, remote, 4);
p_sock->remote_ip = ((uint32_t)remote[0]) |
((uint32_t)remote[1] << 8) |
((uint32_t)remote[2] << 16) |
((uint32_t)remote[3] << 24);
p_sock->remote_port = (uint16_t)(remote[4] | (remote[5] << 8));
p_sock->state = NET_SOCK_STATE_ESTABLISHED;
p_sock->send_ready = 1;
ch395f_set_keepalive_enable(p_sock->ch395_sock, 1);
fire_event(p_sock, NET_EVENT_CONNECTED);
} else {
/* 多连接模式:监听 Socket 收到 CONNECT 中断 = 有新连接被分配到数据 Socket
* Socket 0 自身保持 LISTENING不需要改变状态 */
fire_event(p_sock, NET_EVENT_CONNECTED);
}
}
else if (!p_sock->in_use) {
/* CH395F 自动打开的数<E79A84>?Socket多连接模式首次收到 CONNECT 中断 */
@@ -1450,12 +1472,21 @@ static void handle_timeout_event(net_sock_t *p_sock) {
p_sock->state = NET_SOCK_STATE_CREATED;
}
else if (p_sock->state == NET_SOCK_STATE_ESTABLISHED) {
/* 多连接模式:数据 Socket 超时,恢复为 TCP_ACCEPT 等待新连<E696B0>?*/
DBG_INFO("sock%d TIMEOUT, back to ACCEPT", p_sock->ch395_sock);
if (p_sock->standalone_accept) {
/* 独立监听模式PASV断开后释放 Socket不清零整个控制块net_recv 中的任务仍需读 state */
DBG_INFO("sock%d DISCONNECTED, releasing", p_sock->ch395_sock);
p_sock->state = NET_SOCK_STATE_CLOSED;
p_sock->in_use = 0;
fire_event(p_sock, NET_EVENT_DISCONNECTED);
} else {
/* CH395F 自动关闭了 Socket恢复为未使用状态 */
DBG_INFO("sock%d DISCONNECTED, back to idle", p_sock->ch395_sock);
memset(p_sock->remote_ip_arr, 0, 4);
p_sock->remote_port = 0;
p_sock->send_ready = 1;
p_sock->state = NET_SOCK_STATE_TCP_ACCEPT;
fire_event(p_sock, NET_EVENT_DISCONNECTED);
}
}
else if (p_sock->state == NET_SOCK_STATE_LISTENING) {
/* 监听超时(异常情况) */
@@ -1510,3 +1541,42 @@ net_sock_t *net_get_sock(int sockfd) {
return &s_net_socks[sockfd];
}
/*
* 函数功能:获取 Socket 本地地址IP + Port
* 入口参数sockfd - socket 描述符 int
* addr - 输出:本地地址 struct net_sockaddr *
* addrlen - 输入输出:地址结构体长度 int *
* 返回值0 - 成功,-1 - 失败 int
* 限定条件socket 已创建或已绑定
* 函数说明:返回 sin_family + sin_port网络序+ sin_addr网络序从 net_init 缓存的 s_local_ip
*/
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen) {
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
s_net_errno = NET_ERR_BADF;
return -1;
}
net_sock_t *p_sock = &s_net_socks[sockfd];
if (!p_sock->in_use && p_sock->state == NET_SOCK_STATE_CLOSED) {
s_net_errno = NET_ERR_BADF;
return -1;
}
if (addr == NULL || addrlen == NULL || *addrlen < (int)sizeof(struct net_sockaddr_in)) {
s_net_errno = NET_ERR_INVAL;
return -1;
}
struct net_sockaddr_in *p_addr_in = (struct net_sockaddr_in *)addr;
memset(p_addr_in, 0, sizeof(struct net_sockaddr_in));
p_addr_in->sin_family = NET_AF_INET;
p_addr_in->sin_port = net_htons(p_sock->local_port);
p_addr_in->sin_addr.s_addr = ((uint32_t)s_local_ip[0]) |
((uint32_t)s_local_ip[1] << 8) |
((uint32_t)s_local_ip[2] << 16) |
((uint32_t)s_local_ip[3] << 24);
*addrlen = sizeof(struct net_sockaddr_in);
return 0;
}

View File

@@ -287,6 +287,16 @@ void net_process_messages(void);
*/
net_sock_t *net_get_sock(int sockfd);
/*
* 函数功能:获取 Socket 本地地址IP + Port
* 入口参数sockfd - socket 描述符
* addr - 输出:本地地址
* addrlen - 输入输出:地址结构体长度
* 返回值0 成功,-1 失败
* 限定条件socket 已创建或已绑定
*/
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen);
/*
* 内部 API需在 netTask 上下文中调用,绕过消息队列)
*/

View File

@@ -1,10 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<?xml version="1.0" encoding="UTF-8"?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>STM32F407-Demo</TargetName>
@@ -19,28 +16,28 @@
<PackID>Keil.STM32F4xx_DFP.3.1.1</PackID>
<PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000-0x2001BFFF) IRAM2(0x2001C000-0x2001FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
<FlashDriverDll></FlashDriverDll>
<FlashUtilSpec />
<StartupFile />
<FlashDriverDll />
<DeviceId>0</DeviceId>
<RegisterFile></RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<RegisterFile />
<MemoryEnv />
<Cmp />
<Asm />
<Linker />
<OHString />
<InfinionOptionDll />
<SLE66CMisc />
<SLE66AMisc />
<SLE66LinkerMisc />
<SFDFile>$$Device:STM32F407ZGTx$CMSIS\SVD\STM32F407.svd</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath></RegisterFilePath>
<DBRegisterFilePath></DBRegisterFilePath>
<BinPath />
<IncludePath />
<LibPath />
<RegisterFilePath />
<DBRegisterFilePath />
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
@@ -55,15 +52,15 @@
<CreateHexFile>1</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath></ListingPath>
<ListingPath />
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Name />
<UserProg2Name />
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
@@ -72,8 +69,8 @@
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Name />
<UserProg2Name />
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
@@ -82,15 +79,15 @@
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>1</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Name />
<UserProg2Name />
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>1</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
<SVCSIdString />
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
@@ -104,8 +101,8 @@
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<CustomArgument />
<IncludeLibraryModules />
<ComprImg>0</ComprImg>
</CommonProperty>
<DllOption>
@@ -139,10 +136,10 @@
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3>"" ()</Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<Flash4 />
<pFcarmOut />
<pFcarmGrp />
<pFcArmRoot />
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
@@ -175,7 +172,7 @@
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M4"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<RvctDeviceName />
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
@@ -310,7 +307,7 @@
<Size>0x4000</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
<RvctStartVector />
</ArmAdsMisc>
<Cads>
<interw>1</interw>
@@ -337,10 +334,10 @@
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<MiscControls />
<Define>USE_HAL_DRIVER,STM32F407xx,NDEBUG</Define>
<Undefine></Undefine>
<IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Drivers/BSP/TPAFE5160;../Drivers/BSP/SD2506;../Drivers/BSP/RS485;../Drivers/BSP/NET;../App;../App/task;../App/util;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Lib/dhara;../Lib/FatFs</IncludePath>
<Undefine />
<IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Drivers/BSP/TPAFE5160;../Drivers/BSP/SD2506;../Drivers/BSP/RS485;../Drivers/BSP/NET;../Drivers/BSP/NET/lftpd;../App;../App/task;../App/util;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Lib/dhara;../Lib/FatFs</IncludePath>
</VariousControls>
</Cads>
<Aads>
@@ -355,9 +352,9 @@
<useXO>0</useXO>
<ClangAsOpt>1</ClangAsOpt>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<MiscControls />
<Define />
<Undefine />
<IncludePath>../Drivers/CMSIS/Include</IncludePath>
</VariousControls>
</Aads>
@@ -368,15 +365,15 @@
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange></TextAddressRange>
<DataAddressRange></DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile></ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc></Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
<TextAddressRange />
<DataAddressRange />
<pXoBase />
<ScatterFile />
<IncludeLibs />
<IncludeLibsPath />
<Misc />
<LinkerInputFile />
<DisabledWarnings />
</LDads>
</TargetArmAds>
</TargetOption>
@@ -421,8 +418,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -450,12 +445,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -477,8 +466,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -506,12 +493,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -533,8 +514,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -562,12 +541,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -589,8 +562,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -618,12 +589,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -645,8 +610,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -674,12 +637,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -711,8 +668,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -740,12 +695,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -812,8 +761,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -841,12 +788,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -868,8 +809,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -897,12 +836,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -989,8 +922,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1018,12 +949,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1045,8 +970,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1074,12 +997,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1101,8 +1018,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1130,12 +1045,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1157,8 +1066,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1186,12 +1093,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1256,6 +1157,26 @@
<FileType>1</FileType>
<FilePath>..\Drivers\BSP\GD5F2GQ5UE\nand_ftl.c</FilePath>
</File>
<File>
<FileName>lftpd.c</FileName>
<FileType>1</FileType>
<FilePath>..\Drivers\BSP\NET\lftpd\lftpd.c</FilePath>
</File>
<File>
<FileName>lftpd_inet.c</FileName>
<FileType>1</FileType>
<FilePath>..\Drivers\BSP\NET\lftpd\lftpd_inet.c</FilePath>
</File>
<File>
<FileName>lftpd_io.c</FileName>
<FileType>1</FileType>
<FilePath>..\Drivers\BSP\NET\lftpd\lftpd_io.c</FilePath>
</File>
<File>
<FileName>lftpd_string.c</FileName>
<FileType>1</FileType>
<FilePath>..\Drivers\BSP\NET\lftpd\lftpd_string.c</FilePath>
</File>
</Files>
</Group>
<Group>
@@ -1273,8 +1194,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<GroupArmAds>
@@ -1302,12 +1221,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>2</interw>
@@ -1320,12 +1233,6 @@
<uSurpInc>2</uSurpInc>
<useXO>2</useXO>
<ClangAsOpt>1</ClangAsOpt>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
</GroupArmAds>
</GroupOption>
@@ -1347,8 +1254,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1376,12 +1281,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1403,8 +1302,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1432,12 +1329,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1459,8 +1350,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1488,12 +1377,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1515,8 +1398,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1544,12 +1425,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1571,8 +1446,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1600,12 +1473,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1627,8 +1494,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1656,12 +1521,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1683,8 +1542,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1712,12 +1569,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1739,8 +1590,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1768,12 +1617,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1795,8 +1638,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1824,12 +1665,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1851,8 +1686,6 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
@@ -1880,12 +1713,6 @@
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
@@ -1907,8 +1734,8 @@
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<CustomArgument />
<IncludeLibraryModules />
<ComprImg>1</ComprImg>
</CommonProperty>
<GroupArmAds>
@@ -1938,9 +1765,9 @@
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls>--diag_suppress=177</MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
<Define />
<Undefine />
<IncludePath />
</VariousControls>
</Cads>
<Aads>
@@ -1955,10 +1782,10 @@
<useXO>2</useXO>
<ClangAsOpt>1</ClangAsOpt>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
<MiscControls />
<Define />
<Undefine />
<IncludePath />
</VariousControls>
</Aads>
</GroupArmAds>
@@ -1992,7 +1819,6 @@
</Groups>
</Target>
</Targets>
<RTE>
<apis />
<components>
@@ -2005,7 +1831,6 @@
</components>
<files />
</RTE>
<LayerInfo>
<Layers>
<Layer>
@@ -2014,5 +1839,5 @@
</Layer>
</Layers>
</LayerInfo>
</Project>

View File

@@ -3,65 +3,69 @@ Rebuild target 'STM32F407-Demo'
assembling startup_stm32f407xx.s...
compiling crc.c...
compiling ringbuf.c...
compiling dma.c...
compiling stm32f4xx_hal_timebase_tim.c...
compiling stm32f4xx_it.c...
compiling spi.c...
compiling stm32f4xx_hal_flash_ramfunc.c...
compiling i2c.c...
compiling stm32f4xx_hal_msp.c...
compiling stm32f4xx_hal_timebase_tim.c...
compiling spi.c...
compiling gpio.c...
compiling stm32f4xx_hal_rcc_ex.c...
compiling dma.c...
compiling app_main.c...
compiling stm32f4xx_hal_msp.c...
compiling stm32f4xx_hal_gpio.c...
compiling stm32f4xx_it.c...
compiling stm32f4xx_hal_flash_ex.c...
compiling stm32f4xx_hal_flash.c...
compiling stm32f4xx_hal_flash_ramfunc.c...
compiling sys_clock.c...
compiling usart.c...
compiling stm32f4xx_hal_gpio.c...
compiling adc_task.c...
compiling stm32f4xx_hal_flash.c...
compiling rs485_task.c...
compiling main.c...
compiling stm32f4xx_hal_tim_ex.c...
compiling net_task.c...
compiling stm32f4xx_hal_rcc.c...
compiling main.c...
compiling freertos.c...
compiling stm32f4xx_hal_rcc.c...
compiling stm32f4xx_hal_tim.c...
compiling system_stm32f4xx.c...
compiling sd2506.c...
compiling stm32f4xx_hal_pwr.c...
compiling lftpd_inet.c...
compiling stm32f4xx_hal_i2c_ex.c...
compiling stm32f4xx_hal_dma.c...
compiling stm32f4xx_hal_pwr_ex.c...
compiling stm32f4xx_hal.c...
compiling stm32f4xx_hal_exti.c...
compiling stm32f4xx_hal_cortex.c...
compiling rs485.c...
compiling lftpd_io.c...
compiling ch395f.c...
compiling nand_ftl.c...
compiling stm32f4xx_hal_dma_ex.c...
compiling tpafe5160.c...
compiling lftpd_string.c...
compiling net_select.c...
compiling gd5f2gq5ue.c...
compiling stm32f4xx_hal_uart.c...
compiling stm32f4xx_hal_spi.c...
compiling lftpd.c...
compiling croutine.c...
compiling ch395f_test.c...
compiling event_groups.c...
compiling list.c...
compiling queue.c...
compiling stream_buffer.c...
compiling timers.c...
compiling tasks.c...
compiling heap_4.c...
compiling port.c...
compiling stm32f4xx_hal_dma_ex.c...
compiling stm32f4xx_hal_dma.c...
compiling stm32f4xx_hal_pwr.c...
compiling journal.c...
compiling stm32f4xx_hal_pwr_ex.c...
compiling map.c...
compiling stm32f4xx_hal_cortex.c...
compiling stm32f4xx_hal.c...
compiling system_stm32f4xx.c...
compiling stm32f4xx_hal_i2c_ex.c...
compiling stm32f4xx_hal_exti.c...
compiling ff.c...
compiling rs485.c...
compiling tpafe5160.c...
compiling sd2506.c...
compiling gd5f2gq5ue.c...
compiling ch395f.c...
compiling stm32f4xx_hal_spi.c...
compiling stm32f4xx_hal_uart.c...
compiling net_select.c...
compiling nand_ftl.c...
compiling ch395f_test.c...
compiling net_socket.c...
compiling stream_buffer.c...
compiling queue.c...
compiling timers.c...
compiling heap_4.c...
compiling stm32f4xx_hal_i2c.c...
compiling tasks.c...
compiling map.c...
compiling journal.c...
compiling port.c...
compiling ff.c...
compiling cmsis_os2.c...
linking...
Program Size: Code=48264 RO-data=1416 RW-data=220 ZI-data=53788
Program Size: Code=57652 RO-data=2132 RW-data=392 ZI-data=54848
FromELF: creating hex file...
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:16
Build Time Elapsed: 00:00:19

View File

@@ -72,7 +72,7 @@ Dma.USART1_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphData
FREERTOS.FootprintOK=true
FREERTOS.IPParameters=Tasks01,configENABLE_FPU,FootprintOK,configTOTAL_HEAP_SIZE,Queues01
FREERTOS.Queues01=netMsgQueue,8,net_msg_t,0,Dynamic,NULL,NULL
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,1024,StartNetTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,1024,StartNetTask,Default,NULL,Dynamic,NULL,NULL;ftpTask,24,1024,StartFtpTask,As weak,NULL,Dynamic,NULL,NULL
FREERTOS.configENABLE_FPU=1
FREERTOS.configTOTAL_HEAP_SIZE=30720
File.Version=6

View File

@@ -33,6 +33,7 @@
#include "usart.h"
#include "ff.h"
#include "gd5f2gq5ue.h"
#include "lftpd.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -92,6 +93,13 @@ const osThreadAttr_t netTask_attributes = {
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for ftpTask */
osThreadId_t ftpTaskHandle;
const osThreadAttr_t ftpTask_attributes = {
.name = "ftpTask",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for netMsgQueue */
osMessageQueueId_t netMsgQueueHandle;
const osMessageQueueAttr_t netMsgQueue_attributes = {
@@ -105,6 +113,7 @@ const osMessageQueueAttr_t netMsgQueue_attributes = {
void StartDefaultTask(void *argument);
void StartNetTask(void *argument);
void StartFtpTask(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
@@ -145,6 +154,9 @@ void MX_FREERTOS_Init(void) {
/* creation of netTask */
netTaskHandle = osThreadNew(StartNetTask, NULL, &netTask_attributes);
/* creation of ftpTask */
ftpTaskHandle = osThreadNew(StartFtpTask, NULL, &ftpTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
@@ -279,6 +291,21 @@ void StartNetTask(void *argument)
/* USER CODE END StartNetTask */
}
/* USER CODE BEGIN Header_StartFtpTask */
/**
* @brief Function implementing the ftpTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartFtpTask */
__weak void StartFtpTask(void *argument)
{
/* USER CODE BEGIN StartFtpTask */
lftpd_t ftp;
lftpd_start("/", 21, &ftp);
/* USER CODE END StartFtpTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

View File

@@ -28,12 +28,12 @@
┌─────────────────────────────────────────────────────────────┐
│ 物理分区布局 (256MB) │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 预留 (128MB) │ ftl_fatfs (128MB) │ │
│ │ Block 0~1023 │ Block 1024~2047 │ │
│ │ 未使用 │ dhara FTL + FatFS │ │
│ └────────────────────────────────────────────────────────┘ │
│ 偏移: 0 128MB 256MB
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ ftl_fatfs (256MB) │ │
│ │ Block 0~2047 │ │
│ │ dhara FTL + FatFS全部 2048 个块) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ 偏移: 0 256MB│
└─────────────────────────────────────────────────────────────┘
```
@@ -91,24 +91,20 @@ HAL_Init → SystemClock_Config → MX_GPIO_Init → MX_USART1_UART_Init
单个分区,配置在 `Drivers/BSP/GD5F2GQ5UE/nand_ftl.c`
```c
#define FTL_FATFS_OFFSET (128U * 1024U * 1024U) // 128MB
#define FTL_FATFS_SIZE (128 * 1024 * 1024) // 128MB
#define FTL_FATFS_OFFSET 0 // 偏移 0占用全部 256MB
```
### 3.1 分区对照表
| 分区名 | 偏移 | 大小 | 物理块范围 | 逻辑用途 |
|--------|------|------|-----------|----------|
| 预留 | 0 | 128 MB | Block 0~1023 | 未使用 |
| `ftl_fatfs` | 128 MB | 128 MB | Block 1024~2047 | dhara FTL + FatFS |
| `ftl_fatfs` | 0 | 256 MB | Block 0~2047 | dhara FTL + FatFS |
### 3.2 配置联动
- **FTL** — `nand_ftl.c``FTL_START_BLOCK = FTL_FATFS_OFFSET / GD5F_BLOCK_SIZE = 1024``FTL_NUM_BLOCKS` 自动适配剩余块数
- **FTL** — `nand_ftl.c``FTL_START_BLOCK = 0``FTL_NUM_BLOCKS = 2048`
- **FatFS** — 通过 `disk_ioctl(GET_SECTOR_COUNT)` 获取 FTL 管理的扇区数
> 调整分区大小时只需修改 `nand_ftl.c` 中的 `FTL_FATFS_OFFSET` 宏,下游模块自动适配。
---
## 4. 驱动层gd5f2gq5ue.c/h
@@ -315,12 +311,12 @@ FTL 之上还有一个 **单页写回缓存 (write-back cache)**
### 6.3 容量计算
```
FTL 管理块数 = 1024 (Block 1024~2047)
FTL 管理块数 = 2048 (Block 0~2047)
每块页数 = 64
每页扇区数 (512B) = 4
总扇区数 = 1024 × 64 × 4 = 262144
总容量 = 262144 × 512 = 128MB (原始容量)
FTL 开销后 ≈ 93 MB (随 GC 和 journal 使用量波动)
总扇区数 = 2048 × 64 × 4 = 524288
总容量 = 524288 × 512 = 256MB (原始容量)
FTL 开销后 ≈ 186 MB (随 GC 和 journal 使用量波动)
```
---