Arduino ESP6266 几行代码实现简易多任务框架。
上层是NONOS,框架基本原理还是切换,只不过不使用delay,可以做到任务之间的穿插执行,实时性提高,但并不能保证强实时性。
#include <ESP8266WiFi.h>
#include "sys_rw.h"
#include "rw_ledblink.h"
//#include "rw_1602.h"
//#include "rw_DS1302.h"
typedef unsigned long clock_t;
clock_t nowt ;
clock_t oldt;
time_t t;
void setup(){
Serial.begin(115200);
Serial.println("setup...");
nowt = millis();
rw_ledblink_setup(1);//led任务
//rw_1602_setup(2);//其他任务
//rw_DS1302_setup(3);//其他任务
oldt=nowt;
}
void loop(){
nowt = millis();
int dis=nowt-oldt;
rw_run(dis);
oldt=nowt;
}
//===================================================
sys_rw.h
定义个结构体,根据任务数量定义 结构体数组和指针数组的元素个数。如20个。
#ifndef _SYS_RW_H
#define _SYS_RW_H
#include <Arduino.h>
typedef void (*loopType)(int );
typedef struct rwdata
{
unsigned char setup_rewu1_ok ;
unsigned char en;
unsigned int time_rewu;
unsigned int time_add;
loopType fp;
} rwdata;
extern rwdata rwdata_array[20];//real data
extern rwdata* renwudataall[20];//data point
extern void rw_run(int dis);
#endif // _SYS_RW_H
//===================================================
sys_rw.cpp
loop中调用 rw_run()循环调用所有任务的xx_loop(dis)
#include "sys_rw.h"
rwdata rwdata_array[20];//real data
rwdata* renwudataall[20];//data point
void rw_run(int dis){
for(int i=0;i<20;i++){
//cout<<"id="<<i<<endl;
rwdata* data_rewuc=renwudataall[i];
if(data_rewuc!=NULL){
//cout<<(int)(*data_rewuc).en<<endl;
if(rwdata_array[i].en)(rwdata_array[i].fp)(dis);
}
}
}
//任务代码示例
//===================================================
rw_ledblink.h
每个任务要有xx_setup,xx_loop定义。
#ifndef _RW_LEDBLINK_H
#define _RW_LEDBLINK_H
#include "sys_rw.h"
extern int rw_ledblink_state;
extern int rw_ledblink_id;
extern rwdata* rw_ledblink_datp;
extern void rw_ledblink_setup(int rw_id);
extern void rw_ledblink_loop(int rw_time);
#endif // _RW_LEDBLINK_H
//===================================================
rw_ledblink.cpp
xx_setup完成任务的初始化
xx_loop实现不容时间节点响应不同动作,或者其他任务改变本任务的状态rw_ledblink_state来响应不同动作。
#include "sys_rw.h"
#include "rw_ledblink.h"
#define LED LED_BUILTIN
int rw_ledblink_state = 0;
int rw_ledblink_id = 0;
rwdata* rw_ledblink_datp;
void rw_ledblink_setup(int rw_id) {
rw_ledblink_id = rw_id;
rw_ledblink_datp = &(rwdata_array[rw_id]);
(*rw_ledblink_datp).en = 1;
renwudataall[rw_id] = rw_ledblink_datp;
(*rw_ledblink_datp).fp = rw_ledblink_loop;
//Set LED
pinMode(LED, OUTPUT);
}
int rw_ledblink_flash = 0;
void rw_ledblink_loop(int rw_time) {
int id = rw_ledblink_id;
//cout<<"loop rw_ledblink "<< rw_time<<endl;
rwdata_array[id].time_add += rw_time;
if (rwdata_array[id].time_add >= rwdata_array[id].time_rewu) {
//cout<<"loop rw_ledblink running"<<endl;
//delay(100);rwdata_array[id].time_rewu=100;
if (rw_ledblink_state == 0) {
//cout<<" rw_ledblink state 0 ,delay 1000"<<endl;
//Serial.println(" rw_ledblink state 0 ,delay 1000");
digitalWrite(LED, LOW);
rwdata_array[id].time_rewu = 1000;
} else if (rw_ledblink_state == 1) {
//cout<<" rw_ledblink state 1 ,delay 200"<<endl;
//Serial.println(" rw_ledblink state 1 ,delay 200");
rwdata_array[id].time_rewu = 200;
digitalWrite(LED, rw_ledblink_flash % 2);
rw_ledblink_flash++;
}
rwdata_array[id].time_add = 0;
}
}