RAW-OS之RAW_QUEUE测试代码执行过程

1.进入main()函数 ,  代码及注释如下:
int main(int argc, char * argv[])
{
    VCInit();
    start_vc_timer(1000 / RAW_TICKS_PER_SECOND);
    /*初始化raw_os*/
    raw_os_init();
    /*创建了5个任务 , 调到 步骤2*/
    queue_test2();
    /*启动os , 其中在每次的时钟节拍中断都会触发任务0进行处理 , 在任务0的执行函数的最后会执行调度给其它任务 , 切换到"task1"的处理函数driver_send_task  ,跳到 步骤3*/
    raw_os_start();
    return 0;
}

2.调用queue_test2()创建5个任务 ,  代码及注释如下:
void queue_test2()
{
    if (test_started) {
        return;
    }
    test_started = 1;
    /*该任务用于创建3个queue(driver_queue , app_queue和app_queue2) , 该任务的处理函数为driver_send_task (参考 步骤3)*/
    raw_task_create(&test_queue_obj1[1], (RAW_U8  *)"task1", 0,
                             2, 0,  test_queue_stack11,
                             TEST_TASK_STK_SIZE ,  driver_send_task, 1);
    /*该任务用于接收从队列driver_queue接收到的消息并传递给队列app_queue和app_queue2 (参考 步骤7)*/
    raw_task_create(&test_queue_obj1[2], (RAW_U8  *)"task2", 0,
                             11, 10,   test_queue_stack22,
                             TEST_TASK_STK_SIZE ,   net_receive_task, 1);
    /*该任务用于接收app_queue的消息并打印出来(参考 步骤9)*/
    raw_task_create(&test_queue_obj1[3], (RAW_U8  *)"task3", 0,
                             12, 10,   test_queue_stack33,
                             TEST_TASK_STK_SIZE ,  app_receive_task1, 1);
    /*该任务用于接收app_queue2的消息并打印出来(参考 步骤10)*/
    raw_task_create(&test_queue_obj1[4], (RAW_U8  *)"task4", 0,
                             13, 10,   test_queue_stack44,
                             TEST_TASK_STK_SIZE ,  app_receive_task2, 1);     
}
返回到 步骤1.

3.调用driver_send_task(void * pParam) , 代码及注释如下:

void driver_send_task(void * pParam)
{    
    msg1 = 0x188;
    msg2 = 0x189;
    msg3 = 0x18a;
    msg4 = 0x18b;
    msg5 = 0x18c;
    /*创建3个queue , 其中driver_queue , app_queue用于… , app_queue2用于…  .跳到 步骤4*/
    raw_queue_create(&driver_queue, "driver_queue", (RAW_VOID **)queue1_storge, 1000);
    raw_queue_create(&app_queue, "driver_queue", (RAW_VOID **)queue2_storge, 2000);
    raw_queue_create(&app_queue2, "driver_queue", (RAW_VOID **)queue3_storge, 2000);
    while(1) {
        /*把消息地址们插到队列里 , 使用FIFO方式 , 跳到 步骤5*/
        raw_queue_end_post(&driver_queue, &msg1);
        raw_queue_end_post(&driver_queue, &msg2);
        raw_queue_end_post(&driver_queue, &msg3);
        raw_queue_end_post(&driver_queue, &msg4);
        raw_queue_end_post(&driver_queue, &msg5);
        watch_number++;
        /*睡眠1个时钟节拍 , 这时会切换到"task2"执行 , 跳到 步骤7*/
        raw_sleep(1);
    }
}


4.创建一个queue ,  代码及注释如下:

RAW_U16 raw_queue_create(RAW_QUEUE *p_q, RAW_U8 *p_name, RAW_VOID **msg_start, RAW_U32 number)
{
    #if (RAW_QUEUE_FUNCTION_CHECK > 0)
    if (p_q == 0) {
        return RAW_NULL_OBJECT;
    }
    if ( msg_start == 0) {
        return RAW_NULL_POINTER;
    }
    if (number == 0) {
        return RAW_ZERO_NUMBER;
    }
    #endif
    /*初始化消息队列的阻塞链表*/
    list_init(&p_q->common_block_obj.block_list);
    /*以下填充该消息队列的控制块*/                             
    p_q->common_block_obj.name = p_name;   
    p_q->common_block_obj.block_way = RAW_BLOCKED_WAY_PRIO;
    /*赋消息队列起始地址*/
    p_q->msg_q.queue_start         = msg_start;
    /*赋消息队列结束地址*/        
    p_q->msg_q.queue_end        = &msg_start[number];
    /*赋消息队列的可写地址*/
    p_q->msg_q.write            = msg_start;
    /*赋消息队列的可读地址*/
    p_q->msg_q.read             = msg_start;
    /*赋消息队列的最大消息数*/
    p_q->msg_q.size                = number;
    /*赋当前存在的消息数*/
    p_q->msg_q.current_numbers  = 0;
    /*赋调试信息*/
    p_q->msg_q.peak_numbers        = 0;
    /*赋通告函数*/
    p_q->queue_send_notify      = 0;
    /*赋工程类型*/
    p_q->common_block_obj.object_type = RAW_QUEUE_OBJ_TYPE;
    return RAW_SUCCESS;
}
返回到步骤3 .

5. 调用raw_queue_end_post(RAW_QUEUE *p_q, RAW_VOID *p_void)发送消息到p_q消息队列,采用FIFO方式 , 并且唤醒一个任务, 源码及注释如下:

//发送消息给p_q , 使用FIFO  , 只唤醒最高优先级的任务
RAW_U16 raw_queue_end_post(RAW_QUEUE *p_q, RAW_VOID *p_void)
{
    #if (RAW_QUEUE_FUNCTION_CHECK > 0)
    if (p_q == 0) {
        return RAW_NULL_OBJECT;
    }
    if (p_void == 0) {
        return RAW_NULL_POINTER;
    }
    #endif
    if (p_q->common_block_obj.object_type !=  RAW_QUEUE_OBJ_TYPE) {
        return RAW_ERROR_OBJECT_TYPE;
    }
    #if (CONFIG_RAW_ZERO_INTERRUPT > 0)
    if (raw_int_nesting) {
        return int_msg_post(RAW_TYPE_Q_END, p_q, p_void, 0, 0, 0);
    }
    #endif
    //把消息p_void插入到消息队列的尾部 , 唤醒一个任务
    return msg_post(p_q, p_void,  SEND_TO_END, WAKE_ONE_QUEUE);
}
RAW_U16 msg_post(RAW_QUEUE *p_q, RAW_VOID *p_void, RAW_U8 opt_send_method, RAW_U8 opt_wake_all)             
{
    LIST *block_list_head;
     RAW_SR_ALLOC();
    /*取出阻塞任务的链表头*/
    block_list_head = &p_q->common_block_obj.block_list;
    RAW_CRITICAL_ENTER();
    /*如果当前消息数已经达到队列最大值 , 返回*/
    if (p_q->msg_q.current_numbers >= p_q->msg_q.size) {  
        RAW_CRITICAL_EXIT();
        return RAW_MSG_MAX;
    }
    if (is_list_empty(block_list_head)) {        
        /*如果没有阻塞任务 , 执行以下任务*/
        
        /*当前消息数加一*/
        p_q->msg_q.current_numbers++;                                
        if (p_q->msg_q.current_numbers > p_q->msg_q.peak_numbers) {
            p_q->msg_q.peak_numbers = p_q->msg_q.current_numbers;
        }
        /*选择FIFO插入消息 */
        if (opt_send_method == SEND_TO_END)  {
             *p_q->msg_q.write,
            *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;
            }   
        }
        /*选择LIFO插入消息*/
        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;                               
        }
        RAW_CRITICAL_EXIT();
        /*如果queue注册了notify funtion , 则调用它*/
        if (p_q->queue_send_notify) {
            p_q->queue_send_notify(p_q);    
        }
        /*成功返回*/
        return RAW_SUCCESS;
    }
    /*如果是有阻塞任务 , 则不应该执行上面的插入消息*/
    if (opt_wake_all) {  /*如果唤醒方式是唤醒所有阻塞任务*/
        while (!is_list_empty(block_list_head)) {
            /*唤醒所有任务 , 跳到步骤6*/
            wake_send_msg(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list),  p_void);    
        }
    }
    /*唤醒最高优先级的阻塞任务并且发送消息给它*/
    else {
        wake_send_msg(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list),  p_void);    
    }
    RAW_CRITICAL_EXIT();
    /*执行一次调度器*/
    do_possible_sche();    
    return RAW_SUCCESS;
}
返回到 步骤3.

6.调用wake_send_msg(...)唤醒阻塞中的任务并发送消息 , 源码及注释如下:

RAW_U16 wake_send_msg(RAW_TASK_OBJ *task_ptr, RAW_VOID *msg)
{

    return internal_wake_send(task_ptr, msg, 0);                                                                
}
/*该函数指定唤醒任务控制块*task_ptr ,  消息指针msg , 消息大小size*/
static RAW_U16 internal_wake_send(RAW_TASK_OBJ *task_ptr, RAW_VOID *msg, RAW_U32 size)                                                                    
{
    /*根据任务的当前状态来唤醒任务*/
    switch (task_ptr->task_state) {
        
        case RAW_PEND:
        case RAW_PEND_TIMEOUT:
            /*从对应资源阻塞链表摘除*/
            list_delete(&task_ptr->task_list);
                      /*插入到就绪链表*/    
            add_ready_list(&raw_ready_queue, task_ptr);
            /*任务状态改为就绪态*/
            task_ptr->task_state = RAW_RDY;
            break;

        case RAW_PEND_SUSPENDED:
        case RAW_PEND_TIMEOUT_SUSPENDED:
            list_delete(&task_ptr->task_list);                   
            /*状态改回挂起态*/
            task_ptr->task_state = RAW_SUSPENDED;
            break;

        default:
            #if (CONFIG_RAW_ASSERT > 0)
            RAW_ASSERT(0);
            #endif
            return RAW_OBJ_INVALIDATE_STATE;
    }
    /*如果该任务是超时阻塞 , 把阻塞任务从超时链表摘除*/
    tick_list_remove(task_ptr);
    //把消息地址赋给task_ptr->msg .
    task_ptr->msg = msg;
    #if (CONFIG_RAW_QUEUE_SIZE > 0)
    if (size) {  //如果有指定长度 , 则赋给task_ptr->msg_size
        task_ptr->msg_size = size;
    }
    #endif
    /*修改阻塞状态  ,改成成功获取到资源*/
    task_ptr->block_status = RAW_B_OK;  
    /*阻塞类型标志清零置为0,表示无阻塞*/
    task_ptr->block_obj = 0;
    return RAW_SUCCESS;
}
返回到 步骤5.

7.调用net_receive_task处理函数来接收driver_queue消息队列里的消息 , 并投递给队列app_queue和app_queue2 . 源码及注释如下:

void  net_receive_task(void * pParam)
{    
    void *msg_app1;
    void *msg_app2;
    void *msg_app3;
    void *msg_app4;
    void *msg_app5;
    while(1)
    {        
               /*从driver_queue接收消息 , 并选择一直等到有消息为止 , 跳到 步骤8*/
        raw_queue_receive (&driver_queue, RAW_WAIT_FOREVER, &msg_app1);
        /*把接收到的消息发传递给消息队列app_queue和app_queue2 ,因为这两个的级别比该任务低,所有没有切换*/
        raw_queue_end_post(&app_queue, msg_app1);
        raw_queue_end_post(&app_queue2, msg_app1);
        /*接收第二条消息*/
        raw_queue_receive (&driver_queue, RAW_WAIT_FOREVER, &msg_app2);
        raw_queue_end_post(&app_queue, msg_app2);
        raw_queue_end_post(&app_queue2, msg_app2);
        /*接收第三条消息*/
        raw_queue_receive (&driver_queue, RAW_WAIT_FOREVER, &msg_app3);
        raw_queue_end_post(&app_queue, msg_app3);
        raw_queue_end_post(&app_queue2, msg_app3);
        /*接收第四条消息*/
        raw_queue_receive (&driver_queue, RAW_WAIT_FOREVER, &msg_app4);
        raw_queue_end_post(&app_queue, msg_app4);
        raw_queue_end_post(&app_queue2, msg_app4);
        /*接收第五条消息*/
        raw_queue_receive (&driver_queue, RAW_WAIT_FOREVER, &msg_app5);
        raw_queue_end_post(&app_queue, msg_app5);
        raw_queue_end_post(&app_queue2, msg_app5);
    }
}

8.调用raw_queue_receive(...)获取消息 , 源码及注释如下:

RAW_U16 raw_queue_receive(RAW_QUEUE *p_q, RAW_U32 wait_option, RAW_VOID **msg)
{
    RAW_VOID *pmsg;
    RAW_U16 result;
    RAW_SR_ALLOC();
    #if (RAW_QUEUE_FUNCTION_CHECK > 0)
    if (raw_int_nesting) {
        return RAW_NOT_CALLED_BY_ISR;
    }
    if (p_q == 0) {
        return RAW_NULL_OBJECT;
    }
    if (msg == 0) {
        return RAW_NULL_POINTER;
    }
    #endif
    if (p_q->common_block_obj.object_type !=  RAW_QUEUE_OBJ_TYPE) {
        return RAW_ERROR_OBJECT_TYPE;
    }
    RAW_CRITICAL_ENTER();

    if (p_q->msg_q.current_numbers) {
    /*如果该队列有消息 , 执行该函数体*/
        
        pmsg = *p_q->msg_q.read++; //取出读指针 , 把读指针加一                    
        if (p_q->msg_q.read == p_q->msg_q.queue_end) { //如果该读指针已经到达队列尾部 , 就重新切换到队列开始处
            p_q->msg_q.read = p_q->msg_q.queue_start;
        }
        *msg = pmsg;  //取出该消息,存放到msg形参里 , 作为返回
        p_q->msg_q.current_numbers--;  //把当前消息数减一
        RAW_CRITICAL_EXIT();        
        return RAW_SUCCESS;          //直接返回
    }
    if (wait_option == RAW_NO_WAIT) {   
    /*如果没有消息可取 , 并不执行等待,执行该函数体*/
        *msg = (RAW_VOID *)0;    //把0赋给消息内容
        RAW_CRITICAL_EXIT();      //退出
        return RAW_NO_PEND_WAIT;
    }
    /*如果系统不允许调度 , 则不允许阻塞 , 也是退出*/
    SYSTEM_LOCK_PROCESS_QUEUE();
    /*把当前运行的任务阻塞到p_q队列里*/
    raw_pend_object((RAW_COMMON_BLOCK_OBJECT  *)p_q, raw_task_active, wait_option);
    RAW_CRITICAL_EXIT();  
    raw_sched();    //执行一次调度 ,如果task1睡眠超时了,就需要调度过去执行task1 .
    *msg      = (RAW_VOID      *)0;
    /*阻塞结束后会调用该函数来获取任务师父正确获得消息 , 是的话要把消息存入*msg ,并返回状态*/
    result = block_state_post_process(raw_task_active, msg);
    return result;
}
返回到 步骤7.

9.调用app_receive_task1接收app_queue消息 , 源码及注释如下:

void app_receive_task1(void * pParam)
{    
    int *data1;
        int *data2;
            int *data3;
                int *data4;
                    int *data5;
    while(1)
    {        
        /*接收app_queue的消息 ,并打印出来*/
        raw_queue_receive (&app_queue, RAW_WAIT_FOREVER, &data1);
        vc_port_printf("data1 is %s\n",data1);
        raw_queue_receive (&app_queue, RAW_WAIT_FOREVER, &data2);
        vc_port_printf("data2 is %s\n",data2);
        raw_queue_receive (&app_queue, RAW_WAIT_FOREVER, &data3);
        vc_port_printf("data3 is %s\n",data3);
        raw_queue_receive (&app_queue, RAW_WAIT_FOREVER, &data4);
        vc_port_printf("data4 is %s\n",data4);
        raw_queue_receive (&app_queue, RAW_WAIT_FOREVER, &data5);
        vc_port_printf("data5 is %s\n",data5);
    }
}
10 .调用app_receive_task2接收app_queue2的消息 , 源码及注释如下:

void app_receive_task2(void * pParam)
{    
    int *data1;
        int *data2;
            int *data3;
                int *data4;
                    int *data5;
    while(1)
    {        
        /*接收app_queue2的消息 ,并打印出来*/
        raw_queue_receive (&app_queue2, RAW_WAIT_FOREVER, &data1);
        vc_port_printf("data1 is %s\n",data1);
        raw_queue_receive (&app_queue2, RAW_WAIT_FOREVER, &data2);
        vc_port_printf("data2 is %s\n",data2);
        raw_queue_receive (&app_queue2, RAW_WAIT_FOREVER, &data3);
        vc_port_printf("data3 is %s\n",data3);
        raw_queue_receive (&app_queue2, RAW_WAIT_FOREVER, &data4);
        vc_port_printf("data4 is %s\n",data4);
        raw_queue_receive (&app_queue2, RAW_WAIT_FOREVER, &data5);
        vc_port_printf("data5 is %s\n",data5);
    }
}



你可能感兴趣的:(RTOS之RAW-OS)