345 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			345 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "stdio.h"
 | |
| #include "rtthread.h"
 | |
| #include "board.h"
 | |
| #include "mystdlib.h"
 | |
| #include "list.h"
 | |
| #include "mystring.h"
 | |
| #include "signal.h"
 | |
| #include "prot_uc.h"
 | |
| #include "buff.h"
 | |
| #include "bytearray.h"
 | |
| #include "debug.h"
 | |
| #include "crc.h"
 | |
| #include "dev_flash.h"
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| // 接收buff大小
 | |
| #define RECV_BUFF_SIZE  300
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void recv_irq(void *t,uint8_t d)
 | |
| {
 | |
|   protu_def *p=t;
 | |
|   p->buff[p->buff_index]=d;
 | |
|   p->buff_index++;
 | |
|   switch(p->buff_index){
 | |
|     case 2:
 | |
|       if(p->buff[0]==0x59&&p->buff[1]==0x6d)
 | |
|       {
 | |
|         p->is_big_data=0;
 | |
|         p->num_to_recv=4;
 | |
|       }else{
 | |
|         p->buff[0]=p->buff[1];
 | |
|         p->num_to_recv=0;
 | |
|       }
 | |
|       break;
 | |
|     case 4:
 | |
|       {
 | |
|         int len=p->buff[2]|(p->buff[3]<<8);
 | |
|         if(len<65535){
 | |
|           p->is_big_data=0;
 | |
|           p->num_to_recv+=len+2;
 | |
|         }else{
 | |
|           p->is_big_data=1;
 | |
|           p->num_to_recv=11;
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     case 11:
 | |
|       {
 | |
|         if(p->is_big_data==1)
 | |
|         {
 | |
|           int len=p->buff[7]|(p->buff[8]<<8)|(p->buff[9]<<16)|(p->buff[10]<<24);
 | |
|           p->num_to_recv=4+len+2;
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
|   // 此时一帧数据已完成
 | |
|   if(p->num_to_recv>0&&p->num_to_recv==p->buff_index)
 | |
|   {
 | |
|     //DBG_LOG("recv:%s",str_temp(arr_string(p->buff)));
 | |
|     rt_sem_release(p->sem);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| static void recv_end_irq(void *t,uint32_t len)
 | |
| {
 | |
|   protu_def *p=t;
 | |
|   p->num_to_recv=len;
 | |
|   p->buff_index=len;
 | |
|   rt_sem_release(p->sem);
 | |
| }
 | |
| 
 | |
| array_def *protu_decode_str(protu_def *p,array_def *data);
 | |
| array_def *protu_encode_str(protu_def *p,array_def *data);
 | |
| 
 | |
| 
 | |
| // 查找指定解码器
 | |
| codec_item *protu_find_codec(const char *name)
 | |
| {
 | |
|   extern const int codecstruct$$Base;
 | |
|   extern const int codecstruct$$Limit;
 | |
|   codec_item *start=(codec_item *)&codecstruct$$Base;
 | |
|   codec_item *end=(codec_item *)&codecstruct$$Limit;
 | |
|   for(codec_item *t=start;t<end;t++)
 | |
|   {
 | |
|     if(strcmp(t->name,name)==0)
 | |
|     {
 | |
|       return t;
 | |
|     }
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| // 返回正在使用的解码器
 | |
| codec_item *protu_codec_inuse(protu_def *p)
 | |
| {
 | |
|   return p->codec;
 | |
| }
 | |
| void protu_codec_set(protu_def *p,codec_item *c)
 | |
| {
 | |
|   p->codec=c;
 | |
| }
 | |
| 
 | |
| 
 | |
| // 尝试解码
 | |
| static array_def *protu_try_decode(protu_def *p,array_def *data)
 | |
| {
 | |
|   array_def *decode_data=0;
 | |
|   if(p->codec==0||p->codec->decode==protu_decode_str||
 | |
|     (decode_data=p->codec->decode(p,data),strcmp(p->str_err,"ok")!=0))
 | |
|   {
 | |
|     CHECK_DO(decode_data,arr_delete);
 | |
|     extern const int codecstruct$$Base;
 | |
|     extern const int codecstruct$$Limit;
 | |
|     codec_item *start=(codec_item *)&codecstruct$$Base;
 | |
|     codec_item *end=(codec_item *)&codecstruct$$Limit;
 | |
|     for(codec_item *t=start;t<end;t++)
 | |
|     {
 | |
|       decode_data=t->decode(p,data);
 | |
|       if(strcmp(p->str_err,"ok")==0)
 | |
|       {
 | |
|         p->codec=t;
 | |
|         break;
 | |
|       }
 | |
|       else{
 | |
|         arr_delete(decode_data);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if(decode_data==0)
 | |
|     decode_data=arr_creat();
 | |
|   return decode_data;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void protu_run(void *t)
 | |
| {
 | |
|   protu_def *p=t;
 | |
|   array_def *data;
 | |
|   array_def *decode_data;
 | |
|   while(p->run)
 | |
|   {
 | |
|     rt_sem_take(p->sem,RT_WAITING_FOREVER);
 | |
|     //DBG_LOG("protu run");
 | |
|     data=arr_creat();
 | |
|     arr_appends(data,p->buff,p->buff_index);
 | |
|     p->num_to_recv=0;
 | |
|     p->buff_index=0;
 | |
|     DBG_LOG("recv:%s",str_temp(arr_string(data)));
 | |
|     decode_data=protu_try_decode(p,data);
 | |
|     //DBG_LOG("decode:%s",str_temp(arr_string(decode_data)));
 | |
|     if(p->codec)
 | |
|       emit protu_recv_signal(p,p->codec->name, p->cmd,arr_temp(decode_data),str_temp(str_duplicate(p->str_err)));
 | |
|     arr_delete(data);
 | |
|     irq_disable();
 | |
|     p->num_to_recv=0;
 | |
|     irq_enable();
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // 根据设备类型初始化编解码指针
 | |
| static void protu_set_endecode_fun(protu_def *u)
 | |
| {
 | |
|   const sys_param_def *par=sys_param();
 | |
|   if(strcmp(par->device_type,"coder")==0)
 | |
|   {
 | |
|   }
 | |
|   else if(strcmp(par->device_type,"checker")==0)
 | |
|   {
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static int protu_init(void)
 | |
| {
 | |
|   const sys_param_def *par=sys_param();
 | |
|   const char *name="uart4";
 | |
|   if(strcmp((par->host_if),"utcp")==0)
 | |
|     name="utcp";
 | |
|   protu_def *protu=protu_creat(dev_get(name));
 | |
|   app_variable("protu",protu,0);
 | |
|   
 | |
|   // 如果通信接口不是用的串口,则增加一个串口的通信
 | |
|   if(strcmp(par->host_if,"uart4")==0)
 | |
|   {
 | |
|     app_variable("protu2",protu,0);
 | |
|   }else
 | |
|   {
 | |
|     protu_def *protu2=protu_creat(dev_get("uart4"));
 | |
|     app_variable("protu2",protu2,0);
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| app_init_export(protu_init)
 | |
| 
 | |
| 
 | |
| 
 | |
| protu_def *protu_creat(uart_def *uart)
 | |
| {
 | |
|   static uint16_t count=0;
 | |
|   char name[20]={0};
 | |
|   protu_def *p=calloc(1,sizeof(protu_def));
 | |
|   param_check(p);
 | |
|   p->uart=uart;
 | |
|   sprintf(name,"protu_sem#%d",count);
 | |
|   p->sem=rt_sem_create(name,0,RT_IPC_FLAG_FIFO);
 | |
|   p->buff=malloc(RECV_BUFF_SIZE);
 | |
|   p->run=1;
 | |
|   p->cmd=0xff;// 命令字不可能是0xff
 | |
|   protu_set_endecode_fun(p);
 | |
|   sprintf(name,"protu_t#%d",count);
 | |
|   rt_thread_t rt_t=rt_thread_create(name,protu_run,p,2048,5,20);
 | |
|   rt_thread_startup(rt_t);
 | |
|   int bsp=sys_param()->uartbsp;
 | |
|   if(bsp==9600)
 | |
|     p->uart->init(p->uart,9600);
 | |
|   else
 | |
|     p->uart->init(p->uart,0);
 | |
|   //p->uart->set_irq(p->uart,recv_irq,p);
 | |
|   p->uart->set_end_irq(p->uart,p->buff,RECV_BUFF_SIZE,recv_end_irq,p);
 | |
|   
 | |
|   count++;
 | |
|   return p;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| int protu_send(protu_def *p,array_def *data)
 | |
| {
 | |
|   DBG_LOG("send:%s",str_temp(arr_string(data)));
 | |
|   return p->uart->write(p->uart,arr_data(data),arr_length(data));
 | |
| }
 | |
| 
 | |
| 
 | |
| // 槽函数,回复上位机
 | |
| void protu_reply_call(protu_def *p,array_def *data)
 | |
| {
 | |
|   param_check(p);
 | |
|   array_def *t=0;
 | |
|   if(p->codec)
 | |
|     t=p->codec->encode(p,data);
 | |
|   // DBG_LOG("send encode:%s",arr_string(t));
 | |
|   if(t){
 | |
|     protu_send(p,t);
 | |
|     arr_delete(t);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // 槽函数,主动上发
 | |
| void protu_send_call(protu_def *p,uint8_t cmd,array_def *data)
 | |
| {
 | |
|   array_def *t=0;
 | |
|   if(cmd!=0){
 | |
|     p->cmd=cmd;
 | |
|     p->cmd_no++;
 | |
|     if(p->codec)
 | |
|       t=p->codec->encode(p,data);
 | |
|   }else if(p->cmd==0)
 | |
|   {
 | |
|     // 命令字为0是字符串
 | |
|     t=protu_encode_str(p,data);
 | |
|   }
 | |
|   if(t){
 | |
|     protu_send(p,t);
 | |
|     arr_delete(t);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| // 字符串解码
 | |
| array_def *protu_decode_str(protu_def *p,array_def *data)
 | |
| {
 | |
|   array_def *r=arr_creat();
 | |
|   param_check(r);
 | |
|   DBG_LOG("decode for command");
 | |
|   str_set(p->str_err,"ok");
 | |
|   p->cmd=0;
 | |
|   if(str_is_print_str((const char *)arr_data(data),arr_length(data))==1)
 | |
|   {
 | |
|     arr_append(data,0);
 | |
|     arr_appends_from(r,data);
 | |
|   }else{
 | |
|     DBG_WARN("data not a string");
 | |
|     str_set(p->str_err,"not string");
 | |
|     //arr_remove(data,arr_length(data)-1,1);
 | |
|   }
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // 字符串编码
 | |
| array_def *protu_encode_str(protu_def *p,array_def *data)
 | |
| {
 | |
|   array_def *t=arr_creat();
 | |
|   param_check(t);
 | |
|   arr_appends_from(t,data);
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| 
 | |
| protuc_codec_export(string,protu_decode_str,protu_encode_str);
 | |
| 
 | |
| 
 | |
| 
 | 
