在这个函数中调用了rt_thread_init(......)函数初始化led线程,这个函数暂且先不深入,这个函数是我们所用的RTT官方第一个函数,遵循RTT的命名规则,以小写的rt开头,表示这是一个外部函数,可以由yoghurt调用,以_rt开头表示只能由RT-Thread内部使用,紧接着是文件名,表示该函数改放在哪个文件,最后是函数名称;
初始化完了之后,调用 rt_thread_startup() 函数启动线程并将其加入到就绪队列中,并启动调度器,然后由操作系统运行,进行线程切换等等,这个部分是RT-Thread内核的重中之重,到后面再具体深入讲解,这里了解即可。
讲述完了 led_sample_init 这个函数,其功能就是初始化线程,然后启动线程,加入就绪队列,由系统调度,切换,运行,所以我么只需要在用户入口代码中调用这个函数即可:
int main(void)
{
/* user app entry */
led_sample_init();
return 0;
}
然后编译,进入debug模式,运行,可以从UART#1窗口中观察到现象:
这里我们采用了原有的led例程,从如何创建一个线程,到如何初始化一个线程,最后运行流水灯线程,成功看到UART#1打印出的实验现象,下面我们来自己动手创建两个线程,一个静态线程,一个动态线程,方便对比,为了调用led相关函数,我们直接在led.c中编写; 2.3.2.动态线程的创建
RT-Thread中静态线程的线程堆栈由编译器静态分配,使用 rt_thread_init() 函数创建;而RT-Thread中动态线程的堆栈是由系统动态分配的,使用rt_thread_create() 创建,因为两个线程操作的是统一个led,为了避免冲突,我们只适用串口打印观察现象,代码如下:
修改led1线程的主体代码如下:
{
//rt_hw_led_init();
while (1)
{
/* led1 on */
rt_kprintf("led1 on\r\n");
//rt_hw_led_on(0);
rt_thread_delay(RT_TICK_PER_SECOND / 2);
/* led1 off */
rt_kprintf("led1 off\r\n");
//rt_hw_led_off(0);
rt_thread_delay(RT_TICK_PER_SECOND / 2);
}
}
然后增添led2线程的主体代码:
static void led2_thread_entry(void *parameter){
//rt_hw_led_init();
while (1)
{
/* led2 on */
rt_kprintf("led2 on\r\n");
//rt_hw_led_on(0);
rt_thread_delay(RT_TICK_PER_SECOND / 2);
/* led2 off */
rt_kprintf("led2 off\r\n");
//rt_hw_led_off(0);
rt_thread_delay(RT_TICK_PER_SECOND / 2);
}
}
然后新建一个函数创建这两个线程,代码如下:
int blink_led_init(void){
rt_err_t result;
/* 动态线程的线程控制块指针 */
rt_thread_t led2_thread;
/* 创建静态线程*/
result = rt_thread_init(&led_thread,
"led",
led1_thread_entry,
RT_NULL,
(rt_uint8_t *)&led_stack[0],
sizeof(led_stack),
20,
5);
if (result == RT_EOK)
{
rt_thread_startup(&led_thread);
}
/* 创建动态线程*/
led2_thread = rt_thread_create("led2",
led2_thread_entry,
RT_NULL,
512,
21,
5);
if (led2_thread != RT_NULL)
{
rt_thread_startup(led2_thread);
}
return 0;
}