stm32开发之threadx之modulex模块文件的生成脚本项目

前言

  1. 为了保证在window上运行,且体积小的问题,所以采用c语言编写生成脚本,
  2. 将相关路径由json文件进行配置,
  3. 使用了一个cjson库进行解析
  4. 项目构建使用的是cmake

项目代码

CMakeLists文件

cmake_minimum_required(VERSION 3.27)
project(txm_bat_script C)set(CMAKE_C_STANDARD  11)
find_package(cJSON CONFIG REQUIRED)
configure_file(config.json ${CMAKE_CURRENT_BINARY_DIR}/config.json COPYONLY)
add_executable(txm_bat_script main.ctx_app_module_build.ctx_txm_lib_build.c)target_link_libraries(txm_bat_script PRIVATE cjson)

main函数

/** Copyright (c) 2024-2024,shchl** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-4-14     shchl   first version*/
#include "main.h"
#include "cjson/cJSON.h"FILE *configFile; /*配置文件*/
cJSON *rootJson;char conf_data[4096];int main(void) {configFile = fopen("config.json", "r");if (configFile) {fseek(configFile, 0, SEEK_SET);size_t readCnt = fread(conf_data, 1, 4096, configFile);printf("read cnt:%zu\r\n", readCnt);rootJson = cJSON_Parse(conf_data);if (!rootJson) goto config_error;build_txm_lib_cjson(rootJson);build_app_module_bat_json(rootJson);goto _exit;}config_error:printf("json config error\r\n");_exit:if(configFile) fclose(configFile);if (rootJson) cJSON_Delete(rootJson);return 0;
}

构建txm静态库源文件

/** Copyright (c) 2024-2024,shchl** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-4-14     shchl          thread txm lib 脚本构建*/
#include "main.h"
#include <dirent.h>
#include <sys/stat.h>/*** @brief txm 源文件构建命令*/
const char *tx_txm_lib_source_build_cmd ="arm-none-eabi-gcc -c -g ""-mcpu=cortex-m4 ""-mfloat-abi=hard ""-mfpu=vfpv4 ""-mthumb ""-fpic -fno-plt ""-mno-pic-data-is-text-relative ""-msingle-pic-base ";static void build_txm_lib(char *txm_inc, char *bat_name, char **txm_src_lst, uint32_t cnt) {FILE *pSaveFile = fopen(bat_name, "w");DIR *pDir;char *file_name;if (pSaveFile) {/*删除之前的静态库文件*/fputs("del txm.a\n", pSaveFile);for (int i = 0; i < cnt; ++i) {file_name = txm_src_lst[i];if (strstr(file_name, ".c")) {/*单独添加接口编译源文件*/fprintf(pSaveFile, "%s %s %s\n",tx_txm_lib_source_build_cmd,txm_inc,file_name);} else { /*认为就是目录*/pDir = opendir(file_name);if (pDir) {struct dirent *pDirent = readdir(pDir);while (pDirent) {/*判断是否是.c文件*/if (strstr(pDirent->d_name, ".c")) {fprintf(pSaveFile, "%s %s %s\\%s\n",tx_txm_lib_source_build_cmd,txm_inc,file_name,pDirent->d_name);} else if (strstr(pDirent->d_name, ".") && pDirent->d_namlen == 1) {// 当前目录} else if (strstr(pDirent->d_name, "..") && pDirent->d_namlen == 2) {// 上一级目录} else {// 其他判断}pDirent = readdir(pDir);}closedir(pDir);}}}/*构建静态库*/fputs("arm-none-eabi-ar -r  txm.a *.o\n", pSaveFile);/*删除.o文件*/fputs("del *.o\n", pSaveFile);fclose(pSaveFile);}
}cJSON *itm;
char txm_lib_include[4096] = {0}; /*头文件保存*/
char txm_bat_name[128] = {0};
char **txm_lib_src_dir;
uint32_t txm_lib_src_cnt = 0;static int parse_txm_lib_include_array(cJSON *txm_itm) {cJSON *inc_arr = cJSON_GetObjectItem(txm_itm, "lib_inc_arr");if (!inc_arr) return -1;int cnt = cJSON_GetArraySize(inc_arr);int len = 0;for (int i = 0; i < cnt; ++i) {itm = cJSON_GetArrayItem(inc_arr, i);len += sprintf(txm_lib_include + len, "\t-I%s", cJSON_GetStringValue(itm));}return 1;
}static int parse_txm_lib_bat_name(cJSON *txm_itm) {itm = cJSON_GetObjectItem(txm_itm, "bat_file_name");if (!itm) return -1;char *value = cJSON_GetStringValue(itm);if (!value) return -1;memcpy(txm_bat_name, value, strlen(value));return 1;
}static int parse_txm_lib_src_list(cJSON *txm_itm) {cJSON *inc_arr = cJSON_GetObjectItem(txm_itm, "lib_src_dir_arr");if (!inc_arr) return -1;txm_lib_src_cnt = cJSON_GetArraySize(inc_arr);txm_lib_src_dir = malloc(sizeof(char *) * txm_lib_src_cnt);for (int i = 0; i < txm_lib_src_cnt; ++i) {itm = cJSON_GetArrayItem(inc_arr, i);txm_lib_src_dir[i] = strdup(cJSON_GetStringValue(itm));}return 1;
}int build_txm_lib_cjson(cJSON *root) {cJSON *txm_itm = cJSON_GetObjectItem(root, "txm_lib_config");if (!txm_itm) return -1;/*解析头文件*/if (parse_txm_lib_include_array(txm_itm) == -1) return -1;if (parse_txm_lib_bat_name(txm_itm) == -1)return -1;if (parse_txm_lib_src_list(txm_itm) == -1)return -1;build_txm_lib(txm_lib_include, txm_bat_name, txm_lib_src_dir, txm_lib_src_cnt);/*释放内存*/if (txm_lib_src_dir) {for (int i = 0; i < txm_lib_src_cnt; ++i) {free(txm_lib_src_dir[i]);}free(txm_lib_src_dir);}return 1;
}

构建app模块源文件

/** Copyright (c) 2024-2024,shchl** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-4-14     shchl          生成模块应用脚本代码*/
#include "main.h"
/*指令格式*/
const char *common_del_cmd = "del *.o *.axf *.map"; /*通用删除指令*/
/*** @brief  编译指令 c文件编译成 目标文件*/
const char *module_compilar_to_obj_cmd ="arm-none-eabi-gcc -c -g "" -mcpu=cortex-m4  "" -mfloat-abi=hard  "" -mfpu=vfpv4 -fpie -fno-plt  "" -mno-pic-data-is-text-relative  "" -msingle-pic-base ";
/*** @brief 链接文件+目标文件*/
const char *module_compilar_to_axf_cmd ="arm-none-eabi-ld -A cortex-m4"" -T %s %s "" -e _txm_module_thread_shell_entry txm.a "" -o   app_module.axf"" -M > app_module.map ";
const char *module_compilar_to_bin_cmd ="\narm-none-eabi-objcopy  -O binary  app_module.axf  \"app_module.bin\" ""\narm-none-eabi-objcopy  -O ihex  app_module.axf  \"app_module.hex\" ";/*模块使用的头文件目录*/
//const char *module_inc_dir =
//        "^\n\t\t-IE:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common\\inc "
//        "^\n\t\t-IE:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common_modules\\inc "
//        "^\n\t\t-IE:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\ports_module\\cortex_m4\\gnu\\inc ";void build_app_module_bat(char *inc_list, char *asm_list, char *src_list, char *obj_list,char *link,char *bat) {const char *cmd_asm_fmt = "%s %s\n"; /*汇编指令格式*/const char *cmd_source_fmt = "%s %s %s\n"; /*汇编指令格式*/FILE *pFile = fopen(bat, "w");fprintf(pFile, "del  *.bin  *.hex\n");/*清除*//*汇编文件构建目标文件*/fprintf(pFile, cmd_asm_fmt, module_compilar_to_obj_cmd, asm_list);/*源文件构建目标文件*/fprintf(pFile, cmd_source_fmt, module_compilar_to_obj_cmd, inc_list, src_list);/*目标文件构建axf 文件*/fprintf(pFile, module_compilar_to_axf_cmd, link, obj_list);/*生成bin文件和map文件*/fprintf(pFile, "%s", module_compilar_to_bin_cmd);/*删除 构建中间文件*/fprintf(pFile, "\n%s\n", common_del_cmd);/*清除*/fclose(pFile);
}
static char app_module_inc_str[4096];
static char app_module_src_str[2048];
static char app_module_asm_str[1024];
static char app_module_obj_list[4096];
static char app_module_link[64];
static char app_module_bat[64];
static int app_module_obj_cur_len = 0;char *strReplace(const char *original, const char *substr, const char *replace) {char *tok = NULL;char *newstr = NULL;char *oldstr = NULL;char *head = NULL;if (original == NULL || substr == NULL || replace == NULL) {return NULL;}newstr = strdup(original);head = newstr;while ((tok = strstr(head, substr))) {oldstr = newstr;newstr = (char *) malloc(strlen(oldstr) - strlen(substr) + strlen(replace) + 1);/*failed to alloc mem, free old string and return NULL */if (newstr == NULL) {free(oldstr);return NULL;}memcpy(newstr, oldstr, tok - oldstr);memcpy(newstr + (tok - oldstr), replace, strlen(replace));memcpy(newstr + (tok - oldstr) + strlen(replace), tok + strlen(substr),strlen(oldstr) - strlen(substr) - (tok - oldstr));memset(newstr + strlen(oldstr) - strlen(substr) + strlen(replace), 0, 1);head = newstr + (tok - oldstr) + strlen(replace);free(oldstr);}return newstr;
}static int parse_app_module_inc_list(cJSON *module_itm) {cJSON *inc_dir_arr_itm = cJSON_GetObjectItem(module_itm, "module_inc_dir");if (!inc_dir_arr_itm) return -1;int size = cJSON_GetArraySize(inc_dir_arr_itm);int idx = 0;for (int i = 0; i < size; ++i) {cJSON *itm = cJSON_GetArrayItem(inc_dir_arr_itm, i);if (!itm) return -1;char *value = cJSON_GetStringValue(itm);idx += sprintf(app_module_inc_str + idx, " -I%s ", value);}return 1;
}static void add_file_name_to_obj_list(char *file_name) {/*去掉头*/char *post = strrchr(file_name, '\\') + 1;/*去掉尾部*/char *src = strtok(post, ".");app_module_obj_cur_len += sprintf(app_module_obj_list + app_module_obj_cur_len, " %s.o", src);
}static int parse_app_module_asm_list(cJSON *module_itm) {cJSON *inc_dir_arr_itm = cJSON_GetObjectItem(module_itm, "module_asm_file_list");if (!inc_dir_arr_itm) return -1;int size = cJSON_GetArraySize(inc_dir_arr_itm);int idx = 0;for (int i = 0; i < size; ++i) {cJSON *itm = cJSON_GetArrayItem(inc_dir_arr_itm, i);if (!itm) return -1;char *value = cJSON_GetStringValue(itm);idx += sprintf(app_module_asm_str + idx, " %s ", value);add_file_name_to_obj_list(value);}return 1;
}static int parse_app_module_src_list(cJSON *module_itm) {cJSON *inc_dir_arr_itm = cJSON_GetObjectItem(module_itm, "module_c_source_file_list");if (!inc_dir_arr_itm) return -1;int size = cJSON_GetArraySize(inc_dir_arr_itm);int idx = 0;for (int i = 0; i < size; ++i) {cJSON *itm = cJSON_GetArrayItem(inc_dir_arr_itm, i);if (!itm) return -1;char *value = cJSON_GetStringValue(itm);idx += sprintf(app_module_src_str + idx, " %s ", value);add_file_name_to_obj_list(value);}return 1;
}static int parse_app_module_link_file(cJSON *module_itm) {cJSON *link_itm = cJSON_GetObjectItem(module_itm, "link_file");if (!link_itm) return -1;char *value = cJSON_GetStringValue(link_itm);sprintf(app_module_link, "%s", value);return 1;
}static int parse_app_module_bat_file(cJSON *module_itm) {cJSON *bat_itm = cJSON_GetObjectItem(module_itm, "bat_file_name");if (!bat_itm) return -1;char *value = cJSON_GetStringValue(bat_itm);sprintf(app_module_bat, "%s", value);return 1;
}int build_app_module_bat_json(cJSON *root) {cJSON *module_itm = cJSON_GetObjectItem(root, "txm_module_config");if (parse_app_module_inc_list(module_itm) == -1)return -1;if (parse_app_module_asm_list(module_itm) == -1)return -1;if (parse_app_module_src_list(module_itm) == -1)return -1;if (parse_app_module_link_file(module_itm) == -1)return -1;if (parse_app_module_bat_file(module_itm) == -1)return -1;printf("%s\n", app_module_obj_list);printf("%s\n", app_module_link);printf("%s\n", app_module_bat);build_app_module_bat(app_module_inc_str,app_module_asm_str,app_module_src_str,app_module_obj_list,app_module_link,app_module_bat);return 1;
}

json配置文件(里面的文件可以配置成相对路径)

{"txm_lib_config": {"bat_file_name": "txm_lib_build.bat","lib_inc_arr": ["E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common\\inc","E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common_modules\\inc","E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\ports_module\\cortex_m4\\gnu\\inc"],"lib_src_dir_arr": ["E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common_modules\\module_lib\\src","E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\ports_module\\cortex_m4\\gnu\\module_lib\\src\\txm_module_thread_shell_entry.c"]},"txm_module_config": {"bat_file_name": "txm_module_build.bat","link_file": "..\\app_module.ld","module_inc_dir":["E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common\\inc","E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\common_modules\\inc","E:\\code\\clion\\STM32_Project\\Middleware\\threadx_6_4\\ports_module\\cortex_m4\\gnu\\inc"],"module_asm_file_list": ["..\\app_module_preamble.S ","..\\app_module_setup.s "],"module_c_source_file_list": ["..\\app_module.c"]}
}

在这里插入图片描述

测试(适用于cortex-m4,如果想使用其他内核,修改源码中的编译指令)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/2327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day13-Java进阶-IO字节流及其练习题

1. IO流介绍 2. IO 流体系结构 字节流读取纯文本文件会出现乱码问题 2.1 FileOutputStream 字节输出流 package com.itheima.stream.output;import java.io.FileOutputStream; import java.io.IOException;public class FileOutputStreamDemo3 {/*IO流的异常处理方式: jdk7版本…

socket编程——tcp

在我这篇博客&#xff1a;网络——socket编程中介绍了关于socket编程的一些必要的知识&#xff0c;以及介绍了使用套接字在udp协议下如何通信&#xff0c;这篇博客中&#xff0c;我将会介绍如何使用套接字以及tcp协议进行网络通信。 1. 前置准备 在进行编写代码之前&#xff…

C语言学习/复习30--结构体的声明/初始化/typedef改名/内存对齐大小计算

一、自定义数据类型 二、结构体 1.结构体的定义&#xff08;与数组相对比&#xff09; 2.结构体全局/局部变量的定义 3.typedef对结构体改名 4.匿名结构体类型的声明 注意事项1&#xff1a; 匿名后必须立即创建结构体变量 、 5.结构体与链表节点定义 注意事项1&…

Datawhale ChatGPT基础科普

根据课程GitHub - datawhalechina/hugging-llm: HuggingLLM, Hugging Future. 摘写自己不懂得一些地方&#xff0c;具体可以再到以上项目地址 LM&#xff1a;这是ChatGPT的基石的基石。 Transformer&#xff1a;这是ChatGPT的基石&#xff0c;准确来说它的一部分是基石。 G…

nodejs工具模块学习

util 是一个Node.js 核心模块&#xff0c;提供常用函数的集合&#xff1b; util.inspect(object,[showHidden],[depth],[colors]) 是一个将任意对象转换 为字符串的方法&#xff0c;通常用于调试和错误输出&#xff1b; 如果只有一个参数 object&#xff0c;是要转换的对象&…

英伟达AI系列免费公开课

英伟达公开课官网地址 Augment your LLM Using Retrieval Augmented Generation Building RAG Agents with LLMs langchain的workflow: ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c90cb157c9c84bb5b3da380ec56f5c2a.png Generative AI Explained

函数的使用

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 前面已经介绍了函数的创建以及调用&#xff0c;下面就通过范例学习函数的使用 创建一个函数&#xff0c;如果是偶数则计算其平方&#xff0c;如果是奇数则计算其平方根 分…

如何在 Flutter 中制作多种颜色的 TextField

TextField widget 本身并不施加任何样式。相反&#xff0c;它会要求 TextEditingController 生成一个样式化的 TextSpan 对象&#xff0c;即一段带有样式的文本。 TextField 将其样式传递给 TextEditingController &#xff0c;默认实现只是将其放入 TextSpan 对象中&#xff0…

abide数据集时间序列获取

1.http://preprocessed-connectomes-project.org/abide/ 2. 3.windows批量下载 &#xff08;1&#xff09;创建links.txt&#xff0c;写入链接&#xff0c;例如 https://s3.amazonaws.com/fcp-indi/data/Projects/ABIDE_Initiative/Outputs/dparsf/filt_global/rois_cc400/K…

(十六)call、apply、bind介绍、区别和实现

函数中的this指向&#xff1a; 函数中的this指向是在函数被调用的时候确定的&#xff0c;也就是执行上下文被创建时确定的。在一个执行上下文中&#xff0c;this由调用者提供&#xff0c;由调用函数的方式来决定。 类数组对象arguments&#xff1a; arguments只在函数&#…

谷歌收录工具有什么好用的?

如果是想促进谷歌的收录&#xff0c;其实能用的手段无非就两个&#xff0c;谷歌GSC以及爬虫池 谷歌gsc就不用说了&#xff0c;作为谷歌官方提供的工具&#xff0c;他能提供最准确的数据&#xff0c;并且可以提交每天更新的链接&#xff0c;进而促进收录&#xff0c;只要你的页面…

模块三:二分——69.x的平方根

文章目录 题目描述算法原理解法一&#xff1a;暴力查找解法二&#xff1a;二分查找 代码实现暴力查找CJava 题目描述 题目链接&#xff1a;69.x的平方根 算法原理 解法一&#xff1a;暴力查找 依次枚举 [0, x] 之间的所有数 i &#xff08;这⾥没有必要研究是否枚举到 x /…

【后端】python2和python3的安装与配置

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、python是什么二、python环境的安装与配置Python 2的安装与配置Python 3的安装与配置注意事项 三、总结 前言 随着开发语言及人工智能工具的普及&#xff0…

洗地机哪个牌子好?推荐这四款热销品牌

随着科技的不断发展&#xff0c;洗地机已经成为了家庭中不可或缺的智能家居设备。它们能够帮助我们轻松地完成地面清洁工作&#xff0c;节省时间和精力。但是&#xff0c;面对市场上琳琅满目的洗地机品牌&#xff0c;我们该如何选择呢&#xff1f;本文将为大家介绍四大口碑洗地…

Jackson 2.x 系列【31】Spring Boot 集成之字典翻译

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 场景描述2. 案例演示2.1 修改枚举2.2 定义注解…

使用PlantUML绘制活动图、泳道图

最近在学PlantUML 太漂亮了 给大家欣赏一下 我也记录一下 startuml |使用前| start :用户打开旅游App; |#LightSkyBlue|使用后| :用户浏览旅游信息; |#AntiqueWhite|登机前| :用户办理登机手续; :系统生成登机牌; |使用前| :用户到达机场; |登机前| :用户通过安检; |#Light…

2024华中杯A题|太阳能路灯光伏板的朝向设计问题(思路、代码.....)

太阳能路灯由太阳能电池板组件部分(包括支架)、LED灯头、控制箱(包含控制器、蓄电池)、市电辅助器和灯杆几部分构成。太阳能电池板通过支架固定在灯杆上端。太阳能电池板也叫光伏板,它利用光伏效应接收太阳辐射能并转化为电能输出,经过充放电控制器储存在蓄电池中。太阳能…

使用vue3+ts+vite从零开始搭建bolg(三)(持续更新中)

三、axios&#xff0c;API和路由封装 3.1 axios二次封装 pnpm i axios在src下建立如图文件夹 在request下配置请求拦截器&#xff0c;响应拦截器 import axios from axios import { ElMessage } from element-pluslet request axios.create({baseURL: import.meta.env.VITE…

DFS与回溯专题:路径总和问题

DFS与回溯专题&#xff1a;路径总和问题 一、路径总和 题目链接&#xff1a; 112.路径总和 题目描述 代码思路 对二叉树进行dfs搜索&#xff0c;递归计算每条路径的节点值之和&#xff0c;当某个节点的左右子节点都为空时&#xff0c;说明已经搜索完成某一条路径&#xff0…

牛客NC195 二叉树的直径【simple DFS C++ / Java /Go/ PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/15f977cedc5a4ffa8f03a3433d18650d 思路 最长路径有两种情况&#xff1a; 1.最长条路径经过根节点&#xff0c;那么只需要找出根节点的左右两棵子树的最大深度然后相加即可。 2.最长路径没有经过根节点&#xf…