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


    一、系统任务

    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:循环
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述


    二、消息队列的使用场景

    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);	//关闭定时器
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2.2、场景二

    在网络通信的时候,官方也是建议使用系统消息队列的形式关闭网络连接
    在这里插入图片描述


    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    轮训一次任务的时间基本上是固定的,可以使用变量累加来执行定时操作

    //消息队列回调函数
    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    停止轮训

    //消息队列回调函数
    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    Conmi的正确答案——Maven项目的pom.xml配置阿里云
    基层医院信息管理系统源码 his系统全套成品源码带电子病历4级
    Flutter TapGestureRecognizer 如何工作
    Spring Cloud 中自定义外部化扩展机制原理及实战
    [WPF]用HtmlTextBlock实现消息对话框的内容高亮和跳转
    小白系统初始化配置资源失败怎么办
    `VUE`的介绍
    为什么 Spring的构造器注入不需要 @Autowired 注解
    LeetCode - 解题笔记 -201- Bitwise AND of Numbers Range
    快鲸scrm管理系统:六大功能实现企业营收更大化
  • 原文地址:https://blog.csdn.net/Mr_robot_strange/article/details/127673170