Files
checker_slave/source/task/tran_for_broadcast.c
ranchuan d22fdc1ccb ew写延时验证成功,ej写流水号验证成功
解决上位机协议crc错误依然执行命令的bug
    注意:小板方案中芯片类型与主板不同时,使用槽任务可能造成各种异常问题(死机,死循环,不返回数据等)
2023-12-26 18:08:59 +08:00

257 lines
5.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "tran_for_broadcast.h"
#include "debug.h"
#include "mymisc.h"
#include "mystdlib.h"
#include "board.h"
#include "dev_flash.h"
#include "prot_uc.h"
#include "coder_lib.h"
#include "JQ_PSDGenerate.h"
#include "mystring.h"
#include "coder_judge.h"
#include "JQ_UIDGenerate.h"
#include "transmit.h"
#include "elec_det.h"
#include "crc.h"
#include "dev_backup.h"
#include "elec_task_slot.h"
/*
执行任务命令格式
[0...1]=总字节数,[2]=当前包数(0开始),[3]=当前包字节数
[4...n]=数据
数据域格式
[0]=检测模式0,只检测,返回原始检测结果;模式1,检测并添加任务插槽,只返回异常代码和任务插槽数据;
模式2,检测并执行任务插槽,返回原始检测数据和任务插槽数据;
模式3,只执行任务插槽,返回异常代码和插槽数据
[1...n]小板数据
小板数据格式
[0]=小板地址(0x1f时为通用数据,每个小板都可以使用)[1]=数据长度,[2...n]=数据
单个任务数据格式
[0]=插槽序号,[1]=任务id[2]=参数个数(u16)
[3]=返回值个数(u16)[4]=异常代码,[5]=任务序号
[6...n]=参数
返回数据域格式
[0]=任务序号,[1]=返回数据长度(u16)
[2...n]=参数
*/
typedef struct{
ucport_def u;
rt_timer_t timer;
}slave_def;
typedef struct{
array_def *data;
}self_def;
static self_def g_self;
static slave_def *slave_creat(void)
{
slave_def *u=calloc(1,sizeof(slave_def));
return u;
}
static void slave_del(ucport_def *u)
{
slave_def *s=(slave_def *)u;
CHECK_DO(s->timer,rt_timer_delete);
// CHECK_DO(s->data,arr_delete);
free(u);
}
// 找到自己的数据
static void slave_get_self(self_def *s)
{
int len=arr_length(s->data);
int off=0;
int addr,slave_len;
array_def *expat=arr_creat();
uint8_t *d;
while(off<len){
addr=arr_get(s->data,off);
slave_len=arr_get(s->data,off+1);
if((addr==elec_local_addr())||(addr==0x1f)){
d=arr_data(s->data)+off+2;
arr_appends(expat,d,slave_len);
break;
}
off+=slave_len+2;
}
arr_delete(s->data);
s->data=expat;
}
// 添加任务
static void slave_adds(self_def *s)
{
task_def *t=calloc(1,sizeof(task_def));
void *slot=0;
int off=0;
int len=arr_length(s->data);
task_slot_delete();
slot=task_slot_init();
while(off<len){
t->slot_index=arr_get(s->data,off);
t->task_id=arr_get(s->data,off+1);
t->par_count=arr_get(s->data,off+2);
t->ret_count=arr_get(s->data,off+3);
t->errcode=arr_get(s->data,off+4);
t->exe_flag=0;
t->task_index=arr_get(s->data,off+5);
memcpy(t->params,arr_data(s->data)+off+6,t->par_count*2);
task_slot_add_item(slot,t);
DBG_LOG("slot_index=%d,task_id=%d,par_count=%d,ret_count=%d",
t->slot_index,t->task_id,t->par_count,t->ret_count);
off+=6+t->par_count*2;
}
free(t);
}
// 生成返回数据
// 如果ret不为0则存在未执行的槽任务
static array_def *slave_creat_retdata(slave_def *s,array_def *r,int *ret)
{
void *slot=task_slot_init();
task_def *t=0;
int err=0;
while(t=task_slot_next_item(slot),t!=0)
{
if(t->exe_flag==0){
err|=1;
}
if(r){
arr_append(r,t->task_index);
arr_append(r,t->ret_count);
arr_appends(r,t->rets,t->ret_count*2);
}
}
if(ret) *ret=err;
return r;
}
// 重新设置异常代码,异常代码9未执行的槽任务
#define SET_ERRCODE(arr){\
if(slot_exe_flag){\
if(arr_get(arr,0)==0){\
arr_reset(arr,9,0);\
}\
}}
// 执行任务
static int run_task_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str)
{
slave_def *s=(slave_def *)u;
self_def *g=&g_self;
int pack_curr=0,pack_all=0,pack_size=0;
array_def *r=0;
array_def *check=0;
uint8_t *d;
uint8_t ret_mode=0;
int slot_exe_flag=0;
pack_all=arr_get(data,0)|(arr_get(data,1)<<8);
pack_curr=arr_get(data,2);
pack_size=arr_get(data,3);
if(pack_curr==0){
// 第一个数据包重置接收
CHECK_DO(g->data,arr_delete);
g->data=arr_creat();
}
if(arr_length(g->data)<pack_all){
d=arr_data(data)+4;
arr_appends(g->data,d,arr_length(data)-4);
r=arr_creat();
arr_append(r,0);
emit tran_reply_signal(u->p,arr_temp(r));
}
if(arr_length(g->data)==pack_all){
// 延时以保证正常回复到上位机
rt_thread_mdelay(50);
// 接收完成后执行命令
ret_mode=arr_get(g->data,0);
arr_remove(g->data,0,1);
slave_get_self(g);
slave_adds(g);
if(ret_mode!=3){
check=elec_check_with_scheme(0);
}else{
check=elec_check_slot();
}
if(ret_mode==0){
// 模式0只返回检测数据
slave_creat_retdata(s,0,&slot_exe_flag);
SET_ERRCODE(check);
emit tran_reply_signal(u->p,arr_temp(check));
}else if((ret_mode==1)||(ret_mode==3)){
// 模式1返回异常代码和任务插槽数据
r=arr_creat();
arr_append(r,arr_get(check,0));
slave_creat_retdata(s,r,&slot_exe_flag);
SET_ERRCODE(r);
emit tran_reply_signal(u->p,arr_temp(r));
}else if(ret_mode==2){
// 模式2返回检测数据和任务插槽数据
slave_creat_retdata(s,check,&slot_exe_flag);
SET_ERRCODE(check);
emit tran_reply_signal(u->p,arr_temp(check));
}
}
return 0;
}
static ucport_def *run_task(tran_def *t, uint8_t cmd,array_def *data)
{
int ret=0;
slave_def *u=slave_creat();
u->u.p=t;
u->u.del=slave_del;
u->u.dolater=run_task_dolater;
u->u.dolater(&u->u,cmd,data,"ok");
return (ucport_def *)u;
}
transmit_export(ym_slave,0x20,run_task)
// 0x21 是上位机协议的命令字
transmit_export(ym_checker,0x21,run_task)