天天看點

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);
}      

繼續閱讀