> 有一次在做开发的过程中,发现8266的三个任务已经尽数用完了o(╯□╰)o。没办法,串口驱动也要用一个呢。后来干脆想,把HTTP的任务加在队列里,定时扫描队列出对执行就好了,然后就开始构想代码。于是就是下面两片代码。
app_net_work.c为上层提供app_net_work_init()、http_set_work(http_work_t job),这两个函数,顾名思义就是初始化队列和入队。
然后app_http.c是再下一层,作用是描述具体任务,主要是将工作号和任务对应起来,这里用到了函数指针数组,这样可以方便自由地增删新的函数,不过注意在接收函数末了加入判断是否将GlobalHttp.info.isworking置0,以使该工作是否从队列中删除。
#ifndef APP_INCLUDE_APP_NET_WORK_H_
#define APP_INCLUDE_APP_NET_WORK_H_
#include "jobs_of_net_work.h"
#define HTTP_TASK_SIZE 8
ETSTimer net_work_timer;
typedef struct{
http_work_t task_sequence[HTTP_TASK_SIZE];
struct {
uint8_t active:4;
uint8_t current:3;
uint8_t isworking:1;
}info;
}http_task_t;
http_task_t GlobalHttp;
int ICACHE_FLASH_ATTR app_net_work_init();
int ICACHE_FLASH_ATTR http_set_work(http_work_t job);
#endif /* APP_INCLUDE_APP_NET_WORK_H_ */
#include "includes.h"
#include "client.h"
#include "app_net_work.h"
#include "app_http.h"
//把工作加入队列
int ICACHE_FLASH_ATTR http_set_work(http_work_t job){
if ((GlobalHttp.info.current + 1) % HTTP_TASK_SIZE == GlobalHttp.info.active)
{
os_printf("\r\nIn queue error,may be full.\r\n")
return FALSE
} //队满,无法添加
GlobalHttp.task_sequence[GlobalHttp.info.current] = job
GlobalHttp.info.current = (GlobalHttp.info.current + 1) % HTTP_TASK_SIZE
os_printf("\r\nIN queue:%d\r\n",job)
return TRUE
}
//定时扫描任务
int ICACHE_FLASH_ATTR ScanJobfn(){
http_work_t HttpJob
#ifdef HTTP_QUEUE
os_printf("\r\nScan job.\r\n")
#endif
if (GlobalHttp.info.active == GlobalHttp.info.current){
GlobalHttp.info.isworking = 1
#ifdef HTTP_QUEUE
os_printf("\r\nempty\r\n")
#endif
return FALSE
}
if(GlobalHttp.info.isworking == 0){//如果上一个任务完成
GlobalHttp.info.active = (GlobalHttp.info.active + 1) % HTTP_TASK_SIZE
#ifdef HTTP_QUEUE
os_printf(" --%d-",GlobalHttp.info.active)
#endif
if (GlobalHttp.info.active == GlobalHttp.info.current){
GlobalHttp.info.isworking = 1
#ifdef HTTP_QUEUE
os_printf("\r\n. empty\r\n")
#endif
return FALSE
}
}
HttpJob = GlobalHttp.task_sequence[GlobalHttp.info.active]
#ifdef HTTP_QUEUE
os_printf("%d %d\n",HttpJob,GlobalHttp.task_sequence[GlobalHttp.info.active+1])
#endif
if(true == startHttpWork(HttpJob))//如果执行不出错
os_timer_disarm(&net_work_timer)
GlobalHttp.info.isworking = 1
return TRUE
}
int ICACHE_FLASH_ATTR app_net_work_init(){
initHttpWork()
GlobalHttp.info.isworking = 1
GlobalHttp.info.active = GlobalHttp.info.current = 0
os_timer_setfn(&net_work_timer,ScanJobfn,NULL)
os_timer_arm (&net_work_timer,3000,1)
return TRUE
}
#ifndef APP_INCLUDE_APP_HTTP_H_
#define APP_INCLUDE_APP_HTTP_H_
#define POST "POST %s HTTP/1.1\r\nHOST: %s\r\nUser-Agent: wifi/1.0\r\nContent-Type:application/json;charset=UTF-8\r\nContent-Length: %d\r\n\r\n\r\n%s"
#include "hh_json.h"
#include "includes.h"
#include "app_net_work.h"
#include "client.h"
void ICACHE_FLASH_ATTR initHttpWork();
int ICACHE_FLASH_ATTR startHttpWork(http_work_t job_flag);
#endif /* APP_INCLUDE_APP_HTTP_H_ */
#include "app_http.h"
#include "hh_json.h"
#include "user_main.h"
#include "string.h"
#include "driver/mqtt.h"
#include "user_mqtt.h"
extern http_task_t GlobalHttp;
ETSTimer wait_wifi_conn;
void ICACHE_FLASH_ATTR NULL_fn(){}
/*****************************************************/
/********************自定义接收函数**********************/
void ICACHE_FLASH_ATTR regist_recv_cb(void *arg,char *pdata,unsigned short len){
os_printf("\nregist_recv_cb:%s\n",pdata);
if(success) GlobalHttp.info.isworking = 0;
}
void ICACHE_FLASH_ATTR login_recv_cb(void *arg,char *pdata,unsigned short len){
os_printf("\nlogin_recv_cb\n");
if(success) GlobalHttp.info.isworking = 0;
}
void ICACHE_FLASH_ATTR module_ota_recv_cb(void *arg,char *pdata,unsigned short len){
if(success) GlobalHttp.info.isworking = 0;
}
void ICACHE_FLASH_ATTR module_ota_download_cb(void *arg,char *pdata,unsigned short len){
if(success) GlobalHttp.info.isworking = 0;
}
void* user_tcp_recv_cb[HTTP_TASK_SIZE]={NULL_fn,regist_recv_cb,login_recv_cb,NULL_fn,module_ota_recv_cb,module_ota_download_cb};
/********************自定义接收函数***********************/
/*****************************************************/
/**********************自定义组包函数**********************/
/*****************************************************/
void ICACHE_FLASH_ATTR regist_recv_pack(char* buf){
}
void ICACHE_FLASH_ATTR login_recv_pack(char* buf){
}
void ICACHE_FLASH_ATTR module_ota_pack(char* buf){
}
void ICACHE_FLASH_ATTR module_ota_download_pack(char* buf){
}
void (*user_make_package[HTTP_TASK_SIZE])(char*)={NULL_fn,regist_recv_pack,login_recv_pack,NULL_fn,module_ota_pack,module_ota_download_pack};
/**********************自定义组包函数*************************/
/*********************************************************/
int ICACHE_FLASH_ATTR startHttpWork(http_work_t job_flag)
{
os_printf("\r\nHTTP JOB: %d\r\n",job_flag);
(user_make_package[job_flag])(sent_buffer);
os_printf("\r\n%s\r\n",sent_buffer);
if(0 != espconn_connect(&user_tcp_conn[job_flag])) {
os_printf("\nFAIL TO start CONNECT\n");
return false;
}
espconn_regist_recvcb(&user_tcp_conn[job_flag],user_tcp_recv_cb[job_flag]);
return true;
}
void ICACHE_FLASH_ATTR DSNfound(const char *name, ip_addr_t *ipaddr, void *arg){
struct ip_info ipinfo;
os_printf("{\r\n-------------------\r\n}");
wifi_get_ip_info(STATION_IF,&ipinfo);
os_printf("{\r\n-------------------\r\n}");
char textip[4]={192,168,1,209};
my_tcp_station_init((struct ip_addr*)textip,&ipinfo.ip,10025);
os_printf("{\r\n-------------------\r\n}");
os_timer_disarm(&wait_wifi_conn);
}
void ICACHE_FLASH_ATTR startinit(){
ip_addr_t dns_addr;
struct espconn user_con;
if(wifi_station_get_connect_status() != STATION_GOT_IP) return;
if(ESPCONN_OK == espconn_gethostbyname(&user_con,MY_COMPANY_DNS, &dns_addr,DSNfound))
os_timer_disarm(&wait_wifi_conn);
}
void ICACHE_FLASH_ATTR initHttpWork(){
os_timer_setfn(&wait_wifi_conn,startinit,NULL);
os_timer_arm(&wait_wifi_conn,2000,1);
os_printf("-");
}