Files
checker_gen1/source/soft/signal.c
2025-02-13 23:22:16 +08:00

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),100,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;
}