| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |  | #include "stdio.h"
 | 
					
						
							|  |  |  |  | #include "rtthread.h"
 | 
					
						
							|  |  |  |  | #include "board.h"
 | 
					
						
							|  |  |  |  | #include "mystdlib.h"
 | 
					
						
							|  |  |  |  | #include "list.h"
 | 
					
						
							|  |  |  |  | #include "mystring.h"
 | 
					
						
							|  |  |  |  | #include "signal.h"
 | 
					
						
							|  |  |  |  | #include "handle.h"
 | 
					
						
							|  |  |  |  | #include "buff.h"
 | 
					
						
							|  |  |  |  | #include "bytearray.h"
 | 
					
						
							|  |  |  |  | #include "debug.h"
 | 
					
						
							|  |  |  |  | #include "crc.h"
 | 
					
						
							|  |  |  |  | #include "prot_mcu.h"
 | 
					
						
							|  |  |  |  | #include "mymisc.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * 注码仪 | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |  |  * UART2->1 | 
					
						
							|  |  |  |  |  * UART3->2 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  | **/ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |  | #define PORT_MUN  2
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct{ | 
					
						
							|  |  |  |  |   int init; | 
					
						
							|  |  |  |  |   protm_def *protm[PORT_MUN]; | 
					
						
							|  |  |  |  | }self_def; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static self_def g_self; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct _port_mcu{ | 
					
						
							|  |  |  |  |   protm_def *protm; | 
					
						
							|  |  |  |  |   rt_timer_t timer; | 
					
						
							|  |  |  |  |   int busy; | 
					
						
							|  |  |  |  |   uint8_t addr; | 
					
						
							|  |  |  |  |   handle_def *handle; | 
					
						
							|  |  |  |  | }port_mcu; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | int port_init(void) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   self_def *s=&g_self; | 
					
						
							|  |  |  |  |   if(s->init==0){ | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |  |     s->protm[0]=protm_creat(dev_get("uart2"),(int []){1,},1); | 
					
						
							|  |  |  |  |     s->protm[1]=protm_creat(dev_get("uart3"),(int []){2,},1); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |  |     s->init=1; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return 0; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | port_mcu *port_creat(uint8_t addr,sig_thread t) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   self_def *s=&g_self; | 
					
						
							|  |  |  |  |   if(s->init==0){ | 
					
						
							|  |  |  |  |     DBG_WARN("port not init."); | 
					
						
							|  |  |  |  |     return 0; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   port_mcu *p=calloc(1,sizeof(port_mcu)); | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   p->addr=addr; | 
					
						
							|  |  |  |  |   for(int i=0;i<PORT_MUN;i++) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     if(protm_contains(s->protm[i],addr)) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       p->protm=s->protm[i]; | 
					
						
							|  |  |  |  |       connect(p,port_send_signal,t,p->protm,protm_send_call); | 
					
						
							|  |  |  |  |       connect(p->protm,protm_recv_signal,t,p,port_recv_call); | 
					
						
							|  |  |  |  |       break; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return p; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void port_delete(port_mcu **p) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   param_check(*p); | 
					
						
							|  |  |  |  |   disconnect_sig(*p); | 
					
						
							|  |  |  |  |   CHECK_DO((*p)->timer,rt_timer_delete); | 
					
						
							|  |  |  |  |   CHECK_DO((*p)->handle,(*p)->handle->del); | 
					
						
							|  |  |  |  |   free(*p); | 
					
						
							|  |  |  |  |   *p=0; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void port_recv_call(port_mcu *obj,uint8_t src,uint8_t cmd,array_def *data,char *err_str) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   port_mcu *p=obj; | 
					
						
							|  |  |  |  |   if(src==p->addr) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     //DBG_LOG("addr=%d,cmd=%d,data=%s.",src,cmd,str_temp(arr_string(data)));
 | 
					
						
							|  |  |  |  |     if(p->handle){ | 
					
						
							|  |  |  |  |       p->handle->dolater(p->handle,src,cmd,data,err_str); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     else{ | 
					
						
							|  |  |  |  |       emit port_end_signal(obj,obj,0,0,"success"); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | //  else{
 | 
					
						
							|  |  |  |  | //    DBG_WARN("err data,addr=%d.",src);
 | 
					
						
							|  |  |  |  | //  }
 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void port_timeout_cb(void *t) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   port_mcu *p=t; | 
					
						
							|  |  |  |  |   if(p->handle) | 
					
						
							|  |  |  |  |     p->handle->timeout(p->handle); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 开始定时器,重复调用会重新开始
 | 
					
						
							|  |  |  |  | void port_timer_start(port_mcu *p) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   CHECK_DO(p->timer,rt_timer_start); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 停止定时器
 | 
					
						
							|  |  |  |  | void port_timer_stop(port_mcu *p) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   CHECK_DO(p->timer,rt_timer_stop); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 设置忙状态
 | 
					
						
							|  |  |  |  | void port_set_busy(port_mcu *p,int busy) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   p->busy=busy?1:0; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 获取忙状态
 | 
					
						
							|  |  |  |  | int port_get_busy(port_mcu *p) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   return p->busy; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 获取通信地址
 | 
					
						
							|  |  |  |  | uint8_t port_get_addr(port_mcu *p) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   return p->addr; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 开始一个通信操作,h是此项操作的类
 | 
					
						
							|  |  |  |  | int port_start(port_mcu *p,handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   param_check(p); | 
					
						
							|  |  |  |  |   param_check(h); | 
					
						
							|  |  |  |  |   if(port_get_busy(p)==1){ | 
					
						
							|  |  |  |  |     h->del(h); | 
					
						
							|  |  |  |  |     DBG_WARN("slave:%d, handle is busy:%s",p->addr, p->handle->name); | 
					
						
							|  |  |  |  |     return -1; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   CHECK_DO(p->handle,p->handle->del); | 
					
						
							|  |  |  |  |   p->handle=h; | 
					
						
							|  |  |  |  |   p->handle->p=p; | 
					
						
							|  |  |  |  |   if(p->timer==0) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     char s1[16]={0}; | 
					
						
							|  |  |  |  |     sprintf(s1,"port_t#%d",p->addr); | 
					
						
							|  |  |  |  |     p->timer=rt_timer_create(s1,port_timeout_cb,p, | 
					
						
							|  |  |  |  |       rt_tick_from_millisecond(h->interval), | 
					
						
							|  |  |  |  |       RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   else{ | 
					
						
							|  |  |  |  |     rt_tick_t tick=rt_tick_from_millisecond(h->interval); | 
					
						
							|  |  |  |  |     rt_timer_control(p->timer,RT_TIMER_CTRL_SET_TIME,&tick); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   rt_timer_start(p->timer); | 
					
						
							|  |  |  |  |   p->handle->start(p->handle); | 
					
						
							|  |  |  |  |   return 0; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |  | #define MCU_APP_ADDR_BASE       0x8004000
 | 
					
						
							|  |  |  |  | #define MCU_TASKID_ADDR_BASE    0x803f000
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct{ | 
					
						
							|  |  |  |  |   handle_def h; | 
					
						
							|  |  |  |  |   const uint8_t *data;// 外部地址指针,不需要释放
 | 
					
						
							|  |  |  |  |   int size; | 
					
						
							|  |  |  |  |   int stat; | 
					
						
							|  |  |  |  |   int sent; | 
					
						
							|  |  |  |  |   int retry_time;//升级失败重试次数
 | 
					
						
							|  |  |  |  |   rt_timer_t timer;// 用于发送命令超时
 | 
					
						
							|  |  |  |  | }updata_def; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_del(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_def *c=(updata_def *)h; | 
					
						
							|  |  |  |  |   CHECK_DO(c->timer,rt_timer_delete); | 
					
						
							|  |  |  |  |   free(h); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_start(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_def *c=(updata_def *)h; | 
					
						
							|  |  |  |  |   port_set_busy(h->p,1); | 
					
						
							|  |  |  |  |   c->stat=1; | 
					
						
							|  |  |  |  |   c->sent=0; | 
					
						
							|  |  |  |  |   list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |   int arr[]={0xf9}; | 
					
						
							|  |  |  |  |   list_appends(l,arr,1); | 
					
						
							|  |  |  |  |   emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0xf9,list_temp(l),arr_temp(arr_creat()),60,1); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 跳转到bootloader之后,需要延时一段时间发送擦除命令
 | 
					
						
							|  |  |  |  | static void updata_earse(void *t) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   handle_def *h=t; | 
					
						
							|  |  |  |  |   list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |   int arr[]={0xfe}; | 
					
						
							|  |  |  |  |   list_appends(l,arr,1); | 
					
						
							|  |  |  |  |   emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0xfe,list_temp(l),arr_temp(arr_creat()),5500,1); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_dolater(handle_def *h,uint8_t src,uint8_t cmd,array_def *data,char *err_str) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_def *c=(updata_def *)h; | 
					
						
							|  |  |  |  |   if(port_get_busy(h->p)==0) return; | 
					
						
							|  |  |  |  |   port_timer_start(h->p); | 
					
						
							|  |  |  |  |   if(c->stat==1){ | 
					
						
							|  |  |  |  |     if((arr_length(data)>=2)&&(1==arr_get(data,1))) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       // 这是重试的流程,如果重试时在app状态,则升级成功
 | 
					
						
							|  |  |  |  |       if(c->retry_time>0){ | 
					
						
							|  |  |  |  |         DBG_LOG("slave:%d mcu updata success.",src); | 
					
						
							|  |  |  |  |         emit port_end_signal(h->p,h->p,0,0,"ok"); | 
					
						
							|  |  |  |  |         port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |         port_timer_stop(h->p); | 
					
						
							|  |  |  |  |         return ; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |        | 
					
						
							|  |  |  |  |       // 如果设备不在bootloader,进入这一步
 | 
					
						
							|  |  |  |  |       c->stat=2; | 
					
						
							|  |  |  |  |       DBG_LOG("slave:%d mcu in app mode.",src); | 
					
						
							|  |  |  |  |       // 设备跳转后不响应此命令,只重发一次
 | 
					
						
							|  |  |  |  |       list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |       int arr[]={0xf8}; | 
					
						
							|  |  |  |  |       list_appends(l,arr,1); | 
					
						
							|  |  |  |  |       emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0xf8,list_temp(l),arr_temp(arr_creat()),60,3); | 
					
						
							|  |  |  |  |     }else{ | 
					
						
							|  |  |  |  |       // 都在bootloader模式,直接进入下一步
 | 
					
						
							|  |  |  |  |       c->stat=3; | 
					
						
							|  |  |  |  |       DBG_LOG("slave:%d mcu in bootloader mode.",src); | 
					
						
							|  |  |  |  |       updata_earse(h); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   }else if(c->stat==2){ | 
					
						
							|  |  |  |  |     c->stat=3; | 
					
						
							|  |  |  |  |     DBG_LOG("slave:%d mcu turn in bootloader mode.",src); | 
					
						
							|  |  |  |  |     later_execute(updata_earse,h,1000); | 
					
						
							|  |  |  |  |   }else if(c->stat==3){ | 
					
						
							|  |  |  |  |     if(c->sent<c->size) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       int len=c->sent<c->size-240?240:c->size-c->sent; | 
					
						
							|  |  |  |  |       uint32_t addr=MCU_APP_ADDR_BASE+c->sent; | 
					
						
							|  |  |  |  |       array_def *temp=arr_creat(); | 
					
						
							|  |  |  |  |       arr_append(temp,addr&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>8)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>16)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>24)&0xff); | 
					
						
							|  |  |  |  |       arr_appends(temp,&c->data[c->sent],len); | 
					
						
							|  |  |  |  |       c->sent+=len; | 
					
						
							|  |  |  |  |       list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |       int arr[]={0xfc}; | 
					
						
							|  |  |  |  |       list_appends(l,arr,1); | 
					
						
							|  |  |  |  |       emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0xfc,list_temp(l),arr_temp(temp),350,10); | 
					
						
							|  |  |  |  |       //DBG_LOG("slave addr=%d,rate=%d.",h->p->addr,c->sent*100/c->size);
 | 
					
						
							|  |  |  |  |     }else{ | 
					
						
							|  |  |  |  |       c->stat=4; | 
					
						
							|  |  |  |  |       uint32_t addr; | 
					
						
							|  |  |  |  |       array_def *temp=arr_creat(); | 
					
						
							|  |  |  |  |       addr=MCU_APP_ADDR_BASE; | 
					
						
							|  |  |  |  |       arr_append(temp,addr&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>8)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>16)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>24)&0xff); | 
					
						
							|  |  |  |  |       addr=MCU_APP_ADDR_BASE+c->size; | 
					
						
							|  |  |  |  |       arr_append(temp,addr&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>8)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>16)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>24)&0xff); | 
					
						
							|  |  |  |  |       uint32_t crc=crc_crc32(c->data,c->size); | 
					
						
							|  |  |  |  |       arr_append(temp,crc&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(crc>>8)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(crc>>16)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(crc>>24)&0xff); | 
					
						
							|  |  |  |  |       //DBG_LOG("updata:crc=%08x",crc);
 | 
					
						
							|  |  |  |  |       list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |       int arr[]={0xfb}; | 
					
						
							|  |  |  |  |       list_appends(l,arr,1); | 
					
						
							|  |  |  |  |       emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0xfb,list_temp(l),arr_temp(temp),350,10); | 
					
						
							|  |  |  |  |       DBG_LOG("slave:%d file updata done.",src); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   else if(c->stat==4) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     DBG_LOG("slave:%d mcu reboot to app.",src); | 
					
						
							|  |  |  |  |     emit port_end_signal(h->p,h->p,0,0,"ok"); | 
					
						
							|  |  |  |  |     port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |     port_timer_stop(h->p); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_timeout(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_def *c=(updata_def *)h; | 
					
						
							|  |  |  |  |   // 从机没有指定数目时从这里返回
 | 
					
						
							|  |  |  |  |   DBG_WARN("slave:%d,%s timeout.",h->p->addr, h->name); | 
					
						
							|  |  |  |  |   if(c->retry_time>3) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     port_timer_stop(h->p); | 
					
						
							|  |  |  |  |     port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |     DBG_WARN("slave:%d,%s failed.",h->p->addr, h->name); | 
					
						
							|  |  |  |  |     emit port_end_signal(h->p,h->p,0,-1,"timeout"); | 
					
						
							|  |  |  |  |   }else{ | 
					
						
							|  |  |  |  |     port_timer_start(h->p); | 
					
						
							|  |  |  |  |     DBG_LOG("slave:%d, updata retry",h->p->addr); | 
					
						
							|  |  |  |  |     h->start(h); | 
					
						
							|  |  |  |  |     c->retry_time++; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | handle_def *updata_creat(const uint8_t *data,int size) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_def *c=calloc(1,sizeof(updata_def)); | 
					
						
							|  |  |  |  |   handle_def *h=(handle_def *)c; | 
					
						
							|  |  |  |  |   param_check(h); | 
					
						
							|  |  |  |  |   h->static_=0;// 动态内存这项设置为0
 | 
					
						
							|  |  |  |  |   h->start=updata_start; | 
					
						
							|  |  |  |  |   h->dolater=updata_dolater; | 
					
						
							|  |  |  |  |   h->del=updata_del; | 
					
						
							|  |  |  |  |   h->timeout=updata_timeout; | 
					
						
							|  |  |  |  |   h->interval=15000;// 此项根据方案调整
 | 
					
						
							|  |  |  |  |   h->name="updata"; | 
					
						
							|  |  |  |  |   c->data=data; | 
					
						
							|  |  |  |  |   c->size=size; | 
					
						
							|  |  |  |  |   return h; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct{ | 
					
						
							|  |  |  |  |   handle_def h; | 
					
						
							|  |  |  |  |   const uint8_t *data;// 外部地址指针,不需要释放
 | 
					
						
							|  |  |  |  |   int size; | 
					
						
							|  |  |  |  |   int stat; | 
					
						
							|  |  |  |  |   int sent; | 
					
						
							|  |  |  |  |   int retry_time;//升级失败重试次数
 | 
					
						
							|  |  |  |  |   rt_timer_t timer;// 用于发送命令超时
 | 
					
						
							|  |  |  |  | }updata_scheme_def; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_scheme_del(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_scheme_def *c=(updata_scheme_def *)h; | 
					
						
							|  |  |  |  |   CHECK_DO(c->timer,rt_timer_delete); | 
					
						
							|  |  |  |  |   free(h); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_scheme_send_packet(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_scheme_def *c=(updata_scheme_def *)h; | 
					
						
							|  |  |  |  |   if(port_get_busy(h->p)==0) return; | 
					
						
							|  |  |  |  |   port_timer_start(h->p); | 
					
						
							|  |  |  |  |   if(c->stat==1){ | 
					
						
							|  |  |  |  |     if(c->sent<c->size) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       int len=c->sent<c->size-240?240:c->size-c->sent; | 
					
						
							|  |  |  |  |       uint32_t addr=MCU_TASKID_ADDR_BASE+c->sent; | 
					
						
							|  |  |  |  |       array_def *temp=arr_creat(); | 
					
						
							|  |  |  |  |       arr_append(temp,addr&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>8)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>16)&0xff); | 
					
						
							|  |  |  |  |       arr_append(temp,(addr>>24)&0xff); | 
					
						
							|  |  |  |  |       arr_appends(temp,&c->data[c->sent],len); | 
					
						
							|  |  |  |  |       c->sent+=len; | 
					
						
							|  |  |  |  |       list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |       int arr[]={0x11}; | 
					
						
							|  |  |  |  |       list_appends(l,arr,1); | 
					
						
							|  |  |  |  |       emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0x11,list_temp(l),arr_temp(temp),350,10); | 
					
						
							|  |  |  |  |       //DBG_LOG("slave addr=%d,rate=%d.",h->p->addr,c->sent*100/c->size);
 | 
					
						
							|  |  |  |  |     }else{ | 
					
						
							|  |  |  |  |       c->stat=0; | 
					
						
							|  |  |  |  |       uint32_t addr; | 
					
						
							|  |  |  |  |       array_def *temp=arr_creat(); | 
					
						
							|  |  |  |  |       list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |       int arr[]={0x15}; | 
					
						
							|  |  |  |  |       list_appends(l,arr,1); | 
					
						
							|  |  |  |  |       emit port_send_signal(h->p,((port_mcu *)h->p)->addr,0x15,list_temp(l),arr_temp(temp),350,10); | 
					
						
							|  |  |  |  |       DBG_LOG("slave:%d mcu reboot .",h->p->addr); | 
					
						
							|  |  |  |  |       emit port_end_signal(h->p,h->p,0,0,"ok"); | 
					
						
							|  |  |  |  |       port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |       port_timer_stop(h->p); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_scheme_dolater(handle_def *h,uint8_t src,uint8_t cmd,array_def *data,char *err_str) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_scheme_send_packet(h); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_scheme_start(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_scheme_def *c=(updata_scheme_def *)h; | 
					
						
							|  |  |  |  |   port_set_busy(h->p,1); | 
					
						
							|  |  |  |  |   c->stat=1; | 
					
						
							|  |  |  |  |   c->sent=0; | 
					
						
							|  |  |  |  |   updata_scheme_send_packet(h); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void updata_scheme_timeout(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_scheme_def *c=(updata_scheme_def *)h; | 
					
						
							|  |  |  |  |   // 从机没有指定数目时从这里返回
 | 
					
						
							|  |  |  |  |   DBG_WARN("slave:%d,%s timeout.",h->p->addr, h->name); | 
					
						
							|  |  |  |  |   if(c->retry_time>3) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     port_timer_stop(h->p); | 
					
						
							|  |  |  |  |     port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |     DBG_WARN("slave:%d,%s failed.",h->p->addr, h->name); | 
					
						
							|  |  |  |  |     emit port_end_signal(h->p,h->p,0,-1,"timeout"); | 
					
						
							|  |  |  |  |   }else{ | 
					
						
							|  |  |  |  |     port_timer_start(h->p); | 
					
						
							|  |  |  |  |     DBG_LOG("slave:%d, updata retry",h->p->addr); | 
					
						
							|  |  |  |  |     h->start(h); | 
					
						
							|  |  |  |  |     c->retry_time++; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | handle_def *updata_scheme_creat(const uint8_t *data,int size) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   updata_scheme_def *c=calloc(1,sizeof(updata_scheme_def)); | 
					
						
							|  |  |  |  |   handle_def *h=(handle_def *)c; | 
					
						
							|  |  |  |  |   param_check(h); | 
					
						
							|  |  |  |  |   h->static_=0;// 动态内存这项设置为0
 | 
					
						
							|  |  |  |  |   h->start=updata_scheme_start; | 
					
						
							|  |  |  |  |   h->dolater=updata_scheme_dolater; | 
					
						
							|  |  |  |  |   h->del=updata_scheme_del; | 
					
						
							|  |  |  |  |   h->timeout=updata_scheme_timeout; | 
					
						
							|  |  |  |  |   h->interval=15000;// 此项根据方案调整
 | 
					
						
							|  |  |  |  |   h->name="updata_scheme"; | 
					
						
							|  |  |  |  |   c->data=data; | 
					
						
							|  |  |  |  |   c->size=size; | 
					
						
							|  |  |  |  |   return h; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct{ | 
					
						
							|  |  |  |  |   handle_def h; | 
					
						
							|  |  |  |  |   int data_length; | 
					
						
							|  |  |  |  |   uint8_t cmd; | 
					
						
							|  |  |  |  |   uint8_t data[0]; | 
					
						
							|  |  |  |  | }usercmd_def; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void usercmd_start(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   usercmd_def *u=(usercmd_def *)h; | 
					
						
							|  |  |  |  |   port_set_busy(h->p,1); | 
					
						
							|  |  |  |  |   list_def *l=list_creat_int(); | 
					
						
							|  |  |  |  |   int arr[]={u->cmd}; | 
					
						
							|  |  |  |  |   list_appends(l,arr,1); | 
					
						
							|  |  |  |  |   emit port_send_signal(h->p,port_get_addr(h->p),u->cmd,list_temp(l),arr_temp(arr_creat()),300,3); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void usercmd_dolater(handle_def *h,uint8_t src,uint8_t cmd,array_def *data,char *err_str) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   usercmd_def *c=(usercmd_def *)h; | 
					
						
							|  |  |  |  |   if(port_get_busy(h->p)==0) return; | 
					
						
							|  |  |  |  |   if(cmd==c->cmd) | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |     port_timer_stop(h->p); | 
					
						
							|  |  |  |  |     DBG_LOG("slave:%d, userdata:%s",src,str_temp(arr_string(data))); | 
					
						
							|  |  |  |  |     // 直接返回原始数据
 | 
					
						
							|  |  |  |  |     emit port_end_signal(h->p,h->p,data,0,"ok"); | 
					
						
							|  |  |  |  |   }else | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |     port_timer_stop(h->p); | 
					
						
							|  |  |  |  |     DBG_WARN("slave:%d,get usercmd err,%s",src,str_temp(arr_string(data))); | 
					
						
							|  |  |  |  |     emit port_end_signal(h->p,h->p,0,-1,"get usercmd err"); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void usercmd_timeout(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   // 从机没有指定数目时从这里返回
 | 
					
						
							|  |  |  |  |   port_timer_stop(h->p); | 
					
						
							|  |  |  |  |   port_set_busy(h->p,0); | 
					
						
							|  |  |  |  |   DBG_WARN("slave:%d,%s timeout.",port_get_addr(h->p), h->name); | 
					
						
							|  |  |  |  |   emit port_end_signal(h->p,h->p,0,-1,"timeout"); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void usercmd_del(handle_def *h) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   usercmd_def *c=(usercmd_def *)h; | 
					
						
							|  |  |  |  |   free(h); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | handle_def *usercmd_creat(uint8_t cmd,array_def *data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   int data_len=arr_length(data); | 
					
						
							|  |  |  |  |   usercmd_def *c=calloc(1,sizeof(usercmd_def)+data_len); | 
					
						
							|  |  |  |  |   c->cmd=cmd; | 
					
						
							|  |  |  |  |   c->data_length=data_len; | 
					
						
							|  |  |  |  |   for(int i=0;i<data_len;i++){c->data[i]=arr_get(data,i);} | 
					
						
							|  |  |  |  |   handle_def *h=(handle_def *)c; | 
					
						
							|  |  |  |  |   param_check(h); | 
					
						
							|  |  |  |  |   h->static_=0;// 动态内存这项设置为0
 | 
					
						
							|  |  |  |  |   h->start=usercmd_start; | 
					
						
							|  |  |  |  |   h->dolater=usercmd_dolater; | 
					
						
							|  |  |  |  |   h->del=usercmd_del; | 
					
						
							|  |  |  |  |   h->timeout=usercmd_timeout; | 
					
						
							|  |  |  |  |   h->interval=5000; | 
					
						
							|  |  |  |  |   h->name="usercmd"; | 
					
						
							|  |  |  |  |   return h; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 |