UCOS-ii操作系统的任务堆栈和函数堆栈区别
ucosii操作系统在创建任务的时候,都分配了一段内存用作任务堆栈,用以保存任务的运行状态。问题就在,当某个任务处于运行状态时,此时有中断产生,CPU需要保存该任务的状态...
ucosii操作系统在创建任务的时候,都分配了一段内存用作任务堆栈,用以保存任务的运行状态。问题就在,当某个任务处于运行状态时,此时有中断产生,CPU需要保存该任务的状态到对应的堆栈之中,我想问的是CPU怎么知道把此时任务的状态保存到这个堆栈之中呢?因为,当中断产生时,CPU状态的入栈操作是不用用户关心的(据我了解是这样,或许我了解不深入),就像函数调用一样,也会有对应的入栈和出栈操作,那么任务堆栈和函数堆栈的区别在哪里?怎么让CPU知道任务的堆栈在哪里,同时将相应的状态保存到该堆栈里面?这个问题纠结了我好久了,至今没弄明白,求教各位高手指导指导!急急急~~~~~~~
展开
1个回答
展开全部
任务栈和函数栈有很大不同,要回答你的问题首先应该需要知道任务是怎样切换的以及切换过程对栈的操作。
正如你所说,每个任务都需要分配一个内存空间,这个内存空间作为任务栈,在任务运行时使用。先说单任务情况,给该任务分配一个内存空间作为任务栈,假设在一个时候程序暂停,再运行任务时,仍然可以接着刚才停之前运行处继续执行,为啥呢?因为在停的时候该任务栈保存了所有该任务的信息,再回来时可以继续执行。
换到多任务,每次执行代码cpu是不会关心是什么任务,它只会根据当前指令和栈里的信息执行而已。试想一下,一个任务执行的时候被打断,再次返回时栈里的信息不变,它是不是可以按照被打断前那样继续执行。
好了,接下来该说切换任务时怎么找到栈。要切换任务一般在中断或者陷阱产生后才切换,也就是说当前任务将被打断,进去中断后操作系统(ucos2等)需要将一些必要的寄存器信息保存到该任务栈中,然后找到即将运行的任务栈,恢复寄存器信息即可运行别的任务。举个例子,假设任务a在地址为0x0a0000的指令处被打断,此时pc寄存器(假设该寄存器存放当前指令地址的寄存器)和其他一些相关寄存器被保存到该任务的任务栈中。需要切回该任务时,只要从该任务栈中恢复这些寄存器即可,此时cpu就知道任务刚才被打断时在地址为0x0a0000处,就可以沿着该地址继续执行。
任务切换时cpu入栈出栈确实不用普通用户关系,不关心并不是什么都没做,这部分已经由操作系统处理(如果你需要移植的话,怎么出栈怎么入栈可以自己写),出栈入栈按照一定的顺序保障寄存器恢复正确。
差不多就这些吧,希望能帮助你。
正如你所说,每个任务都需要分配一个内存空间,这个内存空间作为任务栈,在任务运行时使用。先说单任务情况,给该任务分配一个内存空间作为任务栈,假设在一个时候程序暂停,再运行任务时,仍然可以接着刚才停之前运行处继续执行,为啥呢?因为在停的时候该任务栈保存了所有该任务的信息,再回来时可以继续执行。
换到多任务,每次执行代码cpu是不会关心是什么任务,它只会根据当前指令和栈里的信息执行而已。试想一下,一个任务执行的时候被打断,再次返回时栈里的信息不变,它是不是可以按照被打断前那样继续执行。
好了,接下来该说切换任务时怎么找到栈。要切换任务一般在中断或者陷阱产生后才切换,也就是说当前任务将被打断,进去中断后操作系统(ucos2等)需要将一些必要的寄存器信息保存到该任务栈中,然后找到即将运行的任务栈,恢复寄存器信息即可运行别的任务。举个例子,假设任务a在地址为0x0a0000的指令处被打断,此时pc寄存器(假设该寄存器存放当前指令地址的寄存器)和其他一些相关寄存器被保存到该任务的任务栈中。需要切回该任务时,只要从该任务栈中恢复这些寄存器即可,此时cpu就知道任务刚才被打断时在地址为0x0a0000处,就可以沿着该地址继续执行。
任务切换时cpu入栈出栈确实不用普通用户关系,不关心并不是什么都没做,这部分已经由操作系统处理(如果你需要移植的话,怎么出栈怎么入栈可以自己写),出栈入栈按照一定的顺序保障寄存器恢复正确。
差不多就这些吧,希望能帮助你。
更多追问追答
追问
您好,首先非常感谢您的耐心解答,但是我还有些许疑问,您说的是中断产生之后,操作系统进入中断程序之后再保存CPU的寄存器到堆栈中吗??都已经到了中断里面,此时的PC指针的值都已经发生了变化,此时保存的不是任务的信息吧?不好意思啊,我这两个概念有可能没整明白!另外麻烦您看我移植的ucos的下面代码是不是有缺东西?
追答
嗯哪,你的想法很对,,这个就涉及到cpu的问题了,,对于cpu如果发生中断会把pc寄存器存到另外的专用寄存器中,进去中断后保存的是这个专用寄存器的值而不是pc的值
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询