Skip to content

Commit b429fde

Browse files
committed
refactor(fl): split fl.c into modular command files
Split fl.c (1349 lines) into focused modules: - fl.c (228 lines): init, helpers, dispatch table, fl_exec_cmd - fl_codec.c/h: CRC-16 (fl_crc16*) and Base64 (fl_base64_*) - fl_cmd.h: shared types (cmd_args_t, cmd_handler_t) and declarations - fl_cmd_core.c: ping/echo/echoback/info/hello - fl_cmd_mem.c: alloc/upload/read/write - fl_cmd_patch.c: patch/tpatch/dpatch/unpatch/enable + FL_NO_FPB stubs - fl_cmd_file.c: fopen/fwrite/fread/fclose/fcrc/fseek/fstat/flist/fremove/fmkdir/frename All public symbols prefixed with fl_ to avoid namespace collisions. FPB info printing extracted to fl_cmd_print_fpb_info() in fl_cmd_patch.c, eliminating #ifndef FL_NO_FPB from fl_cmd_core.c entirely. Condition compilation (#if) stays in source files, no CMake dependency. Test CRC helper replaced with direct fl_codec.h usage.
1 parent f6e1d59 commit b429fde

12 files changed

Lines changed: 1474 additions & 1190 deletions

File tree

App/func_loader/fl.c

Lines changed: 33 additions & 1155 deletions
Large diffs are not rendered by default.

App/func_loader/fl_cmd.h

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* MIT License
3+
* Copyright (c) 2026 VIFEX
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
* SOFTWARE.
22+
*/
23+
24+
/**
25+
* @file fl_cmd.h
26+
* @brief Internal header shared by fl_cmd_*.c command modules
27+
*/
28+
29+
#ifndef FL_CMD_H
30+
#define FL_CMD_H
31+
32+
#ifdef __cplusplus
33+
extern "C" {
34+
#endif
35+
36+
#include "fl.h"
37+
#include "fl_codec.h"
38+
#include "fl_error.h"
39+
#include "fl_log.h"
40+
41+
/**
42+
* @brief Parsed command arguments (shared by all handlers)
43+
*/
44+
typedef struct {
45+
const char* cmd;
46+
const char* data;
47+
uintptr_t addr;
48+
uintptr_t orig;
49+
uintptr_t target;
50+
int crc; /* -1 = no CRC provided */
51+
int len;
52+
int size;
53+
int comp;
54+
int all;
55+
int enable; /* -1 = not specified, 0 = disable, 1 = enable */
56+
int force;
57+
const char* path;
58+
const char* newpath;
59+
const char* mode;
60+
} cmd_args_t;
61+
62+
/**
63+
* @brief Command handler function pointer
64+
* @return FL_OK or negative fl_error_t
65+
*/
66+
typedef fl_error_t (*cmd_handler_t)(fl_context_t* ctx, const cmd_args_t* args);
67+
68+
/**
69+
* @brief Verify args->crc against a pre-computed CRC value
70+
* @param crc args->crc (-1 = skip verification)
71+
* @param calc Expected CRC computed by caller
72+
* @return true if CRC matches or not provided; false on mismatch (error response sent)
73+
*/
74+
bool fl_verify_crc(int crc, uint16_t calc);
75+
76+
/**
77+
* @brief Flush data cache for a memory region
78+
*/
79+
void fl_flush_dcache(fl_context_t* ctx, const void* addr, size_t len);
80+
81+
/**
82+
* @brief Check if [addr, addr+len) is a safe memory range
83+
* @return true if the range is safe to access
84+
*/
85+
bool fl_check_addr_range(uintptr_t addr, size_t len);
86+
87+
/* ===========================
88+
Command handler declarations
89+
=========================== */
90+
91+
/* Core commands (fl_cmd_core.c) */
92+
fl_error_t fl_cmd_ping(fl_context_t* ctx, const cmd_args_t* args);
93+
fl_error_t fl_cmd_echo(fl_context_t* ctx, const cmd_args_t* args);
94+
fl_error_t fl_cmd_echoback(fl_context_t* ctx, const cmd_args_t* args);
95+
fl_error_t fl_cmd_info(fl_context_t* ctx, const cmd_args_t* args);
96+
fl_error_t fl_cmd_hello(fl_context_t* ctx, const cmd_args_t* args);
97+
98+
/* Memory commands (fl_cmd_mem.c) */
99+
fl_error_t fl_cmd_alloc(fl_context_t* ctx, const cmd_args_t* args);
100+
fl_error_t fl_cmd_upload(fl_context_t* ctx, const cmd_args_t* args);
101+
fl_error_t fl_cmd_read(fl_context_t* ctx, const cmd_args_t* args);
102+
fl_error_t fl_cmd_write(fl_context_t* ctx, const cmd_args_t* args);
103+
104+
/* Patch commands (fl_cmd_patch.c) */
105+
void fl_cmd_print_fpb_info(fl_context_t* ctx);
106+
fl_error_t fl_cmd_patch(fl_context_t* ctx, const cmd_args_t* args);
107+
fl_error_t fl_cmd_tpatch(fl_context_t* ctx, const cmd_args_t* args);
108+
fl_error_t fl_cmd_dpatch(fl_context_t* ctx, const cmd_args_t* args);
109+
fl_error_t fl_cmd_unpatch(fl_context_t* ctx, const cmd_args_t* args);
110+
fl_error_t fl_cmd_enable(fl_context_t* ctx, const cmd_args_t* args);
111+
112+
/* File commands (fl_cmd_file.c) */
113+
#if FL_USE_FILE
114+
fl_error_t fl_cmd_fopen(fl_context_t* ctx, const cmd_args_t* args);
115+
fl_error_t fl_cmd_fwrite(fl_context_t* ctx, const cmd_args_t* args);
116+
fl_error_t fl_cmd_fread(fl_context_t* ctx, const cmd_args_t* args);
117+
fl_error_t fl_cmd_fclose(fl_context_t* ctx, const cmd_args_t* args);
118+
fl_error_t fl_cmd_fcrc(fl_context_t* ctx, const cmd_args_t* args);
119+
fl_error_t fl_cmd_fseek(fl_context_t* ctx, const cmd_args_t* args);
120+
fl_error_t fl_cmd_fstat(fl_context_t* ctx, const cmd_args_t* args);
121+
fl_error_t fl_cmd_flist(fl_context_t* ctx, const cmd_args_t* args);
122+
fl_error_t fl_cmd_fremove(fl_context_t* ctx, const cmd_args_t* args);
123+
fl_error_t fl_cmd_fmkdir(fl_context_t* ctx, const cmd_args_t* args);
124+
fl_error_t fl_cmd_frename(fl_context_t* ctx, const cmd_args_t* args);
125+
#endif
126+
127+
#ifdef __cplusplus
128+
}
129+
#endif
130+
131+
#endif /* FL_CMD_H */

App/func_loader/fl_cmd_core.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* MIT License
3+
* Copyright (c) 2026 VIFEX
4+
*/
5+
6+
/**
7+
* @file fl_cmd_core.c
8+
* @brief Core command handlers (ping/echo/echoback/info/hello)
9+
*/
10+
11+
#include "fl_cmd.h"
12+
#include "fpbinject_version.h"
13+
#include <string.h>
14+
15+
fl_error_t fl_cmd_ping(fl_context_t* ctx, const cmd_args_t* args) {
16+
(void)ctx;
17+
(void)args;
18+
fl_response(true, "PONG");
19+
return FL_OK;
20+
}
21+
22+
fl_error_t fl_cmd_echo(fl_context_t* ctx, const cmd_args_t* args) {
23+
(void)ctx;
24+
/* Echo command for serial throughput testing.
25+
* Echoes back the data length and CRC for verification.
26+
* The data is hex-encoded, so actual byte count is strlen/2.
27+
*/
28+
const char* data_str = args->data;
29+
size_t len = data_str ? strlen(data_str) / 2 : 0;
30+
uint16_t crc = 0;
31+
32+
if (data_str && len > 0) {
33+
/* Calculate CRC of the hex string (not decoded bytes) */
34+
crc = fl_crc16(data_str, strlen(data_str));
35+
}
36+
37+
fl_response(true, "ECHO %u Bytes, CRC 0x%04X", (unsigned)len, crc);
38+
return FL_OK;
39+
}
40+
41+
fl_error_t fl_cmd_echoback(fl_context_t* ctx, const cmd_args_t* args) {
42+
/* Echoback command for download direction throughput testing.
43+
* Fills the send buffer with a deterministic pattern (i % 256),
44+
* base64-encodes it, and sends it back with CRC.
45+
* PC sends: fl -c echoback --len N
46+
*/
47+
int len = args->len;
48+
if (len <= 0 || (size_t)len > FL_BUF_SIZE) {
49+
fl_response(false, "Invalid length %d (max %d)", len, (int)FL_BUF_SIZE);
50+
return FL_ERR_RANGE;
51+
}
52+
53+
/* Fill buffer with deterministic pattern */
54+
for (int i = 0; i < len; i++) {
55+
ctx->buf[i] = (uint8_t)(i % 256);
56+
}
57+
58+
/* Base64 encode */
59+
if (fl_base64_encode(ctx->buf, len, ctx->b64_buf, FL_B64_BUF_SIZE) < 0) {
60+
fl_response(false, "Base64 encode failed");
61+
return FL_ERR_ENCODE;
62+
}
63+
64+
/* CRC over raw pattern bytes */
65+
uint16_t crc = fl_crc16(ctx->buf, len);
66+
67+
/* Output in parts to avoid buffer overflow */
68+
fl_print("[FLOK] ECHOBACK %d bytes crc=0x%04X data=", len, (unsigned)crc);
69+
fl_print_raw(ctx->b64_buf);
70+
fl_print_raw("\n[FLEND]\n");
71+
return FL_OK;
72+
}
73+
74+
fl_error_t fl_cmd_info(fl_context_t* ctx, const cmd_args_t* args) {
75+
(void)args;
76+
77+
fl_println("FPBInject " FPBINJECT_VERSION_STRING);
78+
fl_println("Build: " __DATE__ " " __TIME__);
79+
80+
fl_cmd_print_fpb_info(ctx);
81+
82+
#if FL_USE_FILE
83+
fl_println("FileTransfer: %s", ctx->file_ctx.fs ? "enabled" : "disabled");
84+
#else
85+
fl_println("FileTransfer: not compiled");
86+
#endif
87+
88+
fl_response(true, "Info complete");
89+
return FL_OK;
90+
}
91+
92+
__attribute__((noinline)) void fl_hello(void) {
93+
fl_response(true, "HELLO from original fl_hello(%p) function!", (void*)fl_hello);
94+
}
95+
96+
fl_error_t fl_cmd_hello(fl_context_t* ctx, const cmd_args_t* args) {
97+
(void)ctx;
98+
(void)args;
99+
fl_hello();
100+
return FL_OK;
101+
}

0 commit comments

Comments
 (0)