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);
}
}