1:关于新创建的task在执行函数时,怎样得到它的两个参数:stacd和exinf
在函数knl_setup_stacd中,还有权威指南P142.
就是说执行函数写成:void task_test(INT stacd, VP exinf)和void task_test(INT stacd)都行
2:函数tk_rcv_mbf_impl中
QueInsert(&knl_ctxtsk->tskque, &mbfcb->recv_queue);后
在函数tk_snd_mbf_impl中
tcb = (TCB*)mbfcb->recv_queue.next;直接取出TCB块。
因为:tskque为knl_ctxtsk结构体的第一个元素。
如果一个结构体只插入到一个链表中的话,就只需要一个tskque,而如果把这个tskque当成该结构体第一个元素的话,就可以直接提取
该结构体
3:cmsis_os.h中
#define osTimerDef(name, function) \
uint32_t os_timer_cb_##name[4]; \
const osTimerDef_t os_timer_def_##name = \
{(function),(os_timer_cb_##name)} 语句:
数组os_timer_cb_##name会自动被arm编译器处理为4个字节的对齐,不用你手工去做这个对齐工作;
4:#pragma arm section code = "_kernel_code_sc", rwdata = "_kernel_data_sc", rodata = "_kernel_const_sc"
以上每个kernel文件中有这么一行,主要是把相关数据归结到相关段中。
应用程序中定义的一些东西归结到.text .data等中去,而kernel中定义的东西归结到_kernel_code_sc等这些段中。
可见生成的map文件。
5:tk_rcv_mbf_impl里面调用knl_make_wait(tmout);一定会设置peandsv悬浮中断的吧?
因为如果不切换的话,在这个地方直接返回的话就不是超时等待了
但是一定发生切换的话,那么tk_rcv_mbf_impl一定不能放到中断上下文里去执行吧,否则会fault伺候。
所以预测到这个地方会切换,所以在tk_rcv_mbf_impl入口处检查是否在中断上下文。
实时操作系统的实时意思是指中断的执行时间是确定的,如果在执行中断时发生任务切换则肯定会造成时间的不确定性。
为什么tk_rcv_mbf_impl不能在中断上下文执行如果misellec为0的话。
ready队列中可以有多个TCB块,但是只有优先级最高的TCB块可以被执行。详见knl_wait_release_ok函数,该函数不一定会去设置pendsv中断,如果 被唤醒的优先级不高于当前运行TCB的优先级的话。但是跟上面的4中的必然会去设置pendsv中断的那个分支代码就不一样了。
ready队列中存在不同优先级的所对应的队列,永远都执行最高优先级队列的首TCB。
ut-kernel的chg_pri函数也可以运行在中断上下文中,只要改变的优先级任务不为当前运行TCB,chg_pri是会立即造成任务切换的,也在大多数情况下吧。
ut-kernel的实时性表现在tk_sta_tsk中如果被启动任务的优先级高于readyque里面的最高优先级(也就是当前TCB)的话,会立刻执行这个被启动的任务。
TS_DORMANT状态是指任务的一次执行结束了。
TS_NONEXIST是指一个任务被删除了。
日本人的ut-kernel设计得还是挺严谨的,质量水平还是挺高的。每个API还都指明了
Task
portion Taskindependent
portion
Dispatchdisabled
这三种状态下的判断。因为实时操作系统对应CPU芯片简单,就是为了处理中断而用的。
实时操作系统和分时的,通用的还是有区别的。
6:王SAN调查的问题结果查出来是栈溢出的问题.
BUG现象:执行到knl_Ifree_impl——》knl_removeFreeQue——》QueInsert里面第一条语句时,整个程序卡死原地不能往前执行。
首先分析汇编代码找出卡住那条汇编指令(STRD R0,R1 【R2,0】),然后看寄存器值有没有什么异常,结果发现R1寄存器值为0,R1+R2值为非常小的数,显然是往错误的地址处写内存了。
然后这条指令前面的一条指令,是给R1赋值的,把某个地址处0x1fff6a00的值加载到R1寄存器里,显然是这个地址处的值被破坏了,被改写成0,导致后来R1里的值也为0.
那么可以用DS-5里面的WATCH功能,监视这个地址处的值在什么时候被破坏成0了?
通过又一次的程序运行过程中的监视,发现程序在执行ref_task函数的第一条指令A时,导致了上面的破坏,这时watch功能责令程序停止执行。
然后看这个指令A前面的一条指令为PUSH操作,立刻想到看看此时的栈指针发现竟然为0x1fff6a00,所以此时栈肯定溢出了,导致破坏了这个与此时执行上下文(执行ref_task函数时)毫不相关的0x1fff6a00地址处内容。
那么栈破坏了,结果对照代码看到不是栈不够用,是栈大小设置错了,设置小了,结果导致不够用。