RT-thread实时操作系统实战



  • 将简单的点亮LED封装成设备
    首先,RT-thread提供了PIN设备框架,我们使用PIN对引脚进行初始化

    /* defined the LED0 pin: PA8 */
    #define LED0_PIN        GET_PIN(A, 8)
    
    static struct rt_device _led_dev;
    

    接着,我们完成对LED功能的封装,要定义设备指令与初始化函数

    #define LED_CTRL_CMD_POWER_OFF          0x00
    #define LED_CTRL_CMD_POWER_ON           0x01
    #define LED0_CTRL_CMD_POWER_OFF         0x02
    #define LED0_CTRL_CMD_POWER_ON          0x03
    
    int led_device_init(void);
    

    初始化函数如下:

    int led_device_init(void)
    {
        return led_device_register(LED_DEVICE_NAME, RT_NULL);
    }
    

    设备框架如下

    static rt_err_t  _led_init(rt_device_t dev)
    {
        rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    
        return RT_EOK;
    }
    
    static rt_err_t  _led_open(rt_device_t dev, rt_uint16_t oflag)
    {
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return RT_EOK;
    }
    
    static rt_err_t _led_close(rt_device_t dev)
    {
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return RT_EOK;
    }
    
    static rt_err_t  _led_control(rt_device_t dev, int cmd, void *args)
    {
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        switch (cmd)
        {
            case LED_CTRL_CMD_POWER_ON:
                rt_pin_write(LED0_PIN, PIN_HIGH);
                break;
            case LED_CTRL_CMD_POWER_OFF:
                rt_pin_write(LED0_PIN, PIN_LOW);
                break;
            case LED0_CTRL_CMD_POWER_ON:
                rt_pin_write(LED0_PIN, PIN_HIGH);
                break;
            case LED0_CTRL_CMD_POWER_OFF:
                rt_pin_write(LED0_PIN, PIN_LOW);
                break;
            default:
                break;
        }
    
        return RT_EOK;
    }
    
    #ifdef RT_USING_DEVICE_OPS
    const static struct rt_device_ops led_dev_ops =
    {
        _led_init,
        _led_open,
        _led_close,
        RT_NULL,
        RT_NULL,
        _led_control
    };
    #endif
    
    static int led_device_register(const char *name, void *user_data)
    {
        _led_dev.type         = RT_Device_Class_Miscellaneous;
        _led_dev.rx_indicate  = RT_NULL;
        _led_dev.tx_complete  = RT_NULL;
    
    #ifdef RT_USING_DEVICE_OPS
        _led_dev.ops          = &led_dev_ops;    
    #else
        _led_dev.init         = _led_init;
        _led_dev.open         = _led_open;
        _led_dev.close        = _led_close;
        _led_dev.read         = RT_NULL;
        _led_dev.write        = RT_NULL;
        _led_dev.control      = _led_control;
    #endif
    
        _led_dev.user_data    = user_data;
    
        /* register a character device */
        rt_device_register(&_led_dev, name, RT_DEVICE_FLAG_RDWR);
    
        return 0;
    }
    

    下面,我们定义应用函数

    rt_err_t led_grn_init(void);
    rt_err_t led_grn_power_on(void);
    rt_err_t led_grn_power_off(void);
    rt_err_t led0_grn_power_on(void);
    rt_err_t led0_grn_power_off(void);
    
    #ifndef LED_DEVICE_NAME
    #define LED_DEVICE_NAME            "led"
    #endif
    
    static rt_device_t led_dev = RT_NULL;
    
    static rt_device_t get_led_dev(void)
    {
        if (led_dev != RT_NULL)
            return led_dev;
    
        led_dev = rt_device_find(LED_DEVICE_NAME);
    
        return led_dev;
    }
    
    static rt_err_t led_open(void)
    {
        rt_device_t dev = get_led_dev();
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return rt_device_open(dev, RT_DEVICE_FLAG_RDWR);
    }
    
    rt_err_t led_grn_init(void)
    {
        led_device_init();
        return led_open();
    }
    
    rt_err_t led_grn_power_on(void)
    {
        rt_device_t dev = get_led_dev();
    
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return rt_device_control(dev, LED_CTRL_CMD_POWER_ON, RT_NULL);
    }
    
    rt_err_t led_grn_power_off(void)
    {
        rt_device_t dev = get_led_dev();
    
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return rt_device_control(dev, LED_CTRL_CMD_POWER_OFF, RT_NULL);
    }
    
    rt_err_t led0_grn_power_on(void)
    {
        rt_device_t dev = get_led_dev();
    
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return rt_device_control(dev, LED0_CTRL_CMD_POWER_ON, RT_NULL);
    }
    
    rt_err_t led0_grn_power_off(void)
    {
        rt_device_t dev = get_led_dev();
    
        if (dev == RT_NULL)
            return -RT_ERROR;
    
        return rt_device_control(dev, LED0_CTRL_CMD_POWER_OFF, RT_NULL);
    }
    

    定义线程

    #define THREAD_PRIORITY         25
    #define THREAD_STACK_SIZE       512
    #define THREAD_TIMESLICE        5
    
    static rt_thread_t tid1 = RT_NULL;
    
    /* 线程 1 的入口函数 */
    static void thread1_entry(void *parameter)
    {
        int i=1;
        while(1)
        {
            for(; i<90; i++){
                led0_grn_power_on();
                rt_thread_mdelay(i/6);
                led0_grn_power_off();
                rt_thread_mdelay(16-i/6);
            }
            for(; i>1; i--){
                led0_grn_power_on();
                rt_thread_mdelay(i/6);
                led0_grn_power_off();
                rt_thread_mdelay(16-i/6);
            }
        }
    }
    

    编写线程注册函数

    /* 线程示例 */
    int thread_sample(void)
    {
        /* 创建线程 1,名称是 thread1,入口是 thread1_entry*/
        tid1 = rt_thread_create("thread1",
                                thread1_entry, RT_NULL,
                                THREAD_STACK_SIZE,
                                THREAD_PRIORITY, THREAD_TIMESLICE);
    
        /* 如果获得线程控制块,启动这个线程 */
        if (tid1 != RT_NULL)
            rt_thread_startup(tid1);
    
        return 0;
    }
    

    将线程注册函数挂载到finsh框架中

    /* 导出到 msh 命令列表中 */
    MSH_CMD_EXPORT(thread_sample, thread sample);
    

    main函数只需要进行设备初始化

    int main(void)
    {
        int count = 1;
        led_grn_init();
        while (count++)
        {
            rt_thread_mdelay(1000);
        }
    
        return RT_EOK;
    }
    

    烧录,启动
    0_1653208106859_d03e4aa4-52e5-4f1a-9857-636ecd112a3d-image.png
    输入list_device指令后可以看到,设备框架下多了一条用户自定义的led设备
    输入list_thread指令后可以看到当前运行的所有线程,以及他们对当前系统资源的最大占用率
    输入thread_sample后可以看到,电路板上的LED灯亮起
    再次输入list_thread,发现我们定义的线程已经挂载到了系统上,系统最大占用率为35%
    0_1653208194969_00d12281-ad05-42cf-88d1-4afe8ddee4c3-image.png


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待