本次任务主要学习邮箱,事件(事件集)的使用方法,下面开始发车了。
一、异步日志任务
需要创建一个mylog.c文件,在文件中新建mylog_init线程和一个mb邮箱,代码如下:
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
/* 邮箱控制块 */
static struct rt_mailbox mb;
/* 用于放邮件的内存池 */
static char mb_pool[128];
ALIGN(RT_ALIGN_SIZE)
static char td_stack[1024];
static struct rt_thread td;
void mylog(char* tag, void* data)
{
struct mylog_msg mb_data_send;
mb_data_send.tag = tag;
mb_data_send.data = (int)data;
rt_mb_send(&mb, (rt_ubase_t)&mb_data_send);
}
static void mylog_thread_entry(void *param)
{
char *str;
while(1)
{
if(rt_mb_recv(&mb, (rt_uint32_t *)str, RT_WAITING_FOREVER) == RT_EOK)
{
rt_kprintf("[%s] data is: %d<br>", str.tag, str.data);
}
}
}
int mylog_init(void)
{
rt_err_t result;
/* 初始化一个 mailbox */
result = rt_mb_init(&mb,
"mb_air", /* 名称是 mbt */
&mb_pool[0], /* 邮箱用到的内存池是 mb_pool */
sizeof(mb_pool) / 4, /* 邮箱中的邮件数目,因为一封邮件占 4 字节 */
RT_IPC_FLAG_FIFO); /* 采用 FIFO 方式进行线程等待 */
if (result != RT_EOK)
{
rt_kprintf("init mailbox failed.<br>");
return -1;
}
/* 创建线程 */
td = rt_thread_create("mylog",
mylog_entry, /* 线程入口函数 *
RT_NULL,
1024, /* 线程栈大小 */
30,
20);
if (td == RT_NULL)
{
rt_kprintf("create thread (mylog) failed.<br>");
return -1;
}
rt_thread_startup(td);
return RT_EOK;
}
INIT_APP_EXPORT(mylog_init);
```使用过程中只需调用mylog函数即可。
二、事件使用
本部分主要为按键发送事件,LED与传感器接收事件,代码如下:
```#define EVENT_LED_ON (1 << 0)
#define EVENT_LED_OFF (1 << 1)
#define EVENT_LED_BLINK (1 << 2)
/* 事件控制块 */
struct rt_event led_event;
static void led_entry(void *parameter)
{
rt_uint32_t e;
while(1)
{
/* 接收事件 */
if (RT_EOK == rt_event_recv(&led_event, /* 事件集对象句柄 */
(EVENT_LED_ON | EVENT_LED_OFF | EVENT_LED_BLINK), /* 接收事件 */
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, /* 接收选项 */
RT_WAITING_FOREVER, /* 超时时间 */
&e))
/* 判断标志位 */
if(e & EVENT_LED_ON)
{
led_on(LED0_PIN);
}
if(e & EVENT_LED_ON)
{
led_off(LED0_PIN);
}
if(e & EVENT_LED_ON)
{
led_blink(LED0_PIN);
led_blink(LED0_PIN);
}
}
}
int led_thread_init(void)
{
rt_thread_t led_thread;
rt_err_t result;
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED0_PIN, PIN_LOW);
/* 初始化事件对象 */
result = rt_event_init(&led_event, "air_event", RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init event failed.<br>");
return -1;
}
/* 创建线程 */
led_thread = rt_thread_create("led_th",
led_entry,
RT_NULL,
1024,
RT_THREAD_PRIORITY_MAX / 2 + 1,
20);
if (led_thread != RT_NULL)
{
rt_thread_startup(led_thread);
}
return RT_EOK;
}
传感器中需要数据读取标志和日志发送,led控制事件。
```if(key_temp == 1)
{
/ 读取设备数据 /
res = rt_device_read(dev, 0, &sensor_data, 1);
if (res != 1)
{
rt_kprintf("read data failed! result is %d<br>", res);
rt_device_close(dev);
rt_event_send(&led_event, EVENT_LED_ON);
return;
}
else
{
if (sensor_data.data.temp >= 0)
{
uint8_t temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp
uint8_t humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi
rt_kprintf("temp:%d, humi:%d<br>" ,temp, humi);
mylog("temp", temp);
mylog("humi", humi);
rt_event_send(&led_event, EVENT_LED_BLINK);
}
}
rt_thread_delay(800);
}
else
rt_event_send(&led_event, EVENT_LED_OFF);```