对象定义及操作接口
typedef struct _msg_slot_t
{
uint32_t ms_pid; /* 发送进程id */
uint32_t ms_type; /* 消息类型 */
dword_t ms_param32; /* 32位消息参数 */
qword_t ms_param64; /* 64位消息参数 */
}msg_slot_t;
typedef struct _message_t
{
char msg_name[32]; /* 消息对象名称 */
lock_t msg_lock;
proc_t * msg_send_wait;
proc_t * msg_resv_wait;
int msg_count;
msg_slot_t * msg_buffer;
int msg_send;
int msg_resv;
}message_t;
#define MSG_MAX 24
#define MSG_GLOBAL_LOCK() Lck_lock(&msg_lock)
#define MSG_GLOBAL_FREE() Lck_free(&msg_lock)
#define MSG_LOCK(msg) Lck_lock(&((msg)->msg_lock))
#define MSG_FREE(msg) Lck_free(&((msg)->msg_lock))
#define MSG_IS_FULL(msg) ((((msg)->msg_send + 1) % (msg)->msg_count) == (msg)->msg_resv )
#define MSG_IS_EMPTY(msg) ((((msg)->msg_resv + 1) % (msg)->msg_count) == (msg)->msg_send )
#define MSG_IS_VALID(msg) ((msg)->msg_buffer)
#define MSG_SEND_FORWARD(msg) do{ (msg)->msg_send = ((msg)->msg_send + 1) % (msg)->msg_count; }while(0)
#define MSG_RESV_FORWARD(msg) do{ (msg)->msg_resv = ((msg)->msg_resv + 1) % (msg)->msg_count; }while(0)
void Msg_initial(void);
message_t * Msg_create(const char * name,msg_slot_t * ms,int count);
message_t * Msg_get(const char * name);
result_t Msg_destroy(message_t * msg);
result_t Msg_send(message_t * msg,uint32_t type,dword_t param32,qword_t param64);
result_t Msg_post(message_t * msg,uint32_t type,dword_t param32,qword_t param64);
result_t Msg_resv(message_t * msg ,msg_slot_t * ms);
实现代码
static lock_t msg_lock;
static message_t msg_pool[MSG_MAX];
void Msg_initial(void)
{
memset(msg_pool,0,sizeof(message_t)*MSG_MAX);
msg_lock = 0;
}
message_t * Msg_create(const char * name,msg_slot_t * ms,int count)
{
int i;
message_t * msg;
msg = NULL;
MSG_GLOBAL_LOCK();
for( i = 0 ; i < MSG_MAX ; i++)
{
if( msg_pool[i].msg_buffer )
continue;
msg = msg_pool + i;
msg->msg_buffer = (void *)-1;
break;
}
MSG_GLOBAL_FREE();
if( NULL == msg )
return NULL;
strcpy(msg->msg_name,name);
msg->msg_lock = 0;
msg->msg_send_wait = NULL;
msg->msg_resv_wait = NULL;
msg->msg_buffer = ms;
msg->msg_count = count;
msg->msg_send = 0;
msg->msg_resv = count - 1;
return msg;
}
message_t * Msg_get(const char * name)
{
int i;
message_t * msg;
msg = NULL;
MSG_GLOBAL_LOCK();
for( i = 0 ; i < MSG_MAX ; i++)
{
if( !MSG_IS_VALID(msg_pool + i))
continue;
if( strcmp(name,msg_pool[i].msg_name) == 0 )
{
msg = msg_pool + i;
break;
}
}
MSG_GLOBAL_FREE();
return msg;
}
result_t Msg_destroy(message_t * msg)
{
MSG_GLOBAL_LOCK();
MSG_LOCK(msg);
msg->msg_buffer = NULL;
msg->msg_name[0] = 0;
Proc_wakeup_on(&msg->msg_send_wait);
MSG_FREE(msg);
MSG_GLOBAL_FREE();
return RESULT_SUCCEED;
}
result_t Msg_send(message_t * msg,uint32_t type,dword_t param32,qword_t param64)
{
msg_slot_t * ms;
if( !MSG_IS_VALID(msg))
return -1;
MSG_LOCK(msg);
while( MSG_IS_FULL(msg) )
{
MSG_FREE(msg);
Proc_sleep_on(&msg->msg_send_wait); /* 缓冲区满,睡眠等待 */
if( !MSG_IS_VALID(msg)) /* 睡眠过后,消息对象可能已经销毁 */
return -1;
MSG_LOCK(msg);
}
ms = msg->msg_buffer + msg->msg_send;
ms->ms_pid = proc_current->proc_pid;
ms->ms_type = type;
ms->ms_param32 = param32;
ms->ms_param64 = param64;
MSG_SEND_FORWARD(msg);
MSG_FREE(msg);
Proc_wakeup_on(&msg->msg_resv_wait);
return RESULT_SUCCEED;
}
result_t Msg_post(message_t * msg,uint32_t type,dword_t param32,qword_t param64)
{
msg_slot_t * ms;
if( !MSG_IS_VALID(msg))
return -1;
MSG_LOCK(msg);
if( MSG_IS_FULL(msg) ) /* 缓冲区满,丢弃消息返回 */
{
MSG_FREE(msg);
return -1;
}
ms = msg->msg_buffer + msg->msg_send;
ms->ms_pid = proc_current->proc_pid;
ms->ms_type = type;
ms->ms_param32 = param32;
ms->ms_param64 = param64;
MSG_SEND_FORWARD(msg);
MSG_FREE(msg);
Proc_wakeup_on(&msg->msg_resv_wait);
return RESULT_SUCCEED;
}
result_t Msg_resv(message_t * msg ,msg_slot_t * ms)
{
MSG_LOCK(msg);
while( MSG_IS_EMPTY(msg) )
{
MSG_FREE(msg);
Proc_sleep_on(&msg->msg_resv_wait);
MSG_LOCK(msg);
}
MSG_RESV_FORWARD(msg);
*ms = *(msg->msg_buffer + msg->msg_resv);
MSG_FREE(msg);
Proc_wakeup_on(&msg->msg_send_wait);
return RESULT_SUCCEED;
}
测试代码
msg_slot_t ms_pool[16];
message_t * msg;
int send1(void)
{
int i;
message_t * msg;
qword_t p64;
msg = Msg_get("msg");
if( NULL == msg)
{
printf("can not found message box\n");
return 1;
}
i = 0;
while( i < 16 )
{
Clk_delay(20);
if( RESULT_SUCCEED != Msg_send(msg,i*i,i,p64) )
break;
printf("send1 send msg\n");
i++;
}
return 0;
}
int send2(void)
{
int i;
message_t * msg;
qword_t p64;
msg = Msg_get("msg");
if( NULL == msg)
{
printf("can not found message box\n");
return 1;
}
i = 0;
while( i < 16 )
{
Clk_delay(30);
if( RESULT_SUCCEED != Msg_send(msg,i*i,i,p64) )
break;
printf("send2 send msg\n");
i++;
}
return 0;
}
int resv(void)
{
int i;
msg_slot_t ms;
msg = Msg_create("msg",ms_pool,4);
if( NULL == msg )
{
printf("can not create message\n");
return -1;
}
Proc_create("send1",send1,0,MAKE_STACK(stack2,STACK_SIZE));
Proc_create("send2",send2,0,MAKE_STACK(stack3,STACK_SIZE));
i = 0;
while( i < 8 )
{
Msg_resv(msg,&ms);
printf("resv data.from pid: %ld msg type: %8ld param32: %8ld\n",ms.ms_pid,ms.ms_type,ms.ms_param32);
if( 0 == (i % 3) )
Clk_delay(100);
i++;
}
Msg_destroy(msg);
printf("resv process end\n");
return 0;
}
void main(void)
{
Disable_irq();
Machine_initial();
Proc_initial();
Clk_initial();
Msg_initial();
Enable_irq();
Proc_create("message test",resv,0,MAKE_STACK(stack1,STACK_SIZE));
for(;;)
{
Cpu_hlt();
}
}
测试结果