MAILBOX_LOCAL int mailbox_request_channel(
                struct mb *mb,
                struct mb_buff ** mb_buf,
                unsigned int mailcode)
{
    struct mb_head       *head  = MAILBOX_NULL;
    struct mb_queue      *queue = MAILBOX_NULL;
    struct mb_buff       *mbuff = MAILBOX_NULL;
    int ret_val = MAILBOX_OK;

    *mb_buf = MAILBOX_NULL;
    mbuff = mailbox_get_channel_handle(mb, mailcode);
    if (MAILBOX_NULL == mbuff) {
        ret_val = (int)MAILBOX_ERRO;
        goto request_erro;/*lint --e{801}*/
    }

    /*通过判断通道保护字,检查通道有没有初始化*/
    head = (struct mb_head*)mbuff->config->head_addr;
    if ((  (MAILBOX_PROTECT1 != head->ulProtectWord1) )
        || (MAILBOX_PROTECT2 != head->ulProtectWord2)
       ||(MAILBOX_PROTECT1 != head->ulProtectWord3)
       || (MAILBOX_PROTECT2 != head->ulProtectWord4)) {
        /*保护字不正确,说明邮箱未初始化,或者内存被踩,报错。*/
        ret_val = mailbox_logerro_p1(MAILBOX_NOT_READY, mailcode);
        goto request_erro;/*lint --e{801}*/
    }

    if(mailbox_get_src_id(mailcode) == mb->local_id) {
         /* 不允许在中断中发邮件*/
        if (MAILBOX_TRUE == mailbox_int_context()) {
            //TODO:接下来的开发(IFC for 低功耗)可能需要支持在中断中发送邮件,这里就需要锁中断。
            ret_val = mailbox_logerro_p1(MAILBOX_ERR_GUT_SEND_MAIL_IN_INT_CONTEXT, mailcode);
            goto request_erro;/*lint --e{801}*/
        } else {
            if (MAILBOX_OK != mailbox_mutex_lock(&mbuff->mutex)) {
                /*非中断发送,需要资源保护,获取当前通道资源。*/
                ret_val = mailbox_logerro_p1(MAILBOX_CRIT_GUT_MUTEX_LOCK_FAILED, mailcode);
                goto request_erro;/*lint --e{801}*/
            }
        }
    }

    mbuff->mailcode = mailcode;

    /*共享内存队列,需要依据邮箱头信息对队列操作符进行填充*/
    queue = &mbuff->mail_queue;
    queue->front = queue->base + head->ulFront * sizeof(unsigned int);
    queue->rear  = queue->base + head->ulRear * sizeof(unsigned int);

    mbuff->mb = mb;
    *mb_buf = mbuff;

    return MAILBOX_OK;

request_erro:
    //mailbox_out(("###mailbox_request_channel ERR!"RT));
    return ret_val;
}
Пример #2
0
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;
}
Пример #3
0
/*****************************************************************************
 函 数 名  : 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));

}
Пример #4
0
MAILBOX_LOCAL long mailbox_request_channel(
	struct mb *mb,
	struct mb_buff ** mb_buf,
	unsigned long mailcode)
{
	struct mb_head		 *head	= MAILBOX_NULL;
	struct mb_queue 	 *queue = MAILBOX_NULL;
	struct mb_buff		 *mbuff = MAILBOX_NULL;
	long ret_val = MAILBOX_OK;

	mailbox_dpm_device_get();

	*mb_buf = MAILBOX_NULL;
	mbuff = mailbox_get_channel_handle(mb, mailcode);
	if (MAILBOX_NULL == mbuff) {
		ret_val = MAILBOX_ERRO;
		goto request_erro;
	}

	/*通过判断通道保护字,检查通道有没有初始化*/
	head = (struct mb_head*)mbuff->config->head_addr;
	if ((  (MAILBOX_PROTECT1 != head->ulProtectWord1) )
		|| (MAILBOX_PROTECT2 != head->ulProtectWord2)
		||(MAILBOX_PROTECT1 != head->ulProtectWord3)
		|| (MAILBOX_PROTECT2 != head->ulProtectWord4)) {
#if 1/*k3 modify 保护字不正确重新初始化一下邮箱头,不要return影响通信流程,后续再找根因*/
		/*保护字不正确,说明邮箱未初始化,或者内存被踩,报错。*/
		/* do not check cause hifi maybe not pwr on when the first ipc message send */

		mailbox_init_mem(mbuff->config);

		mailbox_logerro_p1(MAILBOX_NOT_READY, mailcode);
#endif
	}

	if(mailbox_get_src_id(mailcode) == mb->local_id) {
		/* 不允许在中断中发邮件*/
		if (MAILBOX_TRUE == mailbox_int_context()) {
//TODO:接下来的开发(IFC for 低功耗)可能需要支持在中断中发送邮件,这里就需要锁中断。
			ret_val = mailbox_logerro_p1(MAILBOX_ERR_GUT_SEND_MAIL_IN_INT_CONTEXT, mailcode);
			goto request_erro;
		} else {
			if (MAILBOX_OK != mailbox_mutex_lock(&mbuff->mutex)) {
				/*非中断发送,需要资源保护,获取当前通道资源。*/
				ret_val = mailbox_logerro_p1(MAILBOX_CRIT_GUT_MUTEX_LOCK_FAILED, mailcode);
				goto request_erro;
			}
		}
	}

	mbuff->mailcode = mailcode;

	/*共享内存队列,需要依据邮箱头信息对队列操作符进行填充*/
	queue = &mbuff->mail_queue;
	queue->front = queue->base + head->ulFront * sizeof(unsigned long);
	queue->rear  = queue->base + head->ulRear * sizeof(unsigned long);

	mbuff->mb = mb;
	*mb_buf = mbuff;
	return MAILBOX_OK;
request_erro:
	mailbox_out(("###mailbox_request_channel ERR! \n"));
	mailbox_dpm_device_put();
	return ret_val;
}