天天看点

ESP8266--SDK开发(系统任务)

文章目录

  • ​​一、系统任务​​
  • ​​二、消息队列的使用场景​​
  • ​​2.1、场景一​​
  • ​​2.2、场景二​​
  • ​​2.3、场景三​​

一、系统任务

ESP8266内部可以运行消息队列任务.总共可以创建3个消息队列任务,系统有空余时间的时候会取出消息队列里面的消息,如果有消息则会调用其回调函数;

下列代码是常用的固定形式:

#define os_event_t_buff_len 255 //消息队列长度;最大为255
os_event_t os_event_t_buff[os_event_t_buff_len];    //存储消息的数组
#define TaskPrio 2  //任务等级(0,1,2),2是最高等级

os_timer_t os_timer_one;    //定义软件定时器结构体变量

//定时器回调函数
void os_timer_one_function(void *parg)
{
    //把消息插入队列(sig=0;par=0)
    system_os_post(TaskPrio, 0, 0);
}

//消息队列回调函数
void os_task_t_callback(os_event_t *events)
{
    if(events->sig == 0 && events->par == 0) {
        os_printf("os_task_t_callback\r\n");
    }
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    os_printf("=== System start ===\n");
    os_printf("SDK version:%s\n", system_get_sdk_version());

    system_os_task(os_task_t_callback, TaskPrio, os_event_t_buff, os_event_t_buff_len);
    //配置定时器
    os_timer_setfn(&os_timer_one,os_timer_one_function,NULL);//os_timer_one:定时器结构体变量    os_timer_one_function:回调函数    yang:传给回调函数的参数
    //使能定时器
    os_timer_arm(&os_timer_one,1000,1);//os_timer_one:定时器变量        1:1s进一次    1:循环

}      
ESP8266--SDK开发(系统任务)

二、消息队列的使用场景

2.1、场景一

使用​

​system_os_post(TaskPrio, sig, par);​

​可以往系统消息队列中添加消息,可以根据sig和par的值来判定我们需要执行的操作

例如:设置sig=1;par=1的时候关闭定时器

//定时器回调函数
int value = 0;
void os_timer_one_function(void *parg)
{
  //把消息插入队列(sig=0;par=0)
  system_os_post(TaskPrio, 0, 0);

  value++;
  if(value>=10) {
    value = 0;
    //把消息插入队列(sig=1;par=1)
    system_os_post(TaskPrio, 1, 1);
  }
}

//消息队列回调函数
void os_task_t_callback(os_event_t *events)
{
  if(events->sig == 0 && events->par == 0) {
    os_printf("os_task_t_callback\r\n");
  }else if(events->sig == 1 && events->par == 1) {
    os_timer_disarm(&os_timer_one); //关闭定时器
  }
}      

2.2、场景二

在网络通信的时候,官方也是建议使用系统消息队列的形式关闭网络连接

ESP8266--SDK开发(系统任务)

2.3、场景三

使用任务代替定时器:定时器只能定时在5ms和100us的级别;而且经过测试,频繁的定时器会影响到网络信号的传输

如果需要轮训,可以使用下面的方式:

//消息队列回调函数
void os_task_t_callback(os_event_t *events)
{
    if(events->sig == 0 && events->par == 0) {
        system_os_post(TaskPrio, 0, 0);
    }
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    os_printf("=== System start ===\n");
    os_printf("SDK version:%s\n", system_get_sdk_version());

    system_os_task(os_task_t_callback, TaskPrio, os_event_t_buff, os_event_t_buff_len);
    system_os_post(TaskPrio, 0, 0);
}      
//消息队列回调函数
int value=0;
void os_task_t_callback(os_event_t *events)
{
    if(events->sig == 0 && events->par == 0) {
        system_os_post(TaskPrio, 0, 0);
    }

    value++;
    if(value > 300000) { //大约1s
        value=0;
        os_printf("os_task_t_callback\r\n");
    }
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    os_printf("=== System start ===\n");
    os_printf("SDK version:%s\n", system_get_sdk_version());

    system_os_task(os_task_t_callback, TaskPrio, os_event_t_buff, os_event_t_buff_len);
    system_os_post(TaskPrio, 0, 0);
}      
//消息队列回调函数
int value = 0;
bool isRun = true;
void os_task_t_callback(os_event_t *events)
{
    if(events->sig == 0 && events->par == 0) {
        if(isRun) {
            system_os_post(TaskPrio, 0, 0);
        }
    }

    value++;
    if(value > 300000) { //大约1s
        value=0;
        isRun = false;  //不再把消息插入队列即可结束轮训
    }
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    os_printf("=== System start ===\n");
    os_printf("SDK version:%s\n", system_get_sdk_version());

    system_os_task(os_task_t_callback, TaskPrio, os_event_t_buff, os_event_t_buff_len);
    system_os_post(TaskPrio, 0, 0);
}      

继续阅读