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;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|