297 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			297 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | 
 | ||
|  | 
 | ||
|  | #include "signal.h"
 | ||
|  | #include "board.h"
 | ||
|  | #include "stdlib.h"
 | ||
|  | #include "stdio.h"
 | ||
|  | #include "debug.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | typedef struct{ | ||
|  |   void *mutex; | ||
|  |   signal_list *head; | ||
|  | }self_def; | ||
|  | 
 | ||
|  | 
 | ||
|  | static self_def g_self; | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | int signal_init(void) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   if(s->mutex==0) | ||
|  |   { | ||
|  |     s->mutex=rt_mutex_create("signal_",RT_IPC_FLAG_FIFO); | ||
|  |   } | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) | ||
|  | { | ||
|  |   for(int i=0;i<num_4byte;i++) | ||
|  |   { | ||
|  |     dst[i]=src[i]; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #define SLOT_FUN_RUN(fun,param) \
 | ||
|  |   ((slot_fun_def)(fun))(param[0],param[1],param[2],\ | ||
|  |     param[3],param[4],param[5],param[6],param[7]) | ||
|  | 
 | ||
|  | typedef void (*slot_fun_def)(uint32_t a,uint32_t b,uint32_t c,uint32_t d,uint32_t e,uint32_t f,uint32_t g,uint32_t h); | ||
|  | 
 | ||
|  | static void slot_run(void *t) | ||
|  | { | ||
|  |   param_check(t); | ||
|  |   slot_run_def *s=t; | ||
|  |   int msg_size=sizeof(slot_msg_def)+sizeof(uint32_t)*8; | ||
|  |   slot_msg_def *msg=calloc(1,msg_size); | ||
|  |   while(s->run) | ||
|  |   { | ||
|  |     rt_mq_recv(s->mb,msg,msg_size,RT_WAITING_FOREVER); | ||
|  |     SLOT_FUN_RUN(msg->fun,msg->param); | ||
|  |   } | ||
|  |   free(msg); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // 创建一个线程
 | ||
|  | sig_thread thread_creat(int pro) | ||
|  | { | ||
|  |   static uint16_t count=0; | ||
|  |   char name[20]={0}; | ||
|  |   slot_run_def *run=calloc(1,sizeof(slot_run_def)); | ||
|  |   run->run=1; | ||
|  |   sprintf(name,"sig_mq#%d",count); | ||
|  |   run->mb=rt_mq_create(name,(sizeof(slot_msg_def)+sizeof(uint32_t)*8),50,RT_IPC_FLAG_FIFO); | ||
|  |   sprintf(name,"sig_t#%d",count); | ||
|  |   rt_thread_t rt_t=rt_thread_create(name,slot_run,run,2048,pro,20); | ||
|  |   rt_thread_startup(rt_t); | ||
|  |   count++; | ||
|  |   return run->mb; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void thread_delete(sig_thread t) | ||
|  | { | ||
|  |   // 删除线程需要删除与此线程相关的所有信号槽
 | ||
|  |   // 删除消息队列
 | ||
|  |   param_check(0); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | // 如果这个类的信号已注册
 | ||
|  | static signal_list *find(void *sig_obj,void *signal_) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   signal_list *l=s->head; | ||
|  |   while(l!=0) | ||
|  |   { | ||
|  |     if(l->signal_==signal_&&l->sig_obj==sig_obj) | ||
|  |       return l; | ||
|  |     l=l->next; | ||
|  |   } | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int connect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   signal_def *sig; | ||
|  |   sig=signal_find(signal_); | ||
|  |   if(sig==0) return -1; | ||
|  |   rt_mutex_take(s->mutex,RT_WAITING_FOREVER); | ||
|  |   slot_list *slo=calloc(1,sizeof(slot_list)); | ||
|  |   param_check(slo); | ||
|  |   slo->fun=slot; | ||
|  |   slo->mb=t; | ||
|  |   slo->next=0; | ||
|  |   slo->obj=slot_obj; | ||
|  |   signal_list *sig_l=find(sig_obj,signal_); | ||
|  | 
 | ||
|  |   if(sig_l==0){ | ||
|  |     sig_l=calloc(1,sizeof(signal_list)); | ||
|  |     param_check(sig_l); | ||
|  |     sig_l->signal_=signal_; | ||
|  |     sig_l->sig_obj=sig_obj; | ||
|  |     sig_l->next=s->head; | ||
|  |     s->head=sig_l; | ||
|  |   } | ||
|  |   slo->next=sig_l->head; | ||
|  |   sig_l->head=slo; | ||
|  |   //DBG_LOG("signal connect:%08x",slo);
 | ||
|  |   rt_mutex_release(s->mutex); | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | int disconnect(void *sig_obj,void *signal_,sig_thread t,void *slot_obj,void *slot) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   signal_list *sig; | ||
|  |   sig=find(sig_obj,signal_); | ||
|  |   if(sig==0) return -1; | ||
|  |   int ret=-1; | ||
|  |   rt_mutex_take(s->mutex,RT_WAITING_FOREVER); | ||
|  |   slot_list *next=sig->head; | ||
|  |   slot_list *prev=0; | ||
|  |   while(next!=0) | ||
|  |   { | ||
|  |     if(next->fun==slot&&next->obj==slot_obj) | ||
|  |     { | ||
|  |       if(prev) prev->next=next->next; | ||
|  |       else sig->head=next->next; | ||
|  |       //DBG_LOG("signal disconnect:%08x",next);
 | ||
|  |       free(next); | ||
|  |       ret=0; | ||
|  |       break; | ||
|  |     } | ||
|  |     prev=next; | ||
|  |     next=next->next; | ||
|  |   } | ||
|  |   rt_mutex_release(s->mutex); | ||
|  |   return ret; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | // 消除与指定对象相关的所有信号槽连接
 | ||
|  | int disconnect_sig(void *sig_obj) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   rt_mutex_take(s->mutex,RT_WAITING_FOREVER); | ||
|  |   signal_list *sig=s->head; | ||
|  |   signal_list *prev_sig=0; | ||
|  |   while(sig!=0) | ||
|  |   { | ||
|  |     if(sig->sig_obj==sig_obj) | ||
|  |     { | ||
|  |       slot_list *next=sig->head; | ||
|  |       while(next!=0) | ||
|  |       { | ||
|  |         sig->head=next->next; | ||
|  |         free(next); | ||
|  |         next=sig->head; | ||
|  |       } | ||
|  |       if(prev_sig) prev_sig=sig->next; | ||
|  |       else s->head=sig->next; | ||
|  |       free(sig); | ||
|  |       break; | ||
|  |     } | ||
|  |     prev_sig=sig; | ||
|  |     sig=sig->next; | ||
|  |   } | ||
|  |   rt_mutex_release(s->mutex); | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | // 消除与指定对象相关的所有信号槽连接
 | ||
|  | int disconnect_slot(void *slot_obj) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   rt_mutex_take(s->mutex,RT_WAITING_FOREVER); | ||
|  |   signal_list *sig=s->head; | ||
|  |   while(sig!=0) | ||
|  |   { | ||
|  |     slot_list *next=sig->head; | ||
|  |     slot_list *prev=0; | ||
|  |     while(next!=0) | ||
|  |     { | ||
|  |       if(next->obj==slot_obj) | ||
|  |       { | ||
|  |         if(prev) prev->next=next->next; | ||
|  |         else sig->head=next->next; | ||
|  |         free(next); | ||
|  |         break; | ||
|  |       } | ||
|  |       prev=next; | ||
|  |       next=next->next; | ||
|  |     } | ||
|  |     sig=sig->next; | ||
|  |   } | ||
|  |   rt_mutex_release(s->mutex); | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | signal_def *signal_find(void *signal_) | ||
|  | { | ||
|  |   extern const int signalstruct$$Base; | ||
|  |   extern const int signalstruct$$Limit; | ||
|  |   signal_def *start=(signal_def *)&signalstruct$$Base; | ||
|  |   signal_def *end=(signal_def *)&signalstruct$$Limit; | ||
|  |   for(signal_def *t=start;t<end;t++) | ||
|  |   { | ||
|  |     if(t->signal_==signal_) | ||
|  |     { | ||
|  |       return t; | ||
|  |     } | ||
|  |   } | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | // 发送信号
 | ||
|  | int _signal_emit(void *sig_obj,void *signal_,uint32_t *param,int param_num) | ||
|  | { | ||
|  |   self_def *s=&g_self; | ||
|  |   signal_list *sig=find(sig_obj,signal_); | ||
|  |   if(sig==0) return -1; | ||
|  |   if(param_num>7) return -2; | ||
|  |   int size=sizeof(slot_msg_def)+sizeof(uint32_t)*(8); | ||
|  |   slot_msg_def *m=malloc(size); | ||
|  |   rt_mutex_take(s->mutex,RT_WAITING_FOREVER); | ||
|  |   slot_list *h=sig->head; | ||
|  |   m->param_num=param_num; | ||
|  |   m->src=signal_; | ||
|  |   while(h) | ||
|  |   { | ||
|  |     m->fun=h->fun; | ||
|  |     if(h->obj) | ||
|  |     { | ||
|  |       cpy4byte(m->param+1,param,param_num); | ||
|  |       m->param[0]=(uint32_t)h->obj; | ||
|  |     }else{ | ||
|  |       cpy4byte(m->param,param,param_num); | ||
|  |     } | ||
|  |     if(h->mb){ | ||
|  |       rt_mq_send(h->mb,m,size); | ||
|  |     }else{ | ||
|  |       SLOT_FUN_RUN(m->fun,m->param); | ||
|  |     } | ||
|  |     h=h->next; | ||
|  |   } | ||
|  |   rt_mutex_release(s->mutex); | ||
|  |   free(m); | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 |