动机
FreeRTOS在port.c中都是和内核相关的,我就是想了解清楚TC2上下文切换的机制。所以看pxPortInitialiseStack函数,里面主要是初始化CSA,在FreeRTOS任务创建函数中会调用,另外还看了xPortStartScheduler函数,这里面主要是处理上下文切换。
本来在看core寄存器说明文档,里面有说上下文切换保存和恢复的机制。
问题1
里面说到NEW_FCX,而且是用户不可操作的,另外还说道LINK WORD和PCXI关联,值是一样的,那么用户怎么操作呢?这部分不太理解。
问题2
为什么切换任务的时候要用rslcx,而且一开始初始化任务的时候要用lower+Up2个CSA,文档中说的都是or,而且主要都是说产生中断或trip会自动保存lower,为什么还要手动操作呢?
突破
带着这2个问题,我不了解代码为什么要这样设计,感觉混乱的原因是先有鸡还是先有蛋的感觉。于是乎网上搜索看看有没有线索,接着真的找到我想要的了,帮助我解决了理解问题,现在代码能够完全看懂。并且调试验证他理解的是正确的。
FreeRTOS任务创建、启动调度器、任务切换过程分析——基于Tricore1.6
看了他的文章后,我发现PCXI就是LINK WORD,之前没有搜索到,因为在图片中。
调试验证通过
FreeRTOS任务启动验证.png
小结:
重要的理解就是PCXI就是链表(连接线),所以PCXI可以理解为一个指针箭头。FCX的值绑定到连接线,即FCX指向了pulUpperCSA的下一个。
怎么区分低级还是高级上下文的呢?也就是说必须低级的下一个连接到高级,不能高级的下一个连接到低级?对称性,save2个,所以要restore2个。
基于这样的理解,我准备之后自己尝试,初始化只建立一个lowerCSA,那么启动任务的时候只要恢复一个lowerCSA即可。明天继续验证我的猜想。
寄存器参考
UpperAndLower.png
2020/4/7更新
昨夜遗留了一个想法,就是只使用一个lowerCSA可否,今天看了内核手册,发现应该是不可以的。于是修改了代码只用一个lowerCSA或upperCSA,调试结果也显示不可行。
答案从如下3方面来描述
- 从CSA区域功能角度。只有一个CSA,不使用lower和upper的组合的话,缺少参数A[4]。
-
最重要的一点就是Upper是自动保存和恢复的。即保存和恢复LINK word链表指向的CSA内的16个word的数据(这些数据会绑定到A和D寄存器中),而我无法直接为A11(RA)赋值,必须要通过PCXI指向的CSA区域中的A11赋值才可行。
-
自动保存upper.png
-
也不能通过mfcr向PCX来读取当前地址,通过地址+4来为当前的A11赋值。因为一读取,PCXI就自动从链表中移除,指向下一个链表。
上下文恢复机制.png
有了以上3点,就说明我必须要自己制作lower的内容,然后通过rslcx指令手工恢复,由于退出函数会自动执行恢复UpperCSA,所以还在LowerCSA后面还要自己再连接一个UpperCSA。这样自动执行退出函数的时候,能找到我准备的自定义跳转函数,这样就进入了下一个我期待的函数了。Tricore的上下文切换的寄存器原来是要这么操作的。哈哈~
这么验证实验一下,使我对Tricore上下文切换理解的更加深入了。pxPortInitialiseStack和xPortStartScheduler函数的理解也更加深刻了。