feedforward 发表于 2020-3-13 20:38:50

NuttX任务切换的浅表认识

今天开始啃nuttx向sparc上移植的最硬骨头:任务切换!
使用大杀器codeblocks进行单步调试,首先执行__start模块,之后完成up_lowinit初始化,紧接着就开始关键部分:
nx_start()                              sched/init/nx_start.c
--> nx_bringup()                         sched/init/nx_bringup.c
--> nx_create_initthread()            sched/init/nx_bringup.c
    --> nx_start_application()               sched/init/nx_bringup.c
      --> nxtask_create()                               sched/task/task_create.c
          -->nx thread_create()                           sched/task/task_create.c
            --> task_activate()                                       sched/task/task_activate.c
            --> up_unblock_task()                                  arch/sparc/src/sparc-v8/up_unblocktask.c
                --> up_switchcontext()                                       arch/sparc/src/sparc-v8/up_switchcontext.S
up_switchcontext最后执行jmp   %o7 + 8后跳转到了nxtask_start函数,这也正是首次上下文切换要达到的目的,nxtask_start函数是所有线程的起点函数我是知道的,但是nxtask_start怎样和%o7建立联系的呢?事实上nxthread_create函数在调用task_activate函数之前将nxtask_start函数作为参数(通过start_t空函数指针)传递给nxtask_schedsetup函数:

而nxtask_schedsetup函数又将函数指针start(已指向nxtask_start函数)传递给了nxthread_schedsetup函数。在nxthread_schedsetup函数中将start指针捆绑到了tcb结构体中的start。tcb结构体中的xcpt和sparc的寄存器是如何关联的这已经是很明确的,但是依然不明白tcb结构体中的start是如何与%o7建立联系的。
经过两小时的深入侦查,今天的收获总算是有了:
主角登场:nxthread_schedsetup将start指针捆绑到了tcb结构体中的start后调用了一个关键的处理器相关的函数up_initial_state(),该函数将start指针绑定到了上下文寄存结构的 %o7对应位置处:

首次恢复上下文时会将其下载至%o7寄存器,从而使得jmp   %o7 + 8能跳转至nxtask_start,当时底层移植时参考mips构架照猫画虎,不理解up_initial_state函数的意义,这下真相大白了!

页: [1]
查看完整版本: NuttX任务切换的浅表认识