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; }
烧录,启动
输入list_device指令后可以看到,设备框架下多了一条用户自定义的led设备
输入list_thread指令后可以看到当前运行的所有线程,以及他们对当前系统资源的最大占用率
输入thread_sample后可以看到,电路板上的LED灯亮起
再次输入list_thread,发现我们定义的线程已经挂载到了系统上,系统最大占用率为35%