空闲线程是系统线程中一个比较特殊的线程,它具有最低的优先级,当系统中无其他线程可运行时,调度器将调度到空闲线程。空闲线程通常是一个死循环,永远不被挂起。RT-Thread实时操作系统为空闲线程提供了钩子函数(钩子函数:用户提供的一段代码,在系统运行的某一路径上设置一个钩子,当系统经过这个位置时,转而执行这个钩子函数,然后再返回到它的正常路径上),可以让系统在空闲的时候执行一些特定的任务,例如系统运行指示灯闪烁,电源管理等。除了调用钩子函数,RT-Thread也把线程清理(rt_thread->cleanup回调函数)函数、真正的线程删除动作放到了空闲线程中(在脱离或删除线程时,仅改变线程的状态为关闭状态不再参与系统调度)。
空闲线程函数接口:(在src/idle.c中定义)
空闲线程初始化:/** * @ingroup SystemInit * * This function will initialize idle thread, then start it. * * @note this function must be invoked when system init. */void rt_thread_idle_init(void){ /* initialize thread */ rt_thread_init(&idle, "tidle", rt_thread_idle_entry, //空闲线程入口函数 RT_NULL, //入口函数参数为空 &rt_thread_stack[0], //空闲线程栈地址 sizeof(rt_thread_stack), //栈大小,默认为128字节,若使用钩子函数或动态堆时为256字节,在idle.c中宏定义 RT_THREAD_PRIORITY_MAX - 1,//空闲线程优先级最低 32); //时间片为32个时钟节拍 /* startup */ rt_thread_startup(&idle);}
空闲线程入口函数:static void rt_thread_idle_entry(void *parameter){ while (1) { #ifdef RT_USING_HOOK if (rt_thread_idle_hook != RT_NULL) rt_thread_idle_hook();//若使用钩子且钩子函数不为空,则执行钩子函数 #endif rt_thread_idle_excute(); //空闲线程的真正执行函数 }}
空闲线程执行函数:void rt_thread_idle_excute(void){ /* Loop until there is no dead thread. So one call to rt_thread_idle_excute * will do all the cleanups. */ while (_has_defunct_thread()) //检查僵尸线程链表中是否存在僵尸线程,以前的版本中用if (!rt_list_isempty(&rt_thread_defunct))来判断,这样每次只能清除一个僵尸线程 { rt_base_t lock; rt_thread_t thread;#ifdef RT_USING_MODULE rt_module_t module = RT_NULL;#endif RT_DEBUG_NOT_IN_INTERRUPT; //确保此函数不是在中断服务中,若RT_DEBUG_CONTEXT_CHECK is 1 in rtdebug.h,则该宏表示这个函数不能用于中断ISR中。通过检查rt_interrupt_nest中断嵌套计数器是否为0来判断 /* disable interrupt */ lock = rt_hw_interrupt_disable(); /* re-check whether list is empty */ if (_has_defunct_thread()) //再次判断rt_thread_defunct是否为空,若不为空 { /* get defunct thread */ thread = rt_list_entry(rt_thread_defunct.next, struct rt_thread, tlist); //获取待回收的僵尸线程 #ifdef RT_USING_MODULE /* get thread's parent module */ module = (rt_module_t)thread->module_id;//得到模块ID /* if the thread is module's main thread */ if (module != RT_NULL && module->module_thread == thread) { /* detach module's main thread */ module->module_thread = RT_NULL; //清空模块线程 }#endif /* remove defunct thread */ rt_list_remove(&(thread->tlist)); //重置线程链表节点为初始值,即节点next与prev均指向自身节点,即将线程从僵尸线程链表中移除 /* invoke thread cleanup */ if (thread->cleanup != RT_NULL) thread->cleanup(thread); //执行线程清理函数 /* if it's a system object, not delete it */ if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)//若该僵尸线程内核对象为静态对象,则不删除该对程内核对象 { /* enable interrupt */ rt_hw_interrupt_enable(lock); return; } } else //若再次判断rt_thread_defunct僵尸线程链表为空 { /* enable interrupt */ rt_hw_interrupt_enable(lock); /* may the defunct thread list is removed by others, just return */ return; } /* enable interrupt */ rt_hw_interrupt_enable(lock);#ifdef RT_USING_HEAP //程序运行到这,说明上文处理的僵尸线程为动态创建的线程#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) /* the thread belongs to an application module */ if (thread->flags & RT_OBJECT_FLAG_MODULE) rt_module_free((rt_module_t)thread->module_id, thread->stack_addr);//释放模块主线程栈所占内存 else#endif /* release thread's stack */ RT_KERNEL_FREE(thread->stack_addr); //释放动态线程栈所占内存 /* delete thread object */ rt_object_delete((rt_object_t)thread);//删除动态线程内核对象,即从当前类型的内核对象链表中移除,同时释放内核对象所占空间(若使用了模块功能,还要释放模块ID所占空间)#endif#ifdef RT_USING_MODULE if (module != RT_NULL) { extern rt_err_t rt_module_destroy(rt_module_t module); /* if sub thread list and main thread are all empty */ //若模块主线程为空,且子线程对象链表为空 if ((module->module_thread == RT_NULL) && rt_list_isempty(&module->module_object[RT_Object_Class_Thread].object_list)) { module->nref --; } /* destroy module */ if (module->nref == 0) rt_module_destroy(module);//销毁模块 }#endif }}
实例应用:
RT-Thread-v2.0.0移植到STM32及驱动LCD和测温
/*application.c2015.12.4 by Huangtao */#include#include #ifdef RT_USING_COMPONENTS_INIT#include #endif /* RT_USING_COMPONENTS_INIT */#ifdef RT_USING_DFS/* dfs filesystem:ELM filesystem init */#include /* dfs Filesystem APIs */#include #endif#ifdef RT_USING_RTGUI#include #include #include #include #include #endif#include "led.h"#include "LCD5110.h"#include "ds18b20.h"// Thread IDstatic rt_thread_t led_id = RT_NULL;static rt_thread_t lcd5110_id = RT_NULL;static rt_thread_t ds18b20_id = RT_NULL;#define CPU_USAGE_CALC_TICK 10#define CPU_USAGE_LOOP 100static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0;static rt_uint32_t total_count = 0;static void cpu_usage_idle_hook(){ rt_tick_t tick; rt_uint32_t count; volatile rt_uint32_t loop; if (total_count == 0) { /* get total count */ rt_enter_critical(); tick = rt_tick_get(); while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { total_count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } rt_exit_critical(); } count = 0; /* get CPU usage */ tick = rt_tick_get(); while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } /* calculate major and minor */ if (count < total_count) { count = total_count - count; cpu_usage_major = (count * 100) / total_count; cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count; } else { total_count = count; /* no CPU usage */ cpu_usage_major = 0; cpu_usage_minor = 0; }}/*void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor){ RT_ASSERT(major != RT_NULL); RT_ASSERT(minor != RT_NULL); *major = cpu_usage_major; *minor = cpu_usage_minor;}*/void cpu_usage_init(){ /* set idle thread hook */ rt_thread_idle_sethook(cpu_usage_idle_hook);}/*// ledALIGN(RT_ALIGN_SIZE)static rt_uint8_t led_stack[ 512 ];static struct rt_thread led_thread;*/static void led_thread_entry(void* parameter){ rt_hw_led_init(); while (1) { /* led1 on */ rt_hw_led_on(0); // 顺便清屏 ClearScreen(); rt_thread_delay( 100 ); /* sleep 1 second and switch to other thread */ /* led1 off */ rt_hw_led_off(0); // 顺便清屏 //ClearScreen(); rt_thread_delay( 100 ); }}// lcd5110static void lcd5110_thread_entry(void* parameter){ LcdInit(); while(1) { DispString(15,0,"RT-Thread"); DispString(0,1,"CPU:"); DispNum(30,1,cpu_usage_major); DispChar(45,1,'%'); rt_thread_delay( 5 ); }}// ds18b20static void ds18b20_thread_entry(void* parameter){ short temperature = 0; while(DS18B20_Init()); while(1) { DispString(0,3,"Temp: "); temperature = DS18B20_Get_Temp(); if(temperature<0) { DispChar(40,3,'-'); temperature=-temperature; } else DispChar(40,3,' '); DispNum(48,3,((u16)temperature)/10); //显示正数部分 DispChar(60,3,'.'); DispNum(67,3,((u16)temperature)%10); //显示小数部分 rt_thread_delay( 5 ); }}void rt_init_thread_entry(void* parameter){#ifdef RT_USING_COMPONENTS_INIT /* initialization RT-Thread Components */ rt_components_init();#endif#ifdef RT_USING_FINSH finsh_set_device(RT_CONSOLE_DEVICE_NAME);#endif /* RT_USING_FINSH */ /* Filesystem Initialization */#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT) /* mount sd card fat partition 1 as root directory */ if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) { rt_kprintf("File System initialized!\n"); } else rt_kprintf("File System initialzation failed!\n");#endif /* RT_USING_DFS */#ifdef RT_USING_RTGUI { extern void rt_hw_lcd_init(); extern void rtgui_touch_hw_init(void); rt_device_t lcd; /* init lcd */ rt_hw_lcd_init(); /* init touch panel */ rtgui_touch_hw_init(); /* find lcd device */ lcd = rt_device_find("lcd"); /* set lcd device as rtgui graphic driver */ rtgui_graphic_set_device(lcd);#ifndef RT_USING_COMPONENTS_INIT /* init rtgui system server */ rtgui_system_server_init();#endif calibration_set_restore(cali_setup); calibration_set_after(cali_store); calibration_init(); }#endif /* #ifdef RT_USING_RTGUI */}int rt_application_init(void){ rt_thread_t init_thread; /* rt_err_t result; // 静态创建 led 线程 result = rt_thread_init(&led_thread, // 线程控制块内存地址 "led", // 线程名称 led_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 (rt_uint8_t*)&led_stack[0], // 线程栈起始地址 sizeof(led_stack), // 线程栈大小 20, // 线程优先级 5); // 线程时间片大小 if (result == RT_EOK) { rt_thread_startup(&led_thread); } */ // 动态创建 led 线程 led_id = rt_thread_create("led", // 线程名称 led_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 512, // 线程栈大小 21, // 线程优先级 10); // 线程时间片大小 // 如果获得线程控制块,启动这个线程 if (led_id != RT_NULL) rt_thread_startup(led_id); // 动态创建 lcd5110 线程 lcd5110_id = rt_thread_create("lcd5110", // 线程名称 lcd5110_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 2048, // 线程栈大小 20, // 线程优先级 20); // 线程时间片大小 if (lcd5110_id != RT_NULL) rt_thread_startup(lcd5110_id); // 动态创建 ds18b20 线程 ds18b20_id = rt_thread_create("ds18b20", // 线程名称 ds18b20_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 2048, // 线程栈大小 19, // 线程优先级 20); // 线程时间片大小 if (ds18b20_id != RT_NULL) rt_thread_startup(ds18b20_id); // CPU % cpu_usage_init();#if (RT_THREAD_PRIORITY_MAX == 32) init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, 8, 20);#else init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, 80, 20);#endif if (init_thread != RT_NULL) rt_thread_startup(init_thread); return 0;}
实例应用2:
/*application.c2015.12.4 by Huangtao */#include#include #ifdef RT_USING_COMPONENTS_INIT#include #endif /* RT_USING_COMPONENTS_INIT */#ifdef RT_USING_DFS/* dfs filesystem:ELM filesystem init */#include /* dfs Filesystem APIs */#include #endif#ifdef RT_USING_RTGUI#include #include #include #include #include #endif// 我加入的#include "led.h"#include "LCD5110.h"#include "ds18b20.h"#include "usart.h"#include "TIM3_PWM.h"// Thread IDstatic rt_thread_t led_id = RT_NULL;static rt_thread_t fan_id = RT_NULL;static rt_thread_t lcd5110_id = RT_NULL;static rt_thread_t ds18b20_id = RT_NULL;static rt_thread_t uart2_id = RT_NULL;#define CPU_USAGE_CALC_TICK 10#define CPU_USAGE_LOOP 100static rt_uint8_t cpu_usage_major = 0;//static cpu_usage_minor= 0;static rt_uint32_t total_count = 0;/*自定义通信协议:ledControl:'L'+ 0x10----led1 off 0x11----led1 on 0x20----led2 off 0x21----led2 on ...fanControl:'F'+ 0xf0----fan off 0xf1----speed 1 0xf2----speed 2 ...*/static short temperature = 0;static char ledControl = 0;static char fanControl = 0;// 访问温度的互斥量static rt_mutex_t mutexTemperature = RT_NULL;static rt_mutex_t mutexLed = RT_NULL;static rt_mutex_t mutexFan = RT_NULL;// stm32_usart2发送缓冲区static char uart_tx_buffer[64] = "\nOpen uart2 OK.\0";// stm32_usart2接收缓冲区static char uart_rx_buffer[64];// USART 接收消息结构struct rx_msg{ rt_device_t dev; rt_size_t size;};// 用于接收消息的消息队列控制块static rt_mq_t rx_mq;static struct rt_messagequeue my_rx_mq;// 消息队列中用到的放置消息的内存池static char msg_pool[1024];static void cpu_usage_idle_hook(){ rt_tick_t tick; rt_uint32_t count; volatile rt_uint32_t loop; if (total_count == 0) { /* get total count */ rt_enter_critical(); tick = rt_tick_get(); while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { total_count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } rt_exit_critical(); } count = 0; /* get CPU usage */ tick = rt_tick_get(); while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } /* calculate major and minor */ if (count < total_count) { count = total_count - count; cpu_usage_major = (count * 100) / total_count; //cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count; } else { total_count = count; /* no CPU usage */ cpu_usage_major = 0; //cpu_usage_minor = 0; }}void cpu_usage_init(){ /* set idle thread hook */ rt_thread_idle_sethook(cpu_usage_idle_hook);}/*// ledALIGN(RT_ALIGN_SIZE)static rt_uint8_t led_stack[ 512 ];static struct rt_thread led_thread;*/static void led_thread_entry(void* parameter){ rt_hw_led_init(); while (1) { rt_mutex_take(mutexLed, RT_WAITING_FOREVER); if(ledControl == 0x11) { // led1 on rt_hw_led_on(0); } else if(ledControl == 0x10) { // led1 off rt_hw_led_off(0); } else if(ledControl == 0x21) { // led2 on rt_hw_led_on(1); } else if(ledControl == 0x20) { // led2 off rt_hw_led_off(1); } rt_mutex_release(mutexLed); // 顺便清屏 //ClearScreen(); rt_thread_delay( 10 ); }}static void fan_thread_entry(void* parameter){ short Compare2Num = 0; TIM3_PWM_Init(900,5); // PWM频率=72000/5/900 while(1) { rt_mutex_take(mutexFan, RT_WAITING_FOREVER); switch(fanControl) { case 0xf0: Compare2Num=0; break; // 关 case 0xf1: Compare2Num=100; break; // 1档 case 0xf2: Compare2Num=150; break; // 2档 case 0xf3: Compare2Num=200; break; // ... case 0xf4: Compare2Num=250; break; case 0xf5: Compare2Num=300; break; case 0xf6: Compare2Num=350; break; case 0xf7: Compare2Num=400; break; case 0xf8: Compare2Num=450; break; case 0xf9: Compare2Num=500; break; case 0xfa: Compare2Num=600; break; case 0xfb: Compare2Num=700; break; case 0xfc: Compare2Num=800; break; case 0xfd: Compare2Num=900; break; // 13档 default: break; } rt_mutex_release(mutexFan); TIM_SetCompare2(TIM3, Compare2Num); rt_thread_delay(10); }}// lcd5110static void lcd5110_thread_entry(void* parameter){ LcdInit(); while(1) { DispString(15,0,"RT-Thread"); DispString(0,1,"CPU:"); DispNum(30,1,cpu_usage_major); DispChar(45,1,'%'); rt_thread_delay( 5 ); }}// ds18b20static void ds18b20_thread_entry(void* parameter){ short showTemp; //rt_err_t result; while(DS18B20_Init()); while(1) { DispString(0,3,"Temp: "); rt_mutex_take(mutexTemperature, RT_WAITING_FOREVER); temperature = DS18B20_Get_Temp(); showTemp = temperature; rt_mutex_release(mutexTemperature); if(showTemp<0) { DispChar(40,3,'-'); showTemp=-showTemp; } else DispChar(40,3,' '); DispNum(48,3,((u16)showTemp)/10); //显示正数部分 DispChar(60,3,'.'); DispNum(67,3,((u16)showTemp)%10); //显示小数部分 rt_thread_delay( 5 ); }}// uart2//===============================================// 数据到达回调函数// rt_err_t(*)(rt_device_t dev, rt_size_t size) rt_err_t uart_input(rt_device_t dev, rt_size_t size){ struct rx_msg msg; msg.dev = dev; msg.size = size; if(size >=2) { // 发送消息到消息队列中 rt_mq_send(rx_mq, &msg, sizeof(struct rx_msg)); } return RT_EOK;}static void uart2_thread_entry(void* parameter){ rt_err_t result = RT_EOK; struct rx_msg msg; rt_device_t stm32_uart2; rt_uint32_t rx_length; // 根据注册名查找设备 stm32_uart2 = rt_device_find("uart2"); if (stm32_uart2 != RT_NULL) { // 初始化设备 rt_device_init(stm32_uart2); // 设置回调函数(当设备接收到数据执行) rt_device_set_rx_indicate(stm32_uart2, uart_input); // 打开设备 rt_device_open(stm32_uart2, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM); } rt_device_write(stm32_uart2, 0, &uart_tx_buffer[0], 18); while(1) { // 从消息队列中读取消息, RT_WAITING_FOREVER result = rt_mq_recv(rx_mq, &msg, sizeof(struct rx_msg), RT_WAITING_FOREVER); // 成功收到消息 if(result == RT_EOK) { rx_length = (sizeof(uart_rx_buffer) - 1) > msg.size ? msg.size : sizeof(uart_rx_buffer) - 1; // 读取消息 rx_length = rt_device_read(msg.dev, 0, &uart_rx_buffer[0], rx_length); uart_rx_buffer[rx_length] = '\0'; // 'F' + fanControl if(uart_rx_buffer[0] == 0x46) { rt_mutex_take(mutexFan, RT_WAITING_FOREVER); fanControl = uart_rx_buffer[1]; rt_mutex_release(mutexFan); } // 'L' + ledControl else if(uart_rx_buffer[0] == 0x4c) { rt_mutex_take(mutexLed, RT_WAITING_FOREVER); ledControl = uart_rx_buffer[1]; rt_mutex_release(mutexLed); } // 收到'T',则发送温度 else if(uart_rx_buffer[0] == 0x54) { rt_mutex_take(mutexTemperature, RT_WAITING_FOREVER); uart_tx_buffer[0] = temperature & 0xff; uart_tx_buffer[1] = (temperature >> 8) & 0xff; uart_tx_buffer[2] = '\0'; rt_mutex_release(mutexTemperature); rt_device_write(stm32_uart2, 0, &uart_tx_buffer[0], 2); } // 回显观察 //rt_device_write(stm32_uart2, 0, &uart_rx_buffer[0], rx_length); } //rt_thread_delay( 5 ); }}void rt_init_thread_entry(void* parameter){#ifdef RT_USING_COMPONENTS_INIT /* initialization RT-Thread Components */ rt_components_init();#endif#ifdef RT_USING_FINSH finsh_set_device(RT_CONSOLE_DEVICE_NAME);#endif /* RT_USING_FINSH */ /* Filesystem Initialization */#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT) /* mount sd card fat partition 1 as root directory */ if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) { rt_kprintf("File System initialized!\n"); } else rt_kprintf("File System initialzation failed!\n");#endif /* RT_USING_DFS */#ifdef RT_USING_RTGUI { extern void rt_hw_lcd_init(); extern void rtgui_touch_hw_init(void); rt_device_t lcd; /* init lcd */ rt_hw_lcd_init(); /* init touch panel */ rtgui_touch_hw_init(); /* find lcd device */ lcd = rt_device_find("lcd"); /* set lcd device as rtgui graphic driver */ rtgui_graphic_set_device(lcd);#ifndef RT_USING_COMPONENTS_INIT /* init rtgui system server */ rtgui_system_server_init();#endif calibration_set_restore(cali_setup); calibration_set_after(cali_store); calibration_init(); }#endif /* #ifdef RT_USING_RTGUI */}// 创建线程和初始化//============================================================int rt_application_init(void){ rt_thread_t init_thread; // 初始化消息队列 rt_mq_init(&my_rx_mq, "mqt", &msg_pool[0], sizeof(struct rx_msg), sizeof(msg_pool), RT_IPC_FLAG_FIFO); rx_mq = &my_rx_mq; // 创建互斥锁 mutexTemperature = rt_mutex_create("mutexTemperature", RT_IPC_FLAG_FIFO); if (mutexTemperature == RT_NULL) { return 0; } mutexLed = rt_mutex_create("mutexLed", RT_IPC_FLAG_FIFO); if (mutexLed == RT_NULL) { return 0; } mutexFan = rt_mutex_create("mutexFan", RT_IPC_FLAG_FIFO); if (mutexFan == RT_NULL) { return 0; } /*rt_err_t result; // 静态创建 led 线程 result = rt_thread_init(&led_thread, // 线程控制块内存地址 "led", // 线程名称 led_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 (rt_uint8_t*)&led_stack[0], // 线程栈起始地址 sizeof(led_stack), // 线程栈大小 20, // 线程优先级 5); // 线程时间片大小 if (result == RT_EOK) { rt_thread_startup(&led_thread); }*/ // 动态创建 led 线程 led_id = rt_thread_create("led", // 线程名称 led_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 512, // 线程栈大小 21, // 线程优先级 10); // 线程时间片大小 // 如果获得线程控制块,启动这个线程 if (led_id != RT_NULL) rt_thread_startup(led_id); // 动态创建 fan 线程 fan_id = rt_thread_create("fan", // 线程名称 fan_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 1024, // 线程栈大小 20, // 线程优先级 10); // 线程时间片大小 // 如果获得线程控制块,启动这个线程 if (fan_id != RT_NULL) rt_thread_startup(fan_id); // 动态创建 lcd5110 线程 lcd5110_id = rt_thread_create("lcd5110", // 线程名称 lcd5110_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 512, // 线程栈大小 20, // 线程优先级 20); // 线程时间片大小 if (lcd5110_id != RT_NULL) rt_thread_startup(lcd5110_id); // 动态创建 ds18b20 线程 ds18b20_id = rt_thread_create("ds18b20", // 线程名称 ds18b20_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 1024, // 线程栈大小 19, // 线程优先级 20); // 线程时间片大小 if (ds18b20_id != RT_NULL) rt_thread_startup(ds18b20_id); // 动态创建 usart2 线程 uart2_id = rt_thread_create("uart2", // 线程名称 uart2_thread_entry, // 线程入口入口函数 RT_NULL, // 线程入口入口函数参数 2048, // 线程栈大小 19, // 线程优先级 15); // 线程时间片大小 if (uart2_id != RT_NULL) rt_thread_startup(uart2_id); // CPU % cpu_usage_init();#if (RT_THREAD_PRIORITY_MAX == 32) init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, 8, 20);#else init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, 80, 20);#endif if (init_thread != RT_NULL) rt_thread_startup(init_thread); return 0;}