[转载]DSP_5_DSP/BIOS_例程分析_同优先级用户任务切换

标签:
转载 |
分类: DSP |
这是在网上找的一个DSP/BIOS同优先级任务切换的例程。
CPU是DM642。用CCS3.3软件仿真。
在Configuration里添加了三个用户任务TSK0~2,优先级都设为1,任务处理函数都设为task,任务参数(task
代码:
#include <std.h>
#include <log.h>
#include <sys.h>
#include "switestcfg.h"
Void main()
{
}
Void task(Arg id_arg)
{
LOG_printf(&trace, "start %d", id);
}
}
本例中main函数为空。
在所有DSP/BIOS模块初始化之后,调用main函数。此时硬件中断和软件中断都是禁止的。然后程序开始执行任务函数。
首先TSK0调用task函数,任务号id=0,在trace窗口中显示start0,然后进入for循环,
又执行语句LOG_printf(&trace, "Loop %d: Task %d Working", i, id);
i=0,trace窗口显示Loop 0:Task 0 Working
TSK_yield函数将TSK0挂起,任务切换到TSK1。
TSK1也调用task函数,任务号id=1,在trace窗口中显示start1,然后也进入for循环,i=0,trace窗口显示Loop 0:Task 1 Working
TSK_yield函数将TSK1挂起,任务切换到TSK2。
TSK1还调用task函数,任务号id=2,在trace窗口中显示start2,然后也进入for循环,i=0,trace窗口显示Loop 0:Task 2 Working
TSK_yield函数将TSK2挂起,任务循环切换回到TSK0。
TSK0第二次调用task函数,这时下面三条语句
Int
Int
LOG_printf(&trace, "start %d", id);
就不再执行了。
且在for循环中i=0的情况也不再执行了。
因为TSK0第一次执行的时候那三条语句和for循环中i=0的情况都已经执行过了,TSK0被切换的时候这个任务并没有执行完毕也不是被停止,而是被暂时挂起,就相当于在TSK0被切换的时候自动记忆了一个断点,当再次执行TSK0的时候,这个任务就从上次的那个断点出开始继续往下执行。
所以TSK0再次开始执行的时候 i++
i=1, trace窗口显示Loop 1:Task 0 Working
TSK_yield函数再次将TSK0挂起,任务切换到TSK1。
同理TSK1再次开始执行的时候i++
i=1, trace窗口显示Loop 1:Task 1 Working
TSK_yield函数再次将TSK1挂起,任务切换到TSK2。
同理TSK2再次开始执行的时候i++
i=1, trace窗口显示Loop 1:Task 2 Working
TSK_yield函数将TSK2挂起,任务再次循环切换回到TSK0。
如此循环······
TSK0在i=5时跳出for循环执行最后一条语句LOG_printf(&trace, "Task %d DONE", id);
Trace窗口显示Task 0 DONE
TSK1在i=5时跳出for循环
Trace窗口显示Task 1 DONE
TSK2在i=5时跳出for循环
Trace窗口显示Task 2 DONE
所以message log中的整体显示如下
在Execution
Graph中看起来会更直观一些http://s4/middle/533d3f4fhbb07d5facc43&690
在这个图中发现一个问题,显示TSK0~2每个任务都执行了六次,但是for循环中i只设置了五个值,这是因为在i=5时虽然跳出了for循环,但是继续执行下一条语句LOG_printf(&trace, "Task %d DONE", id);也就相当于i从0加到5一共六个值,每个i值TSK0~2都有执行,所以从0到5一共六次。
左上角还有个KNL_swi 是一个软中断,查看其属性如下图:http://s9/middle/533d3f4fhbb07d5fc9bf8&690
他的作用是中断访问TSK调度程序,程序一开始运行Other Thread,我想大概是一些初始化的线程,然后运行软中断KNL_swi使用户建立的任务都不执行,KNL-swi结束后才能开始执行TSK-Task Manager中用户建立的TSK0~2。当TSK0~2全部都结束后,KNL_swi与Other Thread交替执行。
从Execution Graph
Details中的数据能看出TSK_idle