基于tc1767平台的csa节点管理器的实现方法

文档序号:6397611阅读:735来源:国知局
专利名称:基于tc1767平台的csa节点管理器的实现方法
技术领域
本发明涉及微控制器的操作系统,特别涉及一种基于TC1767平台的CSA节点管理器的实现方法。
背景技术
TC1767型芯片为英飞凌公司开发的一款基于TriCore架构的汽车用32位微控制器(MCU),TC1767可作为汽车的核心CPU使用。TriCore架构使用链表结构的CSA(ContextSave Area,上下文保存区域)作为保存上下文的区域,以实现中断、陷阱以及函数调用时产生的上下文切换。由于芯片本身的限制,现有的运行于TC1767芯片上的操作系统,还无法实现任务的切换,以及多任务的处理。

发明内容
本发明针对现有基于TC1767芯片的操作系统无法进行任务切换和多任务处理的缺点,提供了一种通过在现有操作系统中建立和引入一个全新的CSA节点管理器的方法来实现任务切换功能的基于TC1767平台的CSA节点管理器的实现方法。为实现上述目的,本发明可采取下述技术方案
基于TC1767平台的CSA节点管理器的实现方法,包括以下具体步骤为每个任务分别建立CSA链表,所述任务与所述CSA链表之间——对应,所述CSA链表包括FCL和PCL ;切换所述CSA链表为当前CSA链表以实现任务切换。作为优选,所述为每个任务分别建立CSA链表的步骤在TC1767上电后,第一个任务启动之前立即执行。作为优选,在所述建立CSA链表的过程中,保留一定数目的节点,所述保留的节点数目由SYS_START_USED确定。作为优选,还包括,在所述任务第一次执行前对所述CSA链表进行初始化,具体步骤为1)将所述任务的PCL的所有节点插入所述任务的FCL中;2)从FCL中取出两个节点分别为第一节点和第二节点,所述第一节点作为上部上下文储存区域,将所述任务的堆栈指针的值写入所述第一节点的SP子域,所述第二节点作为下部上下文储存区域,将所述任务的入口地址写入所述第二节点的RA子域;3)将所述第一节点以头插法插入所述PCL ;4)将所述第二节点以头插法插入所述PCL。作为优选,所述CSA链表的节点数目为预设值。作为优选,还包括,在所述任务的FCL耗尽后,增加所述CSA链表的节点数目。作为优选,所述任务包括IDLE任务。作为优选,所述任务的TCB包括以下成员变量TPcxCur、TFcxCur> TPcxOrig、TFcxOrig、TLcxOrig,所述成员变量用于保存所述CSA链表的句柄,其中,TPcxCur用于保存当前PCL的首节点地址,TFcxCur用于保存当前FCL的首节点地址,TPcxOrig用于保存初始PCL的首节点地址,TFcxOrig用于保存初始FCL的首节点地址,TLcxOrig用于保存初始FCL的尾节点地址。本发明由于采用了以上技术方案,具有显著的技术效果
引入了一个新的CSA节点管理器,该CSA节点管理器是由每一个任务的CSA链表以及对这些CSA链表的切换或者其他处理步骤所组成的,由于CSA节点管理器的引入,在基于TC1767平台的操作系统上实现了任务切换。任务切换的功能是通过切换与任务相对应的CSA链表所实现的,而切换CSA链表只需要修改TC1767芯片中的上下文寄存器即可实现,因此切换过程所消耗的CPU周期较少,CSA链表切换十分迅速。


图1为所述CSA链表的结构示意图。
具体实施例方式下面结合实施例对本发明作进一步的详细描述。实施例1
基于TC1767平台的CSA节点管理器的实现方法,使用基于TriCore架构的TC1767芯片,TriCore架构使用链表结构的CSA节点。每个CSA节点都是16字的内存区域,16字对齐。每个CSA节点刚好可以保存一个上部或者下部上下文。CSA节点通过一个链接字首尾链接形成CSA链表。链接字有2个域4位的段索引和16位的偏移量,可以通过这两个域来生成下一个CSA的EA。每个段可以用作CSA的区域是4MB,所以可有216个CSA节点。CSA链表的结构如图1所示,此外,TC1767芯片还包括3个上下文管理寄存器,分别为FCX、PCX和LCX,其中,FCX寄存器指向可用的空闲上下文链表(FCL :Free Context List),即保存FCL首节点的地址,PCX寄存器指向已使用的非空闲上下文链表(PCL Previous ContextList),即保存PCL的首节点的地址,LCX寄存器保存FCL尾节点的地址。所述的CSA节点管理器通过以下具体步骤实现为每个任务分别建立CSA链表,更进一步的,所述任务也包括IDLE任务,即系统的空闲任务,所述任务与所述CSA链表之间一一对应,所述CSA链表包括FCL和PCL ;切换所述CSA链表为当前CSA链表以实现任务切换。为每个任务分别建立CSA链表的代码实现如下,函数initAlITaskCSAs O负责为包括IDLE任务在内的所有任务建立CSA链表,以下代码也可以在TC1767启动后,第一个任务之前立即执行。此时,在执行时,需要保留一部分的CSA节点,这部分保留的CSA节点即可以用于FCL的节点耗尽后,增加FCL的节点数目,同时,由于在第一个任务被执行之前,也会随机执行代码,需要为这些代码保留一部分的CSA节点。保留的CSA节点的数目由SYS_START_USED确定,SYS_START_USED的值可以在源代码中设定或者在操作系统启动时从相应的配置文件中读取
boolean initAllTaskCSAs O{
int csaldx, taskldx;
TaskType curTask; unsignedint cfcx, clcx;unsignedint tCsaCnt;
cfcx = _mfcr (FCX) ; /* 获得 CPU 的 FCX 句柄 */ clcx = _mfcr (LCX) ; /* 获得 CPU 的 LCX 句柄 */
/*预留一些CSA节点,用于当前代码到第一个任务启动的过程*/for(csaIdx = O; csaldx< SYS_START_USED ; csaldx++)/*SYS_START_USED为当前代码到第一个任务启动过程中所需要的CSA节点的数目*/
{
if (EquelUint32 (cfcx, clcx)) /* 这里会发生 Trap,不会执行到 */
{
return FALSE;
}
cfcx = getCsaLink( getEffectiveAddress ( cfcx ) );/* 获得下一个CSA节点的有效地址RA,作为当前FCL的句柄*/
}
curTask = OSTCBTbl; /*获得任务TCB数组的句柄*/ for (taskldx = O; taskldx< TASK_NUM; taskldx++)/* 为 TCB 数组中的每个TCB循环执行以下代码,TASK_NUM为TCB的数目*/
{
tCsaCnt = curTask->CsaCnt; /*从任务TCB中获得当前任务配置的CSA
节点的数目*/
curTask->TFcxOrig = cfcx; /*初始化这个任务的FCL的句柄*/ curTask->TPcxOrig = 0;/*初始化这个任务的PCL的句柄*/
/*为这个任务分配CSA节点*/
for (csaldx = O; csaIdx〈tCsaCnt ; csaldx++)/* 此处进行循环以生成
CSA链表*/
{
if (EquelUint32 (cfcx, clcx)) /* 当返回值为 true,表不 FCL 中的节点已经用尽,将引发trap,因此,条件体事实上不会被执行*/
{
return FALSE;
}
cfcx = getCsaLink( getEffectiveAddress ( cfcx ) );/*获得下一个节点的有效地址RA*/
}
curTask->TLcxOrig = cfcx ;/* 初始化这个任务的 TLcxOrig */ curTask ++; /*处理下一个任务*/
}
return TRUE; /* 成功执行,返回 TRUE*/
}o
为了实现CSA链表的切换,需要在任务的TCB中添加下列的成员变量TPcxCur、TFcxCur> TPcxOrig、TFcxOrig、TLcxOrig,所述成员变量用于保存所述CSA链表的句柄,其中,TPcxCur用于保存当前PCL的首节点地址,TFcxCur用于保存当前FCL的首节点地址,TPcxOrig用于保存初始PCL的首节点地址,TFcxOrig用于保存初始FCL的首节点地址,TLcxOrig用于保存初始FCL的尾节点地址。这里的初始PCL和初始FCL是指对CSA链表进行增删操作之前的FCL和PCL的句柄。在所述任务第一次执行前需要对该任务的CSA链表进行初始化,具体步骤为1)将所述任务的PCL的所有节点插入所述任务的FCL中;2)从FCL中取出两个节点分别为第一节点和第二节点,所述第一节点作为上部上下文储存区域,将所述任务的堆栈指针的值写入所述第一节点的SP子域,所述第二节点作为下部上下文储存区域,将所述任务的入口地址写入所述第二节点的RA子域;3)将所述第一节点以头插法插入所述PCL ;4)将所述第二节点以头插法插入所述PCL,伪代码如下
void TCsaInit(TaskType PTCB)
{
·把PCL中未释放的CSA节点释放,即把TPcxCur上的所有节点头删法删掉,然后头插法插入到 TFcxCur 中,这样之后也就保证了 TPcxCur == TPcxOrig, TFcxCur == TFcxOrig;
从TFcxOrig取出一个节点,作为上部上下文存储区域,初始化这个区域,并指定区域中SP子域(Stack Pointer,栈指针)的值为任务的栈指针值,头插法插入到TPcxCur中;从TFcxOrig再次取出一个节点,作为下部上下文存储区域,初始化这个区域,并指定区域中RA子域(Return Address,返回地址)的值为任务的入口地址,头插法插入到TPcxCur 中;
Io上述TCsaInitO的可以由以下代码实现 voidTCsalnit(TaskType Task)
{
unsignedintupCsaEa, IoCsaEa; /^upCsaEa, IoCsaEa 分别为上部上下文和下部上下文的有效地址*/
unsignedintcfcx, cpcx;/*cfcx, cpcx 为 FCL 的句柄或者 PCL 的句柄 */ cfcx = Task->TFcx0rig;/*get task’s fcx*//* 获得任务的 FCL 句柄 */ cpcx = Task->TPcx0rig;/*get task’s pcx*//* 获得任务的 PCL 句柄 */
/*以下代码实现清除PCL的节点并将这些节点插入FCL中*/clearTaskUsedCsa (Task) ; /*把当前任务PCL中所有的节点插入FCL中*/upCsaEa = delCsaNode (&cfcx) ;/*从任务的FCL中取出一个节点,并删除,返回的是节点的有效地址*/
((unsignedint *)upCsaEa) [2] = (uint32) Task->0STCBStkCur;/*初始化上部上下文中的SP子域*/
((unsignedint *)upCsaEa) [3] = (uint32)Task_>PTask;/*初始化上部上下文
中的All*/
((unsignedint *) upCsaEa) [I] = (uint32) 0x00000980 ;/* 初始化上部上下文中的PSW程序状态字*/
addCsaNode (&cpcx,upCsaEa) ;/*把这个节点插入到任务的PCL表头*/IoCsaEa = delCsaNode ( &cfcx );/*从任务的FCL中取出一个节点,并删除,返回的是节点的有效地址*/
((unsignedint *) IoCsaEa) [I] = (uint32)Task_>PTask;/*初始化下部上下文
中的All*/
addCsaNode (&cpcx,IoCsaEa) ;/*把这个节点插入到任务的PCL表头*/ Task->TFcxCur = cfcx;/* 写回到任务的 FCL 句柄 */
Task->TPcxCur = cpcx;/* 写回到任务的 PCL 句柄 */return ;
}o voidcIearTaskUse dCsa (TaskType Task)
{
unsignedintcfcx, cpcx;
unsignedinttmpNode;
cfcx = Task->TFcxCur;
cpcx = Task->TPcxCur;
while (cpcx != 0)/* 任务的 PCL 不为空 */
{
tmpNode = delCsaNode ( &cpcx ) ;/* 从 PCL 中删除一个节点 */ addCsaNode (&cfcx,tmpNode) '卜将上述从PCL中删除的插入FCL中*/
}
Task->TFcxCur = cfcx;/* 写回 */
Task->TPcxCur = cpcx;/* 写回 */ return ;
}o这里,clearTaskUsedCsa ()用于把当前任务PCL中所有的节点插入FCL中。切换任务即切换CSA链表包括以下步骤
保存任务save :保存任务时的任务保存上下文就是保存当前PCX、FCX到被调度出去的任务的 TPcxCur,TFcxCur 中。恢复任务load :恢复任务时的任务恢复上下文就装载被调度进来的任务的TPcxCur, TFcxCur,TLcxOrig 到 CPU 的 PCX,FCX, LCX。执行任务Run :先执行TCsaInit O,然后再执行恢复任务load。实现上述步骤需要以下4个任务切换函数=TaskRun O、TaskSaveRun O、TaskLoadRun O、TaskSaveLoadRun O,伪代码如下
TaskRun O{
TCsaInit O,执行恢复任务load;
}o
TaskSaveRun (PreTCB, CurTCB)
{
TCsaInit () ; TaskSaveLoadRun ();
}oTaskLoadRun (CurTCB)
{
执行恢复任务load; rslcx ();
}oTaskSaveLoadRun(PreTCB, CurTCB)
{
svlcx() ;/*保存下部上下文*/
保存当前 CPU 的 PCX,FCX 到 PreTCB 的 TPcxCur,TFcxCur ;
保存CPU的SP到PreTCB的SP ;
从 CurTCB 加载出 TPcxCur,T`FcxCur,TLcxOrig 到 CPU 的 PCX,FCX, LCX;rslcxO ;
}o上述四个任务切换函数可以由以下代码实现,
inline void TaskSaveLoadRun(TaskType PSavedTcb, TaskType PLoadTcb)
{
—asm(〃svlcx〃);/*保存下部上下文*/
0STCB01d->TFcxCur = _mfcr (FCX) ;/* 保存前一个任务的 FCL 句柄 */0STCB01d->TPcxCur = _mfcr (PCX) ;/* 保存前一个任务的 PCL 句柄 */
_mtcr (FCX, OSTCBCur->TFcxCur) ; /* 装载当前任务的 FCL 句柄到 CPU*/ _mtcr (PCX, OSTCBCur->TPcxCur) ; /* 装载当前任务的 PCL 句柄到 CPU*/
—mtcr (LCX, 0STCBCur->TLcx0rig) ; /* 装载当前任务的 LCX 链表句柄到 CPU*/_mtcr (PCXI, _mfcr (PCXI) & ( (uint32) (I 22))) ;/*设置PCX1. UL = O,表示当前CSA节点为下部上下文节点,PCX1. UL是TC1767芯片的PCXI寄存器的一个域,用于标示当前CSA节点为上部上下文节点还是下部上下文节点*/
—asm(〃rslcx〃);/*恢复下`部上下文*/
_mtcr (PCXI, _mfcr (PCXI) | (uint32) (3 22)) ;/*设置PCX1. UL = 1,表示当前CSA节点为上部上下文节点;设置PCX1. PIE = 1,使得RFE之后能够使能系统中断,PCX1. PIE是PCXI寄存器的一个域,作用是标示中断任务的中断使能位*/
Ioinline void TaskSaveRun(TaskType PSavedTcb, TaskType PLoadTcb)
{
—asm(〃svlcx〃);/*保存下部上下文*/
0STCB01d->TFcxCur = _mfcr (FCX) ;/* 保存前一个任务的 FCL 句柄 */0STCB01d->TPcxCur = _mfcr (PCX) ;/* 保存前一个任务的 PCL 句柄 */_mtcr (FCX, OSTCBCur->TFcxCur) ; /* 装载当前任务的 FCL 句柄到 CPU*/ _mtcr (PCX, OSTCBCur->TPcxCur) ; /* 装载当前任务的 PCL 句柄到 CPU*/
—mtcr (LCX, OSTCBCur->TLcxOrig) ; /* 装载当前任务的 LCX 链表句柄到 CPU*/ _mtcr (PCXI, _mfcr (PCXI) & ( (uint32) (1 22))) ;/*设置PCXI. UL = 0, 表示当前CSA节点为下部上下文节点*/
—asm(〃rslcx〃);/*恢复下部上下文*/
_mtcr (PCXI, _mfcr (PCXI) | (uint32) (3 22)) ;/*设置PCXI. UL = 1,表 示当前CSA节点为上部上下文节点;设置PCXI. PIE = 1,使得RFE之后能够使能系统中断 */
}o
inline void TaskLoadRun(TaskType PRunTcb)
{
—asm(〃svlcx〃);/*保存下部上下文*/
—mtcr (FCX, OSTCBCur->TFcxCur) ; /* 装载当前任务的 FCL 句柄到 CPU*/ —mtcr (PCX, OSTCBCur->TPcxCur) ; /* 装载当前任务的 PCL 句柄到 CPU*/ —mtcr (LCX, 0STCBCur->TLcx0rig) ; /* 装载当前任务的 LCX 链表句柄到 CPU*/ _mtcr (PCXI, _mfcr (PCXI) & ( (uint32) (1 22))) ;/*设置PCXI. UL = 0, 表示当前CSA节点为下部上下文节点*/
—asm(〃rslcx〃);/*恢复下部上下文*/
_mtcr (PCXI, _mfcr (PCXI) | (uint32) (3 22)) ;/*设置PCXI. UI = 1,表 示当前CSA节点为上部上下文节点;设置PCXI. PIE = 1,使得RFE之后能够使能系统中断 */
}oinline void TaskRun(TaskType PRunTcb)
{
—asm(〃svlcx〃);/*保存下部上下文*/
—mtcr (FCX, OSTCBCur->TFcxCur) ; /*装载当前任务的FCL句柄到FCX寄存器
*/
—mtcr (PCX, OSTCBCur->TPcxCur) ; /*装载当前任务的PCL句柄到PCX寄存器
*/
—mtcr (LCX, 0STCBCur->TLcx0rig) ; /*装载当前任务的LCX链表句柄到LCX寄
存器*/
_mtcr (PCXI, _mfcr(PCXI) & C(uint32) (1 22))) ;/*设置PCXI. UL = 0, 表示当前CSA节点为下部上下文节点*/
—asm(〃rslcx〃);/*恢复下部上下文*/
_mtcr (PCXI, _mfcr (PCXI) | (uint32) (3 22)) ;/*设置PCXI. UL = 1,表 示当前CSA节点为上部上下文节点;设置PCXI. PIE = 1,使得RFE之后能够使能系统中断 */
所述CSA链表的节点数目为预设值。其中,非IDLE任务的CSA链表的数目从TCBCfg中读出,并写入相应任务的TCB中,其代码如下
SET_TASK_CSA_CNT(Tcb, TcbCfg->osCsaCnt);
此外,由于IDLE任务也需要为其建立CSA链表,IDLE任务的CSA链表的节点数目直接在源代码中进行定义,其代码如下uint80sIdleCsaCnt = 10;
在所述任务的FCL耗尽后,增加所述CSA链表的节点数目,这里增加的CSA节点从保留的CSA节点中选取。总之,以上所述仅为本发明的较佳实施例,凡依本发明申请专利范围所作的均等变化与修饰,皆应属本发明 专利的涵盖范围。
权利要求
1.一种基于TC1767平台的CSA节点管理器的实现方法,其特征在于,包括以下具体步骤为每个任务分别建立CSA链表,所述任务与所述CSA链表之间对应,所述CSA链表包括FCL和PCL ;切换所述CSA链表为当前CSA链表以实现任务切换。
2.根据权利要求1所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,所述为每个任务分别建立CSA链表的步骤在TC1767上电后,第一个任务启动之前立即执行。
3.根据权利要求2所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,在所述建立CSA链表的过程中,保留一定数目的节点,所述保留的节点数目由SYS_START_USED 确定。
4.根据权利要求1所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,还包括,在所述任务第一次执行前对所述CSA链表进行初始化,具体步骤为1)将所述任务的PCL的所有节点插入所述任务的FCL中;2)从FCL中取出两个节点分别为第一节点和第二节点,所述第一节点作为上部上下文储存区域,将所述任务的堆栈指针的值写入所述第一节点的SP子域,所述第二节点作为下部上下文储存区域,将所述任务的入口地址写入所述第二节点的RA子域;3)将所述第一节点以头插法插入所述PCL ;4)将所述第二节点以头插法插入所述PCL。
5.根据权利要求1所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,所述CSA链表的节点数目为预设值。
6.根据权利要求1所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,还包括,在所述任务的FCL耗尽后,增加所述CSA链表的节点数目。
7.根据权利要求1-6任一所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,所述任务包括IDLE任务。
8.根据权利要求1-6任一所述的基于TC1767平台的CSA节点管理器的实现方法,其特征在于,所述任务的TCB包括以下成员变量TPcxCur、TFcxCur> TPcxOrig、TFcxOrig、TLcxOrig,所述成员变量用于保存所述CSA链表的句柄,其中,TPcxCur用于保存当前PCL的首节点地址,TFcxCur用于保存当前FCL的首节点地址,TPcxOrig用于保存初始PCL的首节点地址,TFcxOrig用于保存初始FCL的首节点地址,TLcxOrig用于保存初始FCL的尾节点地址。
全文摘要
本发明涉及微控制器的操作系统,公开了一种基于TC1767平台的CSA节点管理器的实现方法,包括以下具体步骤为每个任务分别建立CSA链表,所述任务与所述CSA链表之间一一对应,所述CSA链表包括FCL和PCL;切换所述CSA链表为当前CSA链表以实现任务切换。本发明的优点在于,通过建立和引入CSA节点管理器,在TC1767芯片上实现了多任务切换和处理,任务切换迅速,具有较高的应用价值。
文档编号G06F9/48GK103049325SQ20131000741
公开日2013年4月17日 申请日期2013年1月9日 优先权日2013年1月9日
发明者李红, 吴朝晖, 王旭阳, 陈浩杰, 顾宗华 申请人:浙江大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1