将简单的点亮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%