ESP8266--系统任务

系统任务

1.系统任务原理

以下资料来自《ESP8266 Non-OS SDK API参考》第2.2章节与第3.3章节。
Non-OS SDK 不像基于 RTOS 的应⽤程序⽀持任务调度。 Non-OS SDK 使⽤四种类型的函数:

  • 应用函数
  • 回调函数
  • 用户任务
  • 中断服务函数

1.1 应用函数

应用函数类似于嵌入式C编程中常用的C函数。这些函数必须由另一个函数调用。应用函数在定义时建议添加ICACHE_FLASH_ATTR宏,相应程序将存放在flash中,被调用时才会加载到cache运行。而如果添加了IRAM_ATTR宏的函数,则会在上电启动时加载到iRAM中。

1.2 回调函数

回调函数是指不直接从用户程序调用的函数。而是当某系统事件发送时,相应的回调函数由non-OS SDK内核调用执行。这使得开发者能够在不使用RTOS或者轮询事件的情况下响应实时事件。
要编写回调函数,用户首先需要使用相应的register_cb API注册回调函数。回调函数的示例代码包括定时器回调函数和网络事件回调函数。

1.3 中断服务函数

中断服务函数(ISR)是一种特殊类型的回调函数。发生硬件中断时会调用这些函数。当时能中断时,必须注册相应的中断处理函数。请注意,ISR必须添加IRAM_ATTR。

1.4 用户任务

用户任务可以分为三个优先级:0、1、2.任务优先级为2 > 1 > 0。即Non-OS SDK最多只支持3个用户任务,优先级分别为0、1、2。
用户任务一般用于函数不能被调用的情况下。要创建用户任务,请参阅本文档中的system_os_task()的API描述。例如espconn_disconnect() API不能直接在espconn的回调函数中调用,因此建议开发者在espconn回调中创建用户任务来执行espconn_disconnect()。

2. 硬件中断定时器相关API函数

系统接⼝位于 /ESP8266_NONOS_SDK/include/user_interface.h。
os_XXX 系列接⼝位于 /ESP8266_NONOS_SDK/include/osapi.h。

2.1 system_os_task ()函数

函数原型:bool system_os_task(os_task_t task,uint8 prio,os_event_t *queue,uint8 qlen)
函数功能:创建系统任务,最多支持创建3个任务,优先级分别为0/1/2
函数形参:
          os_task_t task:函数任务
          uint8 prio:任务优先级,可分为0/1/2;0为最低优先级。这表示最多只支持建立3个任务。
            可填形参: 
enum {
                    USER_TASK_PRIO_0 = 0,
                    USER_TASK_PRIO_1,
                    USER_TASK_PRIO_2,
                    USER_TASK_PRIO_MAX
};
          os_event_t *queue:消息队列指针
          uint8 qlen:消息队列深度
返回值:
        ture :成功
        false:失败
==============================================================
官方参考示例代码:
#define	SIG_RX	 			0
#define	TEST_QUEUE_LEN		4
os_event_t	*testQueue;

void test_task(os_event_t *e)
{
	switch (e->sig)
	{
		case	SIG_RX:
			os_printf(sig_rx %c / n, (char)e->par);
			break;
		default:
			break;
	}
}

void task_init(void)
{
	testQueue = (os_event_t*)os_malloc(sizeof(os_event_t)*TEST_QUEUE_LEN);
	system_os_task(test_task, USER_TASK_PRIO_0, testQueue, TEST_QUEUE_LEN);
}

2.2 system_os_post()函数

函数原型:bool system_os_post(uint8 prio,os_signal_t sig,os_param_t par)
函数功能:向任务发送消息
函数形参:
          uint8 prio:任务优先级,与建立时的任务优先级对应
          os_signal_t sig:消息类型
          os_param_t par:消息参数
返回值:
          ture :成功
          false:失败

3. 参考代码

3.1 系统任务调用顺序

① 创建任务指针
② 分配任务指针空间
③ 创建任务函数
④ 创建任务
⑤ 给系统安排任务
⑥ 编写任务函数(根据消息类型/消息参数实现相应功能)

3.2 参考驱动源码

//user_main.c
#include "ets_sys.h"
#include "osapi.h"

#include "user_interface.h"
#include "driver/uart.h"
#include "gpio.h"
#include "eagle_soc.h"
#include "driver/delay.h"
#include "driver/led.h"
#include "driver/key.h"
#include "driver/HwTimer.h"
#include "osapi.h"
#include "mem.h"				// 内存申请等函数

/*
*	① 创建任务指针
*	② 分配任务指针空间
*	③ 创建任务
*	④ 创建任务函数
*	⑤ 给系统安排任务
*	⑥ 编写任务函数(根据消息类型/消息参数实现相应功能)
* */
#define	TEST_QUEUE_LEN		4	//消息队列深度
os_event_t	*testQueue;			//① 创建任务指针

								//④ 创建任务  形参必须为s_event_t *类型
void test_task(os_event_t * Task_message)
{
	//⑤ 给系统安排任务
	os_printf("消息类型=%d,消息参数=%c\r\n", Task_message->sig, Task_message->par);
}

void ICACHE_FLASH_ATTR user_init(void)
{
	int i;
	char data = 0;
	char ch = 'a';
	uart_init(115200, 115200);//设置串口波特率
	DelayMs(1000);			// 延时1秒
	//	LedInitConfig();//LED灯初始化函数
	//	KeyInitConfig();//按键初始化函数
	//	KeyExtiInitConfig();//配置按键外部中断
	//	TimerInitConfig(500,1);
	//	hw_timer_set_func();
	//	HwTimerInitConfig();
	os_printf("=============================================\r\n");
	os_printf("\t SDK version:\t%s", system_get_sdk_version());
	os_printf("\r\n嵌入式陈工个人编辑资料\r\n未经本人同意请勿私自传播\r\n");
	os_printf("\r\n系统任务调度代码\r\n");
	os_printf("\r\n带看门狗\r\n");
	os_printf("=============================================\r\n");

	//② 分配任务指针空间
	testQueue = (os_event_t*)os_malloc(sizeof(os_event_t)*TEST_QUEUE_LEN);
	//③ 创建任务函数
	system_os_task(test_task, USER_TASK_PRIO_0, testQueue, TEST_QUEUE_LEN);
	for (i = 0; i < 5; i++)
	{
		system_soft_wdt_feed();//喂软件看门狗,防止程序跑偏

		os_DelayMs(1000);			// 延时1秒  系统延时函数
		os_printf("安排任务:Task = %d\r\n", i);

		// 调用任务(参数1=任务等级 / 参数2=消息类型 / 参数3=消息参数)
		// 注意:参数3必须为无符号整数,否则需要强制类型转换
		//---------------------------------------------------------------
		system_os_post(USER_TASK_PRIO_0, data ++, ch ++);
	}
	os_printf("任务创建完成\r\n");
}

源代码参考:https://github.com/ChenJiliang00/ESP8266

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值