MAILBOX_EXTERN long mailbox_register_cb( unsigned long mailcode, void (*cb)(void *mbuf, void *handle, void *data), void *usr_handle, void *usr_data) { struct mb_cb *read_cb = MAILBOX_NULL; struct mb_buff *mbuf = MAILBOX_NULL; struct mb *mb = MAILBOX_NULL; unsigned long dst_id; mb = &g_mailbox_handle;/*有可能在初始化过程中注册*/ /* 允许注册空回调,相当于UnRegister if (MAILBOX_NULL == pFun) { return mailbox_logerro_p1(MAILBOX_ERR_GUT_MAILBOX_NULL_PARAM, mailcode); } */ /*往某个CPU的某个邮箱通道中的某个邮件应用用注册回调函数*/ dst_id = mailbox_get_dst_id(mailcode); printk("mb->local_id = %ld dst_id = %ld\n", mb->local_id, dst_id); if (mb->local_id != dst_id) { return mailbox_logerro_p1(MAILBOX_ERR_GUT_INVALID_TARGET_CPU, mailcode); } mbuf = mailbox_get_channel_handle(mb, mailcode); if (MAILBOX_NULL == mbuf) { /*找不到,此通道未初始化。*/ return mailbox_logerro_p1(MAILBOX_ERR_GUT_INVALID_CHANNEL_ID, mailcode); } /*检查OK, 赋值给回调函数指针*/ read_cb = &mbuf->read_cb[mailbox_get_use_id(mailcode)]; if (MAILBOX_NULL != read_cb->func) { /*mailbox_logerro_p1(MAILBOX_WARNING_USER_CALLBACK_ALREADY_EXIST, mailcode);*/ } mailbox_mutex_lock(&mbuf->mutex); read_cb->handle = usr_handle; read_cb->data = usr_data; read_cb->func = cb; mailbox_mutex_unlock(&mbuf->mutex); return MAILBOX_OK; }
/***************************************************************************** 函 数 名 : mailbox_release_channel 接口类型 : 对内接口 功能描述 : 关闭邮箱,释放资源。 输入参数 : mb_buff* mbuff - 邮箱通道缓存操作符 输出参数 : 无 返 回 值 : 邮箱关闭是否成功 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2012年9月27日 作 者 : 莫南 00176101 修改内容 : 新生成函数 *****************************************************************************/ MAILBOX_LOCAL long mailbox_release_channel(struct mb *mb, struct mb_buff *mbuff) { unsigned long channel_id = mbuff->channel_id; /*需要区分是读还是写*/ if (mb->local_id == mailbox_get_src_id(channel_id)) { if (MAILBOX_TRUE == mailbox_int_context()) { /*TODO:接下来的开发(IFC for 低功耗)可能需要支持在中断中发送邮件, 这里就需要解锁中断。*/ } else { mailbox_mutex_unlock(&mbuff->mutex); } } return MAILBOX_OK; }
/***************************************************************************** 函 数 名 : mailbox_read_mail 接口类型 : 对内接口 功能描述 : 读取并处理一封邮箱的正文数据内容,接受邮箱数据的数据层入口, 并且调用上层注册的邮件数据处理回调函数 输入参数 : mb_buff* mbuff - 邮箱通道操作符 输出参数 : 无 返 回 值 : 读取的邮件数据长度,包括邮件头,返回0表示失败。 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2012年9月24日 作 者 : 莫南 00176101 修改内容 : 新生成函数 *****************************************************************************/ MAILBOX_LOCAL long mailbox_read_mail(struct mb_buff *mbuff) { struct mb_mail mail; struct mb_cb *read_cb = MAILBOX_NULL;/*此邮箱通道的功能回调函数队列*/ struct mb_queue tmp_queue; struct mb_queue *usr_queue = MAILBOX_NULL; struct mb_queue *m_queue = MAILBOX_NULL; unsigned long use_id; unsigned long slice_start; unsigned long to_bottom; void *usr_handle; void *usr_data; void (*usr_func)(void *mbuf, void *handle, void *data); m_queue = &(mbuff->mail_queue); usr_queue = &(mbuff->usr_queue); mailbox_memcpy((void *) usr_queue, (const void *) m_queue, sizeof(struct mb_queue)); /*保存临时队列状态,交换读写指针。*/ tmp_queue.base = usr_queue->base; tmp_queue.length = usr_queue->length; tmp_queue.front = usr_queue->rear; tmp_queue.rear = usr_queue->front; /*读取邮件的头信息*/ mailbox_queue_read(usr_queue, (char*)&mail, sizeof(struct mb_mail)); /*1.检查邮件头,判断读到的消息是否存在异常,包括SN号是否连续、消息滞留时间是否过长。 2.填充信息读取时间*/ mailbox_check_mail(mbuff, &mail, m_queue->rear); /*把读取时间写回邮箱队列*/ mailbox_queue_write(&tmp_queue, (char*)&mail, sizeof(struct mb_mail)); use_id = mailbox_get_use_id(mail.ulMailCode); /*检查Use ID的有效性*/ if (use_id >= mailbox_get_use_id(mbuff->config->butt_id)) { mailbox_logerro_p1(MAILBOX_ERR_GUT_INVALID_USER_ID, mail.ulMailCode); goto EXIT; } read_cb = &mbuff->read_cb[use_id]; mailbox_mutex_lock(&mbuff->mutex); usr_handle = read_cb->handle; usr_data = read_cb->data; usr_func = read_cb->func; mailbox_mutex_unlock(&mbuff->mutex); if (MAILBOX_NULL != usr_func) { usr_queue->size = mail.ulMsgLength; slice_start = mailbox_get_timestamp(); usr_func(mbuff, usr_handle , usr_data); /*记录可维可测信息*/ #ifdef MAILBOX_OPEN_MNTN mailbox_record_receive(&mbuff->mntn, mbuff->channel_id, slice_start); #endif } else { mailbox_logerro_p1(MAILBOX_ERR_GUT_READ_CALLBACK_NOT_FIND, mail.ulMailCode); } EXIT: /*不管用户有没有用回调读数据,读了多少数据,邮箱队列的读指针都需要按实际 大小偏移,以保证后面邮件读取的正确性。*/ to_bottom = (m_queue->base + m_queue->length) - m_queue->rear; if (to_bottom > (mail.ulMsgLength + sizeof(struct mb_mail))) { m_queue->rear += (mail.ulMsgLength + sizeof(struct mb_mail)); } else { m_queue->rear = m_queue->base + ((mail.ulMsgLength + sizeof(struct mb_mail)) - to_bottom); } /*读保证指针4字节对齐*/ m_queue->rear = mailbox_align_size(m_queue->rear, MAILBOX_ALIGN); return (mailbox_align_size(mail.ulMsgLength, MAILBOX_ALIGN) + sizeof(struct mb_mail)); }