RT_Tread是一款国内开源的物联网操作系统,前不久出了一款IDE,今天上手体验了一下,感觉很不错。第一次使用有很多不熟悉的地方,先来点个灯。
这个网上也百度得到,我在这放上下载链接:下载官网。安装也很简单,采用下一步安装法即可。
首先他的界面比较简洁好看,创建工程也比较简单。
可以在项目资源管理处右键-新建-项目,也可以在左上角文件点击新建-项目。
这时需要选择项目类型,如果是裸跑不加操作系统的话,或者像移植其他操作系统的话,可以选择新建裸板项目,如果使用RT_Thread操作系统的话,选择RT_Thread项目。我在这里选择后者。
填写项目信息,需要注意的时,在选择版本的时候,有一个nano-v3.1.3的版本,RT-Thread Nano 它是一个极简版的硬实时内核,算是RT-Thread的精简版,比较简单,容易移植,且占用资源较少。但是既然是精简版,必然比RT-Thread缺少一些东西。我在这里选择的是v4.0.2的版本。其他信息就是根据自己的情况配置。
点击完成,便开始自己创建项目模板了。到这里创建也就完成了。
进入工程,感觉功能比较齐全,可玩性比较高。
点击项目文件夹下的RT-Thread Setting文件可以看到一个组件和驱动配置的界面:
我们可以通过添加软件包的方式将需要的软件包移植添加到工程内部:
添加驱动和组件的方式也十分简单,直接在你想要添加的组件或者驱动将双击即可,不需要复杂的配置代码,简化了开发流程。
回到代码部分,我在applications文件夹下创建了两个文件,分别是led.c
和led.h
先将这两部分代码贴出来
led.h:
#ifndef APPLICATIONS_LED_H_
#define APPLICATIONS_LED_H_
#include
#include
#define LED0_PIN GET_PIN(B, 5)
#define LED1_PIN GET_PIN(E, 5)
void led0();
void led1();
int led0_task();
int led1_task();
#endif /* APPLICATIONS_LED_H_ */
这里面没什么好说的,宏定义了我板子上的两个灯的引脚,然后是下面led.c文件的函数声明。
led.c:
#include "led.h"
void led0()
{
int count = 1;
while (count++)
{
/* set LED0 pin level to high or low */
rt_pin_write(LED0_PIN, count % 2);//通过给LED0取余,实现LED的闪烁。
rt_thread_mdelay(1000);//延时
}
}
void led1()
{
int count = 1;
while (count++)
{
/* set LED0 pin level to high or low */
rt_pin_write(LED1_PIN, count % 2);
rt_thread_mdelay(500);
}
}
//创建任务;
int led0_task()
{
rt_thread_t num;
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
num=rt_thread_create("LED0", led0, RT_NULL, 2048, 12, 10);
if(num!=RT_NULL)
{
rt_thread_startup(num);
}
return RT_EOK;
}
int led1_task()
{
rt_thread_t num;
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
num=rt_thread_create("LED1", led1, RT_NULL, 2048, 10, 10);
if(num!=RT_NULL)
{
rt_thread_startup(num);
}
return RT_EOK;
}
rt_thread_t
表示的是线程的句柄,在C语言中的实现是指向线程控制块的指针,详细定义情况见以下代码:
/* rt_thread_t线程句柄,指向线程控制块的指针 */
typedef struct rt_thread* rt_thread_t;
/*
* 线程控制块
*/
struct rt_thread
{
/* RT-Thread根对象定义 */
char name[RT_NAME_MAX]; /* 对象的名称*/
rt_uint8_t type; /* 对象的类型*/
rt_uint8_t flags; /* 对象的参数*/
#ifdef RT_USING_MODULE
void *module_id; /* 线程所在的模块ID*/
#endif
rt_list_t list; /* 对象链表*/
rt_list_t tlist; /* 线程链表*/
/* 栈指针及入口 */
void* sp; /* 线程的栈指针*/
void* entry; /* 线程入口*/
void* parameter; /* 线程入口参数*/
void* stack_addr; /* 线程栈地址*/
rt_uint16_t stack_size; /* 线程栈大小*/
rt_err_t error; /* 线程错误号*/
rt_uint8_t stat; /* 线程状态 */
/* 优先级相关域 */
rt_uint8_t current_priority; /* 当前优先级*/
rt_uint8_t init_priority; /* 初始线程优先级*/
#if RT_THREAD_PRIORITY_MAX > 32
rt_uint8_t number;
rt_uint8_t high_mask;
#endif
rt_uint32_t number_mask;
#if defined(RT_USING_EVENT)
/* 事件相关域 */
rt_uint32_t event_set;
rt_uint8_t event_info;
#endif
rt_ubase_t init_tick; /* 线程初始tick*/
rt_ubase_t remaining_tick; /* 线程当次运行剩余tick */
struct rt_timer thread_timer; /* 线程定时器*/
/* 当线程退出时,需要执行的清理函数 */
void (*cleanup)(struct rt_thread *tid);
rt_uint32_t user_data; /* 用户数据*/
};
rt_pin_mode()
函数是将LED的脚定义为输出。
rt_thread_create()
自然是创建线程。
顺序对应参数分别是:线程名、入口函数、函数输入参数、线程栈大小、线程优先级(数字越小优先级越高,0为最高优先级)、线程时间片。
代码中RT_NULL
所表示的意思为无输入参数。
然后就是启动线程了。
主函数的代码改动不多,直接截图:
这样这个点亮两个LED小灯的工程就完成了。