内容
函数和任务的区别
- 调用函数:立即进入该函数,执行函数语句,实现函数功能
- 安排任务:给系统安排任务,当系统空闲时,次啊会执行任务
system_os_post()API给系统安排任务时
- 参数2(消息类型)传递给 任务函数形参->sig
例程中:Task_message->sig - 参数3(消息参数)传递给 任务函数形参->par
例程中:Task_message->par
要点
- 用户最多设置3个任务,优先级:2>1>0
- 调用任务时需给出任务参数(参数1=任务等级/参数2=消息类型/参数3=消息参数)
- 不管系统是否还有未完成的任务,用户都可以继续安排任务(任务可叠加),当系统空闲时会依次执行任务函数
- 任务虽然可以叠加,但是叠加次数不能超过设定值(消息队列深度)。超过设定值(消息队列深度)的任务将被丢弃
步骤
- 定义任务指针【os_event_t * Pointer_Task_1 ;】
- 为任务分配内存【Pointer_Task_1=(os_event_t*)os_malloc((sizeof(os_event_t))*MESSAGE_QUEUE_LEN);】
- 创建任务函数【void Func_Task_1(os_event_t * Task_message){}】
- 创建任务【system_os_task(Func_Task_1, USER_TASK_PRIO_0, Pointer_Task_1, MESSAGE_QUEUE_LEN);】
- 给系统安排任务【system_os_post(USER_TASK_PRIO_0, Message_Type++, Message_Para++);】
效果
代码
头文件
#include "user_config.h" // 用户配置
#include "driver/uart.h" // 串口
//#include "at_custom.h"
#include "c_types.h" // 变量类型
#include "eagle_soc.h" // GPIO函数、宏定义
#include "ip_addr.h" // 被"espconn.h"使用
#include "espconn.h" // TCP/UDP接口
//#include "espnow.h"
#include "ets_sys.h" // 回调函数
//#include "gpio.h"
#include "mem.h" // 内存申请等函数
#include "os_type.h" // os_XXX
#include "osapi.h" // os_XXX、软件定时器
//#include "ping.h"
//#include "pwm.h"
//#include "queue.h"
//#include "smartconfig.h"
//#include "sntp.h"
//#include "spi_flash.h"
//#include "upgrade.h"
#include "user_interface.h" // 系统接口、system_param_xxx接口、WIFI、RateContro
宏定义
#define ProjectName "Task" // 工程名宏定义
#define MESSAGE_QUEUE_LEN 2 // 消息队列深度(对于同一个任务,系统最多接受的叠加任务数)
全局变量
os_event_t * Pointer_Task_1 ; // 定义任务1(串口打印任务) // 第①步:定义任务指针
任务函数Func_Task_1
void Func_Task_1(os_event_t* Task_message)
{
os_printf("消息类型=%d, 消息参数=%c\r\n", Task_message->sig, Task_message->par);
}
user_init
void ICACHE_FLASH_ATTR user_init(void)
{
u8 C_Task = 0;
u8 Message_Type = 1; //消息类型
u8 Message_Para = 'A'; //消息参数
uart_init(115200,115200); //初始化串口波特率
os_delay_us(10000); //等待串口稳定
os_printf("\r\n=================================================\r\n");
os_printf("\t Project:\t%s\r\n", ProjectName);
os_printf("\t SDK version:\t%s", system_get_sdk_version());
os_printf("\r\n=================================================\r\n");
//给任务1分配空间(任务1空间=1个队列1空间*队列数
Pointer_Task_1 = (os_event_t*)os_malloc((sizeof(os_event_t))*MESSAGE_QUEUE_LEN);
//创建任务
system_os_task(Func_Task_1, USER_TASK_PRIO_0, Pointer_Task_1, MESSAGE_QUEUE_LEN);
//调用任务
for(C_Task=1;C_Task<=4;C_Task++)
{
system_soft_wdt_feed(); //喂狗
delay_ms(1000);
os_printf("\r\n安排任务:Task == %d\r\n", C_Task);
//給系统安排任务
system_os_post(USER_TASK_PRIO_0, Message_Type++, Message_Para++);
}
os_printf("\r\n------------------ user_init OVER ----------------\r\n\r\n");
}
全部代码
#include "user_config.h" // 用户配置
#include "driver/uart.h" // 串口
//#include "at_custom.h"
#include "c_types.h" // 变量类型
#include "eagle_soc.h" // GPIO函数、宏定义
#include "ip_addr.h" // 被"espconn.h"使用
#include "espconn.h" // TCP/UDP接口
//#include "espnow.h"
#include "ets_sys.h" // 回调函数
//#include "gpio.h"
#include "mem.h" // 内存申请等函数
#include "os_type.h" // os_XXX
#include "osapi.h" // os_XXX、软件定时器
//#include "ping.h"
//#include "pwm.h"
//#include "queue.h"
//#include "smartconfig.h"
//#include "sntp.h"
//#include "spi_flash.h"
//#include "upgrade.h"
#include "user_interface.h" // 系统接口、system_param_xxx接口、WIFI、RateContro
//============================================================
// 宏定义
//==================================================================================
#define ProjectName "Task" // 工程名宏定义
#define MESSAGE_QUEUE_LEN 2 // 消息队列深度(对于同一个任务,系统最多接受的叠加任务数)
//==================================================================================
// 全局变量
//=========================================================
os_event_t * Pointer_Task_1 ; // 定义任务1(串口打印任务) // 第①步:定义任务指针
//=========================================================
void ICACHE_FLASH_ATTR delay_ms(u32 C_time)
{ for(;C_time>0;C_time--)
os_delay_us(1000);
}
void Func_Task_1(os_event_t* Task_message)
{
os_printf("消息类型=%d, 消息参数=%c\r\n", Task_message->sig, Task_message->par);
}
void ICACHE_FLASH_ATTR
user_init(void)
{
u8 C_Task = 0;
u8 Message_Type = 1; //消息类型
u8 Message_Para = 'A'; //消息参数
uart_init(115200,115200); //初始化串口波特率
os_delay_us(10000); //等待串口稳定
os_printf("\r\n=================================================\r\n");
os_printf("\t Project:\t%s\r\n", ProjectName);
os_printf("\t SDK version:\t%s", system_get_sdk_version());
os_printf("\r\n=================================================\r\n");
//给任务1分配空间(任务1空间=1个队列1空间*队列数
Pointer_Task_1 = (os_event_t*)os_malloc((sizeof(os_event_t))*MESSAGE_QUEUE_LEN);
//创建任务
system_os_task(Func_Task_1, USER_TASK_PRIO_0, Pointer_Task_1, MESSAGE_QUEUE_LEN);
//调用任务
for(C_Task=1;C_Task<=4;C_Task++)
{
system_soft_wdt_feed(); //喂狗
delay_ms(1000);
os_printf("\r\n安排任务:Task == %d\r\n", C_Task);
//給系统安排任务
system_os_post(USER_TASK_PRIO_0, Message_Type++, Message_Para++);
}
os_printf("\r\n------------------ user_init OVER ----------------\r\n\r\n");
}
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR
user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR
user_rf_pre_init(void)
{}
总结框架
需要修改的参数
- 队列深度【MESSAGE_QUEUE_LEN】
- 消息类型
- 消息参数
- 任务执行函数
- 任务等级
#define MESSAGE_QUEUE_LEN 2 // 消息队列深度(对于同一个任务,系统最多接受的叠加任务数)
void Func_Task_1(os_event_t* Task_message)
{
....... //任务函数,完成的功能
}
void ICACHE_FLASH_ATTR user_init(void)
{
u8 Message_Type = 1; //消息类型
u8 Message_Para = 'A'; //消息参数
//给任务1分配空间(任务1空间=1个队列1空间*队列数
Pointer_Task_1 = (os_event_t*)os_malloc((sizeof(os_event_t))*MESSAGE_QUEUE_LEN);
// 创建任务(参数1=任务执行函数 / 参数2=任务等级 / 参数3=任务空间指针 / 参数4=消息队列深度)
system_os_task(Func_Task_1, USER_TASK_PRIO_0, Pointer_Task_1, MESSAGE_QUEUE_LEN);
//调用任务
//給系统安排任务
system_os_post(USER_TASK_PRIO_0, Message_Type++, Message_Para++);
}