/** * @file myFunc.h * @brief 基础工具函数接口 — 65 个函数,7 大分类 * @details 校验计算 / 字符串转换 / 时间处理 / 文件目录操作 / * 进程管理 / 环境变量路径 / IPC 消息队列 */ #ifndef _MY_FUNC_H_ #define _MY_FUNC_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief 系统时间结构体(位域存储,用于嵌入式装置内部表示) * @note year: 7bit(0-127+1900), month:4bit(1-12), day:5bit(1-31) * hour:5bit(0-23), min:6bit(0-59), ms:16bit(0-59999) */ typedef struct { uint32_t ms : 16; /* 毫秒(实际存储秒*1000+毫秒,范围 0-59999) */ uint32_t min : 6; /* 分钟 0-59 */ uint32_t : 2; /* 保留 */ uint32_t hour: 5; /* 小时 0-23 */ uint32_t : 3; /* 保留 */ uint32_t day : 5; /* 日期 1-31 */ uint32_t week: 3; /* 星期 */ uint32_t month:4; /* 月份 1-12 */ uint32_t : 4; /* 保留 */ uint32_t year: 7; /* 年份偏移(实际值-1900),范围 0-127 */ uint32_t : 1; /* 保留 */ } stru_time_sys; /** * @brief 日历时间结构体(Unix 时间 + 微秒) */ typedef struct { time_t sec; /* Unix 时间戳(秒) */ time_t usec; /* 微秒部分 */ } stru_time_cal; /** * @brief IPC 消息文本载荷 */ typedef struct { int qid; /* 响应队列 ID */ int type; /* 响应类型(enum_ipc_resp) */ int len; /* 有效数据长度 */ char text[4096]; /* 消息内容 */ } stru_ipc_text; /** * @brief IPC 响应类型 */ typedef enum { IPC_RESP_NONE = 1, /* 无需响应 */ IPC_RESP_ONCE, /* 单次响应 */ IPC_RESP_ALWAYS /* 持续响应 */ } enum_ipc_resp; /** * @brief IPC 消息(System V 消息队列格式) */ typedef struct { long id; /* 消息类型 ID */ stru_ipc_text t; /* 消息载荷 */ } stru_ipc_msg; /** * @brief 文件描述头结构(256 字节,含 CRC 校验) * @note flag 魔数为 0xA55AA55AA55AA55A */ #pragma pack(1) typedef struct { uint64_t flag; /* 魔数标识 0xA55AA55AA55AA55A */ char ver[16]; /* 版本号 */ char author[16]; /* 作者 */ char modify[32]; /* 修改时间 YYYY-MM-DD HH-MM-SS */ uint16_t crc; /* CRC16 校验 */ char desc[128]; /* 附加描述 */ char bak[54]; /* 对齐填充(总计 256 字节) */ } stru_file_info; #pragma pack() /* ================================================================ * 校验计算函数(CRC16 使用 Modbus 多项式 0xA001) * ================================================================ */ /** 8 位累加校验和 */ uint8_t func_cal_sum_byte(const uint8_t *d, uint32_t n); /** 16 位累加校验和 */ uint16_t func_cal_sum_word(const uint8_t *d, uint32_t n); /** CRC16(Modbus 多项式,初始值 0xFFFF) */ uint16_t func_cal_crc16(const uint8_t *d, uint32_t n); /** CRC32(标准多项式,初始值 0xFFFFFFFF) */ uint32_t func_cal_crc32(const uint8_t *d, uint32_t n); /** 文件 CRC16(4KB 缓冲区流式计算) */ uint16_t func_cal_file_crc16(const char *path); /** 文件 CRC32(4KB 缓冲区流式计算) */ uint32_t func_cal_file_crc32(const char *path); /* ================================================================ * 字符串转换函数 * ================================================================ */ /** 单个十六进制字符 → 数值('F'→15) */ uint8_t func_hex_ch(char c); /** 单个十进制字符 → 数值('9'→9) */ uint8_t func_dec_ch(char c); /** 十六进制字符串 "FF" → int 255 */ int func_hex2dec(char *s); /** 十进制字符串 "255" → int 255(支持负号) */ int func_dec2dec(char *s); /** * @brief 十六进制字符串 → 字节缓冲区 * @param s 源字符串(如 "0102FF") * @param dst 目标缓冲区 * @param len [out]实际字节数 * @return 0 成功,-1 奇数长度 */ int func_hex2buf(const char *s, char *dst, int *len); /** * @brief int → 十进制字符串,右对齐前补零 * @param width 最小宽度(不足补 0,如 width=4 val=255 → "0255") */ char *func_dec2str(char *buf, int sz, int val, int width); /** int → 十六进制字符串(width=0 时不补零) */ char *func_hex2str(char *buf, int sz, int val, int width); /** float → 字符串 */ char *func_float2str(char *buf, int sz, float f, int width); /** 字节数组 → 十六进制字符串(如 {0x01,0xFF} → "01FF") */ char *func_buf2str(char *buf, int sz, const char *src, int n); /** 字符串按空格分割为 argc/argv */ int func_str2argv(char *s, uint8_t *argc, char *argv[], uint8_t max); /* ================================================================ * 时间处理函数 * ================================================================ */ /** 系统时间 → "YYYY-MM-DD HH:MM:SS.mmm" 格式字符串 */ char *func_time_sys2str(char *buf, int sz, stru_time_sys *t); /** 字符串 → 系统时间,解析失败返回 -1 */ int func_str2time_sys(const char *s, stru_time_sys *t); /** 获取当前时间(type: 1=stru_time_sys, 2=stru_time_cal) */ int func_get_time(void *t, int type); /** 设置系统时间(需要 root 权限) */ int func_set_time(void *t, int type); /** 系统时间 → 日历时间 */ void func_time_sys2cal(stru_time_sys *src, stru_time_cal *dst); /** 日历时间 → 系统时间 */ void func_time_cal2sys(stru_time_cal *src, stru_time_sys *dst); /* ================================================================ * 文件目录操作函数 * ================================================================ */ /** 判断目录是否存在(返回 1=存在, 0=不存在) */ int func_dir_exist(const char *p); /** 递归创建目录 */ int func_make_dirs(const char *p); /** 递归删除目录(含所有内容) */ int func_del_dirs(const char *p); /** 通过系统命令删除目录(rm -rf) */ int func_del_dirs_cmd(const char *p); /** 判断文件是否存在(返回 1=存在, 0=不存在) */ int func_file_exist(const char *p); /** 获取文件大小(字节),失败返回 0 */ uint32_t func_file_size(const char *p); /** 读取文件到预分配缓冲区,out 返回实际读取字节数 */ int func_read_file(const char *p, char *buf, uint32_t cap, uint32_t *out); /** 读取文件到动态分配缓冲区(调用者负责 free) */ uint8_t *func_read_file_alloc(const char *p, uint32_t *out); /** 写缓冲区到文件(覆盖模式) */ int func_write_file(const char *p, const char *buf, uint32_t n); /** * @brief 读取结构化的文件描述头 * @param check 1=校验 flag 和 CRC,0=直接读取 */ int func_read_file_info(const char *p, stru_file_info *info, int check); /* ================================================================ * 进程管理函数(基于 /proc 文件系统) * ================================================================ */ /** 获取当前进程名称 */ int func_proc_self_name(char *buf, uint32_t sz); /** 通过 PID 获取进程名称 */ int func_proc_name_by_pid(int pid, char *buf, uint32_t sz); /** 获取当前进程 PID */ int func_proc_pid(void); /** 通过进程名称获取 PID(返回 -1 表示未找到) */ int func_proc_pid_by_name(const char *name); /** 通过 PID 判断进程是否存在 */ int func_proc_exist_by_pid(int pid); /** 通过名称判断进程是否存在 */ int func_proc_exist_by_name(const char *name); /** 通过 PID 获取进程可执行文件路径 */ int func_proc_path_by_pid(int pid, char *buf, uint32_t sz); /** 获取当前进程可执行文件路径 */ int func_proc_self_path(char *buf, uint32_t sz); /** 获取当前进程所在目录 */ int func_proc_self_dir(char *buf, uint32_t sz); /* ================================================================ * 环境变量路径函数 * ================================================================ */ /** 获取工作目录路径(环境变量 WORK_PATH) */ int func_get_work_path(char *buf, uint32_t sz); /** 获取系统配置路径(SYS_CFG_PATH) */ int func_get_syscfg_path(char *buf, uint32_t sz); /** 获取应用根路径(APP_ROOT_PATH) */ int func_get_app_root(char *buf, uint32_t sz); /** 获取历史数据根路径(HIS_ROOT_PATH) */ int func_get_his_root(char *buf, uint32_t sz); /** 获取日志根路径(LOG_ROOT_PATH) */ int func_get_log_root(char *buf, uint32_t sz); /** 获取数据库根路径(DBC_ROOT_PATH) */ int func_get_dbc_root(char *buf, uint32_t sz); /** 获取脚本路径(SHELL_PATH) */ int func_get_shell_path(char *buf, uint32_t sz); /** 获取更新包路径(UPDATE_PATH) */ int func_get_update_path(char *buf, uint32_t sz); /** 拼接应用路径:APP_ROOT_PATH/app_name */ int func_get_app_path(const char *app, char *buf, uint32_t sz); /** 拼接应用配置路径:APP_ROOT_PATH/app_name/ext */ int func_get_app_cfg(const char *app, const char *ext, char *buf, uint32_t sz); /** 拼接应用历史路径:HIS_ROOT_PATH/app_name */ int func_get_app_his(const char *app, char *buf, uint32_t sz); /** 拼接应用日志路径:LOG_ROOT_PATH/app_name */ int func_get_app_log(const char *app, char *buf, uint32_t sz); /* ================================================================ * IPC 消息队列函数(System V 消息队列) * ================================================================ */ /** 按进程名创建消息队列 */ int func_ipc_create_by_name(char *name, int *qid); /** 按 PID 创建消息队列 */ int func_ipc_create_by_pid(int pid, int *qid); /** 按进程名获取消息队列 ID(不存在则创建) */ int func_ipc_get_by_name(const char *name, int *qid); /** 按 PID 获取消息队列 ID(不存在则创建) */ int func_ipc_get_by_pid(int pid, int *qid); /** 发送原始字节到消息队列 */ int func_ipc_send_buf(int qid, uint8_t *tx, uint32_t n); /** 从消息队列接收原始字节 */ int func_ipc_recv_buf(int qid, uint8_t *rx, uint32_t n); /** 发送结构体消息 */ int func_ipc_send_msg(int qid, stru_ipc_msg *m); /** 接收结构体消息 */ int func_ipc_recv_msg(int qid, stru_ipc_msg *m); /** 删除消息队列 */ int func_ipc_delete(int qid); #ifdef __cplusplus } #endif #endif