CubeMX v6.1.0、RT-Thread Nano v3.1.3、Keil v5.33
第一步 配置并生成代码
官方指南假设你已了解关于CubeMX 的中级知识。如果你刚开始学习单片机,将此文档作为你的第一步可能不是最好的主意——掌握好基础知识再来吧!之前有其它框架的使用经验会有帮助,但这不是必需的。
配置好我们所需的外设后,添加CJSON、RTT支持包,如下图所示:
一定要去掉下面4项:
进行上一步操作之后,生成代码【GENERATE CODE】,此时用keil打开工程并进行相关设置,如下图:
第二步 安装nodejs、并添加相应支持
nodejs v14.15.1 LTS
添加脚本【${project}/MDK-ARM/RttSrcModify.js】
var fs = require('fs');
var path = require('path');
let log = console.log
const dir = fs.readdirSync('.');
let projectName = dir.filter(e=>e.includes('.uvprojx'))[0];
// log(projectName)
// return;
let ModifyKeilFilesConfigFilePath = path.join(__dirname, "RttSrcModify.json")
let defaultPath = '../Middlewares/Third_Party/RealThread_RTOS_RT-Thread'
let config = fs.readFileSync(ModifyKeilFilesConfigFilePath);
config = config.toString();
config = config.replace(/_myProject.uvprojx/g, projectName)
config = JSON.parse(config)
config?.modifyFiles?.forEach(e => {
let fPath = e.filePath.includes('./') ? path.join(__dirname, e.filePath) : path.join(__dirname, defaultPath, e.filePath)
let fileContent = fs.readFileSync(fPath)
fileContent = fileContent.toString().split('\n');
let isModify = false
fileContent.forEach((ee, i) => {
if (ee.includes(e.findStr)) {
if(fileContent[i + e.dstOffset].includes(e.src)) {
isModify = true;
fileContent[i + e.dstOffset] = fileContent[i + e.dstOffset].replace(e.src, e.dst)
}
}
})
//log(fileContent)
if(isModify) fs.writeFileSync(fPath, fileContent.join('\n'))
});
添加修改json文件【${project}/MDK-ARM/RttSrcModify.json】
{
"modifyFiles":[
{
"filePath": "./_myProject.uvprojx",
"findStr":"<FileName>main.c</FileName>",
"dstOffset": 1,
"src":"<FileType>1</FileType>",
"dst":"<FileType>8</FileType>"
},
{
"filePath": "./_myProject.uvprojx",
"findStr":"<FileName>context_rvds.S</FileName>",
"dstOffset": 1,
"src":"<FileType>1</FileType>",
"dst":"<FileType>2</FileType>"
},
{
"filePath": "src/ipc.c",
"findStr":"mb->msg_pool = msgpool;\n",
"dstOffset": 0,
"src":"mb->msg_pool = msgpool;\n",
"dst":"mb->msg_pool = (rt_uint32_t *)RT_KERNEL_MALLOC(mb->size * sizeof(rt_uint32_t));\n"
},
{
"filePath": "src/ipc.c",
"findStr":"mb->msg_pool = RT_KERNEL_MALLOC(mb->size * sizeof(rt_uint32_t));\n",
"dstOffset": 0,
"src":"mb->msg_pool = RT_KERNEL_MALLOC(mb->size * sizeof(rt_uint32_t));\n",
"dst":"mb->msg_pool = (rt_uint32_t *)RT_KERNEL_MALLOC(mb->size * sizeof(rt_uint32_t));\n"
},
{
"filePath": "src/kservice.c",
"findStr":"for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)\n",
"dstOffset": 0,
"src":"for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)\n",
"dst":"for (su1 = (const unsigned char *)cs, su2 = (const unsigned char *)ct; 0 < count; ++su1, ++su2, count--)\n"
},
{
"filePath": "src/thread.c",
"findStr":"(void *)((char *)thread->stack_addr + thread->stack_size - 4),\n",
"dstOffset": 0,
"src":"(void *)((char *)thread->stack_addr + thread->stack_size - 4),\n",
"dst":"(rt_uint8_t *)((char *)thread->stack_addr + thread->stack_size - 4),\n"
},
{
"filePath": "include/rtdef.h",
"findStr": "RT_USED const init_fn_t __rt_init_##fn SECTION(\".rti_fn.\"level) = fn\r",
"dstOffset": 0,
"src":"RT_USED const init_fn_t __rt_init_##fn SECTION(\".rti_fn.\"level) = fn\r",
"dst":"RT_USED const init_fn_t __rt_init_##fn SECTION(\".rti_fn.\" level) = fn\r"
},
{
"filePath": "bsp/rtconfig.h",
"findStr": "#define RT_MAIN_THREAD_STACK_SIZE 256",
"dstOffset": 0,
"src":"#define RT_MAIN_THREAD_STACK_SIZE 256",
"dst":"#define RT_MAIN_THREAD_STACK_SIZE 2048"
},
{
"filePath": "bsp/rtconfig.h",
"findStr": "//#define RT_USING_HEAP\r",
"dstOffset": 0,
"src":"//#define RT_USING_HEAP\r",
"dst":"#define RT_USING_HEAP\r"
},
{
"filePath": "bsp/board.c",
"findStr": "#define RT_HEAP_SIZE 1024\r",
"dstOffset": 0,
"src":"#define RT_HEAP_SIZE 1024\r",
"dst":"#define RT_HEAP_SIZE 1024 * 20"
}
]
}
第三步 添加快捷菜单项
当日总结
主线程栈默认值点灯都跑不起来【#define RT_MAIN_THREAD_STACK_SIZE 256】。
启用动态堆【#define RT_USING_HEAP】之后可以动态创建线程,但是线程栈总大小被【#define RT_HEAP_SIZE 1024】限制了,所以简单调节一下即可。