仓库迁移

This commit is contained in:
andy
2023-06-10 11:52:00 +08:00
parent e4616bfae5
commit 077c27f2bb
499 changed files with 199745 additions and 92 deletions

View File

@@ -0,0 +1,470 @@
#include "stdio.h"
#include "rtthread.h"
#include "board.h"
#include "mystdlib.h"
#include "list.h"
#include "mystring.h"
#include "signal.h"
#include "prot_mcu.h"
#include "buff.h"
#include "bytearray.h"
#include "debug.h"
#include "crc.h"
typedef struct{
uint16_t no;
list_def *cmds;//int
uint8_t addr;
uint8_t cmd;
array_def *data;
int retry;
int timeout_ms;
}protm_slave;
static int protm_slave_sub(void *a,void *b)
{
protm_slave *a_=a;
protm_slave *b_=b;
return a_->addr-b_->addr;
}
static int protm_slave_del(void *t)
{
protm_slave *p=t;
CHECK_DO(p->cmds,list_delete);
return 0;
}
static protm_slave *protm_slave_creat(void)
{
protm_slave *p=calloc(1,sizeof(protm_slave));
param_check(p);
return p;
}
array_def *protm_decode(protm_def *p,array_def *data);
protm_slave *protm_get_slave(protm_def *p,uint8_t addr);
typedef struct{
array_def *data;
int addr;
}send_data_def;
// <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
#define EVENT_RECV 0x1
#define EVENT_SEND 0x2
#define EVENT_TIMEOUT 0x4
struct _protm_def{
uart_def *uart;
array_def *buff;
int num_to_recv;
rt_event_t event;
rt_timer_t timer;
int run;
char *str_err;
list_def *slaves;//protm_slave
list_def *slaves_addr;//int
list_def *send_data;//send_data_def
int in_send;//<2F>ڷ<EFBFBD><DAB7><EFBFBD>״̬ʱΪ1
uint8_t recv_cmd;
uint8_t recv_src;
};
static void recv_irq(void *t,uint8_t d)
{
protm_def *p=t;
arr_append(p->buff,d);
switch(arr_length(p->buff)){
case 2:
if(arr_get(p->buff,0)=='Y'&&arr_get(p->buff,1)=='e')
{
p->num_to_recv=4;
}else{
arr_remove(p->buff,0,1);
p->num_to_recv=0;
}
break;
case 4:
{
int len=arr_get(p->buff,2)|(arr_get(p->buff,3)<<8);
p->num_to_recv=len;
}
break;
default:
break;
}
// <20><>ʱһ֡<D2BB><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(p->num_to_recv>0&&p->num_to_recv==arr_length(p->buff))
{
rt_event_send(p->event,EVENT_RECV);
}
}
/*
* <20><><EFBFBD>ӻ<EFBFBD>ͨ<EFBFBD>ŵĴ<C5B5><C4B4><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4>еģ<D0B5>һ<EFBFBD><D2BB>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD>ʼ<EFBFBD><CABC>һ<EFBFBD><D2BB>ͨ<EFBFBD><CDA8>
* Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2>еģ<D0B5>Ӧ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B1BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void protm_send_next(void *t);
int protm_send(protm_def *p,send_data_def *d);
static void protm_send_timeout(void *t);
static void protm_run(void *t)
{
protm_def *p=t;
array_def *data;
array_def *decode_data;
uint32_t ev;
while(p->run)
{
rt_event_recv(p->event,0xffffffff,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&ev);
if(ev&EVENT_RECV)
{
// DBG_LOG("protmcu:recv event.");
data=arr_duplicate(p->buff);
arr_clear(p->buff);
//DBG_LOG("recv:%s",str_temp(arr_string(data)));
decode_data=protm_decode(p,data);
arr_delete(data);
emit protm_recv_signal(p,p->recv_src,p->recv_cmd,arr_temp(decode_data),str_temp(str_duplicate(p->str_err)));
irq_disable();
p->num_to_recv=0;
irq_enable();
protm_send_next(p);
}
else if(ev&EVENT_TIMEOUT)
{
protm_send_timeout(p);
}
if (ev&EVENT_SEND)
{
// DBG_LOG("protmcu:send event.");
if(list_length(p->send_data)>0)
{
send_data_def *a=(send_data_def *)list_get(p->send_data,0);
protm_send(p,a);
}
}
ev=0;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
static void protm_send_next(void *t)
{
protm_def *p=t;
rt_timer_stop(p->timer);
list_remove(p->send_data,0);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
if (list_length(p->send_data)>0)
{
// DBG_LOG("protmcu:EVENT_SEND.");
rt_event_send(p->event,EVENT_SEND);
}
else{
irq_disable();
p->in_send=0;
irq_enable();
}
}
static void protm_send_timeout_cb(void *t)
{
protm_def *p=t;
rt_event_send(p->event,EVENT_TIMEOUT);
}
// <20><><EFBFBD>ճ<EFBFBD>ʱ
static void protm_send_timeout(void *t)
{
protm_def *p=t;
send_data_def *s=list_get(p->send_data,0);
protm_slave *sl=protm_get_slave(p,s->addr);
if(sl->retry>0){
sl->retry--;
DBG_WARN("slave:%d retry left ",s->addr,sl->retry);
list_shift(p->send_data);
}else{
DBG_WARN("slave:%d retry timeout,remove the send data.",s->addr);
list_remove(p->send_data,0);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
if (list_length(p->send_data)>0)
{
// DBG_LOG("protmcu:EVENT_SEND.");
rt_event_send(p->event,EVENT_SEND);
}
else{
irq_disable();
p->in_send=0;
irq_enable();
}
}
// <20><><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>Ŀ
static int _list_send_data_del(void *t)
{
send_data_def *a=t;
arr_delete(a->data);
return 0;
}
protm_def *protm_creat(uart_def *uart,int *addrs,int num)
{
static int count=0;
char name[20]={0};
protm_def *p=calloc(1,sizeof(protm_def));
param_check(p);
p->uart=uart;
sprintf(name,"protm_event#%d",count);
p->event=rt_event_create(name,RT_IPC_FLAG_FIFO);
p->buff=arr_creat();
p->run=1;
p->slaves=list_creat(sizeof(protm_slave),protm_slave_sub,protm_slave_del,0);
p->slaves_addr=list_creat_int();
p->send_data=list_creat(sizeof(send_data_def),0,_list_send_data_del,0);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٵȴ<D9B5><C8B4>ӻ<EFBFBD><D3BB><EFBFBD><EFBFBD><EFBFBD>
p->timer=rt_timer_create("port_timer",protm_send_timeout_cb,p,
rt_tick_from_millisecond(55),
RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
list_appends(p->slaves_addr,addrs,num);
sprintf(name,"protm_t#%d",count);
rt_thread_t rt_t=rt_thread_create(name,protm_run,p,512,5,20);
rt_thread_startup(rt_t);
p->uart->init(p->uart);
p->uart->set_irq(p->uart,recv_irq,p);
count++;
return p;
}
// <20>õ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>Ĵӻ<C4B4>,<2C>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
protm_slave *protm_get_slave(protm_def *p,uint8_t addr)
{
protm_slave *r=0;
for(int i=0;i<list_length(p->slaves);i++)
{
r=list_get(p->slaves,i);
if(r->addr==addr)
return r;
}
r=protm_slave_creat();
r->addr=addr;
r->cmds=list_creat_int();
r->no=0;
list_append(p->slaves,r);
free(r);
return list_get(p->slaves,-1);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дӻ<D0B4><D3BB><EFBFBD>ˮ<EFBFBD><CBAE>
void protm_set_no_all(protm_def *p,uint16_t no,list_def *cmd/*int*/)
{
for(int i=0;i<list_length(p->slaves);i++)
{
protm_slave *s=list_get(p->slaves,i);
s->no=no;
list_clear(s->cmds);
list_append_from(s->cmds,cmd);
}
}
// <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ӻ<EFBFBD><D3BB><EFBFBD>ˮ<EFBFBD><CBAE>
void protm_set_no(protm_def *p,uint8_t addr,uint16_t no,list_def *cmd/*int*/)
{
protm_slave *s=protm_get_slave(p,addr);
s->no=no;
list_clear(s->cmds);
list_append_from(s->cmds,cmd);
}
// <20><><EFBFBD><EFBFBD>
array_def *protm_decode(protm_def *p,array_def *data)
{
array_def *r=arr_creat();
param_check(r);
str_set(p->str_err,"ok");
if(arr_length(data)<10)
{
DBG_WARN("recv data len too less.");
str_set(p->str_err,"recv data len too less.");
return r;
}
uint8_t src=arr_get(data,4);
p->recv_src=src;
uint16_t len=arr_get(data,2)|(arr_get(data,3)<<8);
uint8_t crc=crc_crc8(arr_data(data),arr_length(data)-1);
if(len!=arr_length(data))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>ʧ
DBG_WARN("recv data have lossed.");
str_set(p->str_err,"recv data have lossed.");
return r;
}
uint16_t no=arr_get(data,7)|(arr_get(data,8)<<8);
uint16_t h_no=protm_get_slave(p,src)->no;
if(no!=h_no)
{
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ָ<EFBFBD><D6B8><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>ʱ<EFBFBD><CAB1>ˮ<EFBFBD><CBAE>Ӧ<EFBFBD><D3A6>ͬ
//DBG_WARN("slave_addr=%d cmd_no error:h_no=%d,no=%d.",src,h_no,no);
//str_set(p->str_err,"cmd no err.");
//return r;
}
if(crc!=arr_get(data,-1))
{
DBG_WARN("recv data crc check error:%02x,%02x.",crc,arr_get(data,-1));
str_set(p->str_err,"crc check err.");
}
p->recv_cmd=arr_get(data,6);
list_def *cmds=protm_get_slave(p,src)->cmds;
if(list_contains(cmds,(int []){p->recv_cmd})==0){
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><E9B2BB>
DBG_WARN("cmd check err.cmds=%s,recv_cmd=%d",tappend(list_string(cmds),0),p->recv_cmd);
str_set(p->str_err,"cmd check err.");
}
arr_delete(r);
return arr_mid(data,9,len-10);
}
// <20><><EFBFBD><EFBFBD>
array_def *protm_encode(protm_def *p,uint8_t dst,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data)
{
array_def *t=arr_creat();
param_check(t);
uint16_t len=arr_length(data)+10;
protm_slave *slave=protm_get_slave(p,dst);
slave->no++;
protm_set_no(p,dst,slave->no,comp_cmd);
arr_append(t,'Y');
arr_append(t,'e');
arr_append(t,len&0xff);
arr_append(t,len>>8);
arr_append(t,0);// Դ<><D4B4>ַ
arr_append(t,dst);// Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
arr_append(t,cmd);// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
arr_append(t,slave->no&0xff);
arr_append(t,slave->no>>8);
arr_appends_from(t,data);
arr_append(t,crc_crc8(arr_data(t),arr_length(t)));
return t;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʱ<EFBFBD><CAB1>
int protm_send(protm_def *p,send_data_def *d)
{
rt_tick_t tick=0;
protm_slave *s=protm_get_slave(p,d->addr);
//DBG_LOG("send:%s",str_temp(arr_string(d->data)));
tick=rt_tick_from_millisecond(s->timeout_ms);
rt_timer_control(p->timer,RT_TIMER_CTRL_SET_TIME,&tick);
rt_timer_start(p->timer);
if(d->data==0)
{
DBG_WARN("addr=%d,d->data=0",d->addr);
return 0;
}
return p->uart->write(p->uart,arr_data(d->data),arr_length(d->data));
}
//// <20>ۺ<EFBFBD><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ
//void protm_send_call(protm_def *p,list_def *addrs/*int*/,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data)
//{
// param_check(p);
// for(int i=0;i<list_length(addrs);i++)
// {
// uint8_t dst=(uint8_t)list_get_int(addrs,i);
// if(list_contains(p->slaves_addr,(int []){dst})==1)
// {
// array_def *t=0;
// t=protm_encode(p,dst,cmd,comp_cmd,data);
// protm_send(p,t);
// arr_delete(t);
// }
// }
//}
// <20>ۺ<EFBFBD><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ
void protm_send_call(protm_def *p,uint8_t addr,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data,int timeout_ms,int retry)
{
param_check(p);
if(list_contains(p->slaves_addr,(int []){addr})==1)
{
array_def *t=0;
t=protm_encode(p,addr,cmd,comp_cmd,data);
//protm_send(p,t);
//arr_delete(t);
// <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>У<EFBFBD><D0A3><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
DBG_LOG("send to:%d",addr);
send_data_def sd={0};
sd.addr=addr;sd.data=t;
protm_slave *s=protm_get_slave(p,addr);
s->retry=retry;
s->timeout_ms=timeout_ms;
list_append(p->send_data,&sd);
if(p->in_send==0){
irq_disable();
p->in_send=1;
irq_enable();
//DBG_LOG("send call");
rt_event_send(p->event,EVENT_SEND);
}
}
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD><31>ʾ<EFBFBD>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>Է<EFBFBD><D4B7>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>
int protm_contains(protm_def *p,uint8_t addr)
{
param_check(p);
return list_contains(p->slaves_addr,(int []){addr});
}