zoukankan      html  css  js  c++  java
  • RT-thread内核之空闲线程

      空闲线程是系统线程中一个比较特殊的线程,它具有最低的优先级,当系统中无其他线程可运行时,调度器将调度到空闲线程。空闲线程通常是一个死循环,永远不被挂起。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.c
    2015.12.4 by Huangtao
     
     */
    
    #include <board.h>
    #include <rtthread.h>
    
    #ifdef  RT_USING_COMPONENTS_INIT
    #include <components.h>
    #endif  /* RT_USING_COMPONENTS_INIT */
    
    #ifdef RT_USING_DFS
    /* dfs filesystem:ELM filesystem init */
    #include <dfs_elm.h>
    /* dfs Filesystem APIs */
    #include <dfs_fs.h>
    #endif
    
    #ifdef RT_USING_RTGUI
    #include <rtgui/rtgui.h>
    #include <rtgui/rtgui_server.h>
    #include <rtgui/rtgui_system.h>
    #include <rtgui/driver.h>
    #include <rtgui/calibration.h>
    #endif
    
    #include "led.h"
    #include "LCD5110.h"
    #include "ds18b20.h"
    
    // Thread ID
    static 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        100
    
    static 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);
    }
    
    
    /*
    // led
    ALIGN(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 );
    
        }
    }
    
    // lcd5110
    static 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 );
    
        }
    
    }
    
    // ds18b20
    static 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!
    ");
        }
        else
            rt_kprintf("File System initialzation failed!
    ");
    #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.c
    2015.12.4 by Huangtao
     
     */
    
    #include <board.h>
    #include <rtthread.h>
    
    #ifdef  RT_USING_COMPONENTS_INIT
    #include <components.h>
    #endif  /* RT_USING_COMPONENTS_INIT */
    
    #ifdef RT_USING_DFS
    /* dfs filesystem:ELM filesystem init */
    #include <dfs_elm.h>
    /* dfs Filesystem APIs */
    #include <dfs_fs.h>
    #endif
    
    #ifdef RT_USING_RTGUI
    #include <rtgui/rtgui.h>
    #include <rtgui/rtgui_server.h>
    #include <rtgui/rtgui_system.h>
    #include <rtgui/driver.h>
    #include <rtgui/calibration.h>
    #endif
    
    // 我加入的
    #include "led.h"
    #include "LCD5110.h"
    #include "ds18b20.h"
    #include "usart.h"
    #include "TIM3_PWM.h"
    
    // Thread ID
    static 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        100
    
    static 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] = "
    Open uart2 OK.";
    // 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);
    }
    
    
    /*
    // led
    ALIGN(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);
        }
    }
    
    // lcd5110
    static 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 );
    
        }
    
    }
    
    // ds18b20
    static 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] = '';
    
                
                // '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] = '';
                    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!
    ");
        }
        else
            rt_kprintf("File System initialzation failed!
    ");
    #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;
    }
  • 相关阅读:
    [总结]FFMPEG视音频编解码零基础学习方法--转
    ffmpeg中swscale 的用法
    FFmpeg解码H264及swscale缩放详解
    C++: std::string 与 Unicode 如何结合?
    SpringBoot-@RequestParam
    SpringBoot --web 应用开发之文件上传
    Java并发编程:线程池的使用
    Executor线程池的最佳线程数量计算
    并发下线程池的最佳数量计算
    根据CPU核心数确定线程池并发线程数
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/8524692.html
Copyright © 2011-2022 走看看