本文介绍如何搭建一个不依靠官方ide:RT-Thread Studio来创建工程文件以及烧录编译的方法。基于官方的env工具以及基于bsp创建工程文件,基于gcc for arm编译工具编译pico的库代码。
--编辑器:vscode
--工程创建工具:env
--编译器:gcc for arm工具
--编译工具:下载|GNU Arm 嵌入式工具链下载 – Arm 开发人员
--编辑器:Visual Studio Code - Code Editing. Redefined
--env工具、源码:下载 - RT-Thread物联网操作系统
1、常规步骤安装vscode,env不需要安装,但要通过几个操作把env工具放在桌面的右键工具里。将env工具解压缩放到d盘后,官方办法:Env 用户手册 (rt-thread.org),也可以看下图:
2、进入bsp源码文件夹:
右键可以看到名为:ConEmu的工具,点击就会打开env工具。这样env工具将会定位到文件夹,而不用麻烦的用cd命令慢慢指向。如图:
进入到该文件夹后,创建工程文档。当然,直接把bsp文件当工程文件夹也可以(不推荐)。这里介绍另一种方法:直接键入命令
scons --dist
可以看到文件夹下多了个子文件夹:
这个就是刚创建的工程文件。可以看到在创建的时候会编译而且提示了错误 :
这个是因为env的默认编译器不能编译pico,需要安装gcc for arm工具。关闭当前env,进入自己用命令:scons --dist 创建的工程文件夹里用右键打开env,常规方法安装gcc for arm工具后,在env键入命令行:
注:地址需要自己修改成自己的安装路径,注意路径到bin文件夹。
注:《每次打开env工具需要重新键入下方命令行》
set RTT_CC=gcc
set RTT_EXEC_PATH=D:\gcc_FOR_arm\10 2020-q4-major\bin
如图:
3、键入 scons 命令编译,如图可以看到非常多的错误。这个需要自己按照错误的描述一点点排除,不过大部分是缺文件,或者打开了什么功能。
键入命令:menuconfig 看看打开了什么功能,如图:
源码很久前下的,一些不能开启的功能开启了导致了错误,刚下载的源码没有这个问题。比如图中的smp 多核心调度功能,虽然pico是双m0内核的,但可惜rt-thread给的bsp源码没有实现这个多核的功能。按空格取消使能后再编译:
错误少了很多。再看错误,提示cpp文件出错。还是开了不能开的功能的原因:
空格取消。 键入scons编译:
错误又少了很多。 图中的错误非常奇怪,论坛也有人提出这个问题:RT-Thread-undefined reference to `stm32f2_onchip_flash' 哪位大神给看看,这个...RT-Thread问答社区 - RT-Thread
这个依旧是开了不能开的功能的错误。
这个fal功能依旧无法使用,空格取消。 但这个功能其实很有用,很多时候需要保存一些掉电保存的数据。但官方没实现,那就莫得办法。
再次键入scons命令:
可以看到,编译结果正常。
4、修改时钟
具体步骤参考我之前的文章。
(28条消息) 关于rt-thread中的bsp:pico的延时函数延时时间不对问题_啊?这...的博客-CSDN博客
既然准备工作完成了,那我们点个灯吧。
#include
#include
#include
#include "rtdef.h"
//定义线程栈
ALIGN(RT_ALIGN_SIZE)
rt_uint8_t rt_led1_stack[512];
rt_uint8_t rt_led2_stack[512];
//线程声明
void led1_thread_entry(void *p_arg);
void led2_thread_entry(void *p_arg);
//定义线程控制块
struct rt_thread rt_led1;
struct rt_thread rt_led2;
#define LED_PIN 25
int main(void)
{
//硬件初始化代码
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
//初始化线程
rt_thread_init(
&rt_led1, //控制块
"led1", //线程名
led1_thread_entry, //线程函数
RT_NULL, //函数参数
&rt_led1_stack[0], //堆栈起始
sizeof(rt_led1_stack), //堆栈深度
1, //优先级 0-32
50); //时间片轮转调度时的执行时间
//将线程插入就绪列表
rt_thread_startup(&rt_led1);
rt_thread_init(
&rt_led2, //控制块
"led2", //线程名
led2_thread_entry, //线程函数
RT_NULL, //函数参数
&rt_led2_stack[0], //堆栈起始
sizeof(rt_led2_stack), //堆栈深度
2, //优先级 0-32
50); //时间片轮转调度时的执行时间
//将线程插入就绪列表
rt_thread_startup(&rt_led2);
}
void led1_thread_entry(void *p_arg)
{
rt_thread_mdelay(250);
while (1)
{
rt_pin_write(LED_PIN, 1);
rt_kprintf("led up \n");
rt_thread_mdelay(500);
}
}
void led2_thread_entry(void *p_arg)
{
while (1)
{
rt_pin_write(LED_PIN, 0);
rt_kprintf("led down \n");
rt_thread_mdelay(500);
}
}
使用vscode编辑器打开工程,修改main.c函数。再进env工具使用scons命令编译,然后根据pico的烧录方法烧录就能看到灯闪烁了。用usb转串口工具接串口0还能看到交替传来的数据。
看到图中给出的rt-thread代码跟freeRtos跟ucosIII的代码比起来看起来很怪,没有启动调度器也没有初始化系统,那么是怎么运行成功的?其实是因为运行main函数前先执行了borad.c文件里的函数,使得看起来main函数少了很多东西,甚至看起来允许main函数结束。但如果加了初始化函数以及调度使能,上面的代码就不能运行了。