嵌入式操作系统内核原理和开发(消息队列)

发表于:2012-9-27 09:42

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:feixiaoxing    来源:51Testing软件测试网采编

  虽然相比较之前的互斥函数,消息队列的初始化内容好像多一些。但是大家如果对循环队列的知识比较了解的话,其实也不是很复杂的。我们看到,函数除了对通用阻塞结构进行初始化之外,就是对这些循环队列进行初始化。接着,我们就可以看看消息发送函数是怎么样的,

static RAW_U16 internal_msg_post(RAW_QUEUE *p_q, RAW_VOID *p_void,  RAW_U8 opt_send_method, RAW_U8 opt_wake_all, RAW_U32 wait_option)            
  {
   RAW_U16 error_status;
   LIST *block_list_head;
   RAW_U8 block_way;
   
    RAW_SR_ALLOC();
 
   #if (RAW_QUEUE_FUNCTION_CHECK > 0)
 
   if (raw_int_nesting) {
 
    if (wait_option != RAW_NO_WAIT) {
     
     return RAW_NOT_CALLED_BY_ISR;
    }
   }
 
   if (p_q == 0) {
    
    return RAW_NULL_OBJECT;
   }
   
   if (p_void == 0) {
    
    return RAW_NULL_POINTER;
   }
   
   #endif
 
   block_list_head = &p_q->common_block_obj.block_list;
   
   RAW_CRITICAL_ENTER();
 
   /*queue is full condition, there should be no received task blocked on queue object!*/
   if (p_q->msg_q.current_numbers >= p_q->msg_q.size) { 
 
    if (wait_option  == RAW_NO_WAIT) {
     RAW_CRITICAL_EXIT();
     return RAW_MSG_MAX;
    }
 
    else {
     
     /*system is locked so task can not be blocked just return immediately*/
     if (raw_sched_lock) {  
      RAW_CRITICAL_EXIT(); 
      return RAW_SCHED_DISABLE;   
     }
     /*queue is full and  SEND_TO_FRONT  method is not allowd*/
     if (opt_send_method == SEND_TO_FRONT) {
 
      RAW_CRITICAL_EXIT(); 
      return RAW_QUEUE_FULL_OPT_ERROR; 
     }
 
     p_q->msg_q.blocked_send_task_numbers++;
     raw_task_active->msg = p_void;
     block_way = p_q->common_block_obj.block_way;
     p_q->common_block_obj.block_way = RAW_BLOCKED_WAY_FIFO;
     /*there should be no blocked received task beacuse msg exits*/
     raw_pend_object(&p_q->common_block_obj, raw_task_active, wait_option);
     p_q->common_block_obj.block_way = block_way;
     
     RAW_CRITICAL_EXIT();
 
     raw_sched();
     
     error_status = block_state_post_process(raw_task_active, 0);
 
     return error_status;  
     
    }
 
   }
 
   /*Queue is not full here, there should be no blocked send task*/ 
   /*If there is no blocked receive task*/
   if (is_list_empty(block_list_head)) {       
 
    p_q->msg_q.current_numbers++;                                 /* Update the nbr of entries in the queue        */
    
    if (opt_send_method == SEND_TO_END)  {
 
     *p_q->msg_q.write++ = p_void;                             
 
     if (p_q->msg_q.write == p_q->msg_q.queue_end) {  
      
      p_q->msg_q.write = p_q->msg_q.queue_start;
      
     }  
 
    }
 
    else {
 
     if (p_q->msg_q.read == p_q->msg_q.queue_start) {             
            p_q->msg_q.read = p_q->msg_q.queue_end;
        }
     
     p_q->msg_q.read--;
     *p_q->msg_q.read = p_void;                               /* Insert message into queue                     */
     
    }
    
    RAW_CRITICAL_EXIT();
    
    return RAW_SUCCESS;
   }
 
   /*wake all the task blocked on this queue*/
   if (opt_wake_all) {
 
    while (!is_list_empty(block_list_head)) {
     wake_send_msg(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list),  p_void); 
    }
    
    p_q->msg_q.blocked_receive_task_numbers = 0;
   }
   
   /*wake hignhest priority task blocked on this queue and send msg to it*/
   else {
    
    wake_send_msg(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list),  p_void); 
    p_q->msg_q.blocked_receive_task_numbers--;
   }
   
   RAW_CRITICAL_EXIT();
 
   raw_sched();   
   return RAW_SUCCESS;
  }
 

  这里消息发送函数稍显冗长,这主要是因为消息发送的情况比较复杂,方方面面考虑的情况比较多。但是整个函数处理的逻辑还是比较清晰的,只要有耐心,慢慢读下去还是没有什么问题。这里不妨和大家一起看一下消息发送函数是怎么实现的,

  (1)检验参数合法性,注意在中断下调用这个函数时,必须是RAW_NO_WAIT的选项,中断毕竟是不好调度的;

  (2) 处理消息已满的情况,

    a)如果线程不想等待,函数返回;

    b)如果禁止调度,函数返回;

    c)消息存储到线程的msg里面,线程把自己pend到等待队列中;

    d)调用系统调度函数,等待再次被调度的机会,函数返回。

42/4<1234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号