一种ThreadX操作系统在ARM处理器上的运行方法与流程

文档序号:11133721阅读:1161来源:国知局
一种ThreadX操作系统在ARM处理器上的运行方法与制造工艺

本发明属于计算机技术领域,具体涉及一种ThreadX操作系统在ARM处理器上的运行方法。



背景技术:

ThreadX操作系统是Express Logic公司为嵌入式应用设计的硬实时操作系统,通过设计合理的接口程序可以使ThreadX操作系统在多种处理器上运行。操作系统与处理器之间的汇编语言接口程序是系统运行过程中指令密集度最高的部分,虽然很多处理方法所提供的接口程序可以满足大多数实时系统的要求,但执行效率并不高。问题主要集中在指令不够精简,堆栈不能利用编译器的规则做最小化设计,不支持中断嵌套和不支持内核剥夺功能等。



技术实现要素:

本发明的目的是提供一种ThreadX操作系统在ARM处理器上的运行方法,以解决基于ThreadX操作系统的ARM处理器平台稳定性和高效性的问题。

本发明采用以下技术方案:

一种ThreadX操作系统在ARM处理器上的运行方法,包括以下步骤:

步骤一、初始化ARM处理器的运行环境并切换至特权模式;

步骤二、初始化ARM处理器的底层任务;

步骤三、创建中断上下文线程堆栈框架,并初始化中断上下文线程堆栈框架及创建线程;

步骤四、将执行线程的中断上下文加载到ARM寄存器中,并对执行线程开 始处理,此时执行线程变为当前线程,在当前线程运行过程中进行响应同步事件处理和异步事件处理,同步事件处理为主动线程切换过程,而异步事件处理为被动中断响应过程。

进一步地,步骤四中同步事件处理过程如下:

当前线程运行过程中,通过调用系统服务函数,进而调用CPU控制权返还函数,将当前线程的执行现场利用返还函数保存为请求上下文堆栈线程,保存执行现场完成后,再通过线程调度函数进行线程的切换。

进一步地,步骤四中异步事件处理过程如下:

当当前线程运行过程中发生异步事件时,通过调用中断处理函数保存当前线程执行现场,然后开始执行中断服务例程,待中断服务例程执行完成后,根据被中断的当前线程中断点位置及执行线程和当前线程的状态信息,恢复执行现场或进行内核剥夺操作。

进一步地,异步事件处理过程中,保存当前线程执行现场的方法为:

a、在中断模式中,调用中断处理函数执行中断模式跳转指令,跳转指令分为无线程执行时的空循环指令区域、正在运行的线程指令区域、中断例程指令区域,中断处理函数将根据中断点落入的区域进行保存当前线程执行现场:

当保存中断点位于无线程执行时的空循环指令区域时,不保存任何寄存器;

当保存中断点位于正在运行的线程指令区域和中断例程指令区域时将SPSR寄存器保存到当前中断模式的堆栈中;然后递增系统状态变量的计数,系统状态变量的计数表示当前中断嵌套层数,也表示当前位于中断模式中;

b、通过系统自动跳转到中断入口函数执行中断请求,首先将处理器的模式切换为系统模式,将系统模式下的lr寄存器压入堆栈中,之后调用中断服务例程, 进行异步事件处理;

c、异步事件处理完成后,恢复系统模式下的lr寄存器,然后将系统的模式切换回中断模式,进行恢复执行现场或进行内核剥夺操作。

进一步地,恢复执行现场或进行内核剥夺操作的方法为:

5.1)当系统状态变量的计数不为0时,为中断嵌套情况,即中断点位于中断例程指令区域,恢复中断例程执行现场;

5.2)当系统状态变量的计数为0时,直接切换为特权模式,并观察剥夺禁止变量:

当剥夺禁止变量不为0时,中断点位于不可剥夺指令区域,恢复当前线程执行现场;

当剥夺禁止变量为0时,中断点位于可剥夺指令区域,如不存在更高优先级的就绪线程,则恢复当前线程执行现场;否则,保存被中断线程的中断上下文,然后调用线程调度函数执行高优先级的就绪线程,实现内核剥夺操作。

进一步地,中断上下文和请求上下文的0偏移地址存储的指示标志不同。

进一步地,步骤一的具体方法:初始化ARM处理器的运行环境,包括初始化各模式的堆栈分配及各模式的堆栈指针寄存器,之后将ARM处理器切换至特权模式,并调用主函数,进而调用内核入口函数。

进一步地,步骤二的具体方法:初始化ARM处理器的底层任务,包括设置周期时钟中断源,找到用于线程堆栈分配的剩余内存首地址。

本发明的有益效果是:通过特有的堆栈方法构建堆栈、调用线程及线程控制权返还函数等方法能够充分发挥ThreadX操作系统的特性,使基于本方法所构建的系统平台满足实时性强,可靠性高的特点,且中断响应速度非常快,假如CPU 的时钟频率是50MHz,响应异步事件的最长时间小于0.6us;本方法支持ThreadX操作系统的内核剥夺调度功能,使高优先级线程更快得到执行,支持ThreadX操作系统基于时间片的轮转调度功能,实现了中断嵌套功能。

【附图说明】

图1为本发明中的中断上下文堆栈框架;

图2为本发明中的请求上下文堆栈框架。

【具体实施方式】

下面结合附图和具体实施方式对本发明进行详细说明。

本发明公开了一种ThreadX操作系统在ARM处理器上的运行方法,包括以下步骤:

步骤一、初始化ARM处理器的运行环境,包括初始化各模式的堆栈分配及各模式的堆栈指针寄存器,之后将ARM处理器切换至特权模式svc,并调用主函数main,进而调用内核入口函数_tx_initialize_kernel_enter;各模式包括特权模式svc、系统模式sys、普通中断模式irq和快速中断模式fiq,即sp_svc、sp_sys、sp_irq、sp_fiq。堆栈指针寄存器包括相应模式的r13或sp寄存器。

步骤二、初始化ARM处理器的底层任务,即实现函数_tx_initialize_low_level。该函数是内核启动过程中,ThreadX操作系统与ARM处理器初始化汇编语言程序的接口,在该函数中将实现所有ARM处理器相关初始化操作,包括设置周期时钟中断源,找到用于线程堆栈分配的剩余内存首地址;

CPU相关初始化操作包括配置协处理器寄存器实现缓存CACHE、内存管理单元MMU的设置等;

设置时钟中断源,用于产生周期性中断以驱动定时器;

根据自定义的RAM分配图表及链接规则计算用于线程堆栈的内存最低地址;将内存最低地址存储到threadX指定变量_tx_initialize_unused_memory中;根据编译器的指令集选项,即THUMB指令集或ARM指令集,使用相对应的跳转指令。

步骤三、通过线程堆栈建立函数_tx_thread_stack_build创建中断上下文线程堆栈框架,该函数是ThreadX操作系统与ARM处理器的线程堆栈建立汇编语言程序接口,由内核提供的线程创建函数所调用,用于建立应用线程启动的堆栈框架;

并初始化中断上下文线程堆栈框架及创建堆栈线程,任何线程的创建都将调用线程堆栈建立函数_tx_thread_stack_build建立一个被称之为中断上下文的线程堆栈框架,并初始化线程堆栈框架。

该函数接口有两个参数,寄存器r0所传递的参数是线程控制块TCB地址,寄存器r1所传递的参数是线程的入口函数地址。

从TCB中获取线程堆栈底地址,使其8字节对齐;

从线程堆栈底向低地址方向预留中断上下文框架所占用空间;根据图1构造线程初始启动所需要的中断上下文;更新TCB中的线程堆栈指针;根据编译器的指令集选项,即THUMB指令集或ARM指令集,使用相对应的跳转指令。

中断上下文的堆栈框架如图1所示,图中堆栈的增长方向为由高地址向低地址增长;tx_stack_end为所建立线程的堆栈底;tx_stack_limit为所建立线程的堆 栈顶;tx_stack_ptr为线程堆栈建立完成后的线程堆栈指针;表格内为中断上下文,每行占4个字节,0偏移地址存储中断上下文指示标志,4偏移地址对应ARM处理器的当前程序状态寄存器CPSR,设计线程运行在特权模式SVC下,CPSR应初始化为SVC模式,8偏移地址至0x40偏移地址相应于ARM处理器的寄存器,其中sl为r10,fp为r11,ip为r12,lr为r14,pc为r15。

当某线程首次执行时,_tx_thread_stack_build所构建的中断上下文除0偏移地址外,其他内容将被加载到ARM处理器寄存器中后,该线程的主函数将开始运行。

步骤四、通过线程调度函数_tx_thread_schedule将执行线程的中断上下文加载到ARM寄存器中,执行线程是最高优先级的就绪线程,并对执行线程开始处理,即运行该线程主函数,此时执行线程变为当前线程;

当前线程运行过程中可以通过调用系统服务函数,进而主动调用CPU控制权返还函数,将当前线程的执行现场利用返还函数保存为请求上下文堆栈线程,保存执行现场完成后,再通过线程调度函数_tx_thread_schedule进行线程的切换。

线程调度函数_tx_thread_schedule实现线程切换,通过将线程堆栈中的上下文加载到ARM寄存器中,即恢复现场使就绪线程开始执行处理,并递增就绪线程调度计数和设置就绪线程的时间片。若无就绪线程,则无限循环线程调度函数_tx_thread_schedule,等待异步事件去恢复某个线程到就绪状态,就绪线程为线程链表中优先级最高的线程,由操作系统计算出,并保存在变量_tx_thread_execute_ptr中。

线程调度函数_tx_thread_schedule是ThreadX操作系统与ARM处理器的汇编语言程序接口,在ThreadX操作系统完成初始化后调用,其主要功能是从线程 堆栈中加载上下文到处理器的寄存器,恢复线程的运行。

首先打开中断,然后实现无就绪线程时的空循环,否则进入恢复就绪线程的流程,然后递增就绪线程的运行计数,将就绪线程TCB中的时间片赋值到全局时间片变量中;之后将就绪线程TCB中的堆栈指针加载到sp寄存器;从sp寄存器所指堆栈地址弹出上下文中第1个和第2个值分别加载到r0和r1寄存器,此时r0寄存器中存储上下文标识,r1存储cpsr;判断r0为中断上下文还是请求上下文,若为中断上下文,直接恢复线程执行现场的指令;若为请求上下文,则首先将请求上下文中r4,r5,r6,r7,r8,r9,sl,fp,pc加载到ARM处理器中对应的寄存器,其中lr寄存器存储线程返回地址,然后将之前存储到r1中的cpsr内容加载到处理器cpsr寄存器,然后跳转到lr中存储的线程返回地址,开始恢复线程运行。

在当前线程运行过程中进行同步事件处理和异步事件处理,同步事件处理为主动线程切换过程,而异步事件处理为被动中断响应过程。

同步事件处理过程如下:

当前线程运行过程中需要调用系统服务函数,系统服务函数将主动调用CPU控制权返还函数,将当前线程的执行现场利用控制权返还函数保存为请求上下文堆栈线程,保存执行现场完成后,再通过线程调度函数进行线程的切换;

控制权返还函数是操作系统与处理器的汇编语言程序接口,由操作系统服务函数调用,用于当前运行线程放弃CPU控制权。

首先将请求上下文标识0赋值给r0寄存器,将cpsr赋值给r1寄存器临时保存,然后将r0-r9,sl,fp,lr压入当前运行线程堆栈中,然后关闭中断,然后保存当前线程剩余时间片变量到TCB中,然后保存当前栈指针到TCB,此时现场 保护完毕,之后将当前线程的时间片全局变量和当前线程运行的计数变量清零,最后跳转至调度函数_tx_thread_schedule。

控制权返还是指保存当前线程的执行现场,即利用编译规则,将必要ARM寄存器保存到线程堆栈中,必要寄存器被称之为请求上下文,请求上下文和中断上下文的0偏移地址存储的指示标志不同。

在这里之所以能够利用编译器的规则,是因为控制权返还始终是通过调用系统服务函数实现的,而非通过异步事件。例如,当线程请求资源而等待,相应的系统服务函数将调用_tx_thread_system_return。_tx_thread_system_return是无参的函数,所以不需要保存临时寄存器r0,r1,r2,r3。另外,函数返回点r15是明确的,已保存到r14中,所以不需要保存r15。

请求上下文框架如图2所示,图中堆栈的增长方向为由高地址向低地址增长;tx_stack_end为所建立线程的堆栈底;tx_stack_limit为所建立线程的堆栈顶;tx_stack_ptr为当前线程控制权返还给系统后的堆栈指针,被保存在当前线程控制块中;表格内为请求上下文,每行占4个字节,0偏移地址存储请求上下文指示标志,4偏移地址对应ARM处理器的当前程序状态寄存器CPSR,8偏移地址至0x40偏移地址相应于ARM处理器的寄存器,其中sl为r10,fp为r11,lr为r14。保存现场完成后,将当前线程的时间片全局变量和当前线程运行的计数变量清零,然后调用所述线程调度函数实现线程切换。

异步事件处理过程如下:

当当前线程运行过程中发生异步事件时,通过调用中断处理函数保存当前线程执行现场,然后开始执行中断服务例程,待中断服务例程执行完成后,根据被中断的当前线程中断点位置及执行线程和所述当前线程的状态信息,恢复执行现 场或进行内核剥夺操作。

异步事件是通过中断机制触发的,中断发生时pc指针可能位于临界区之外的任何指令位置,该位置称之为中断点,简称POI。当当前线程运行过程中发生中断时,通过调用中断处理函数保存当前线程执行现场,然后开始执行中断服务例程,待中断服务例程执行完成后,根据被中断的当前线程中断点位置及执行线程和当前线程的状态信息,恢复执行现场或进行内核剥夺操作。

实现中断处理函数_tx_irq_handler,该函数仅是一个封装函数,通过顺序调用各子函数完成一次异步事件处理,当中断发生后,处理器自动将中断点pc指针和中断点cpsr分别存入中断模式的lr寄存器和中断模式spsr,同时切换模式到中断模式,然后置pc指针到中断向量表中断跳转指令位置调用中断处理函数。

处理异步事件时具有内核剥夺功能和中断嵌套功能,其具体步骤如下,

a、在当前线程运行过程中,异步事件发出中断请求,ARM处理器将当前模式的当前程序状态寄存器和PC指针寄存器分别备份至中断模式的SPSR和lr寄存器,并切换为中断模式,将PC指针跳转至中断向量表,调用中断处理函数_tx_thread_context_save执行中断模式跳转指令,跳转指令分为三个部分,无线程执行时的空循环指令区域Idle Loop Instruction Domain(ILID)、正在运行的线程指令区域Running Thread Instruction Domain(RTID)、中断例程指令区域ISR Instruction Domain(ISRID),中断处理函数_tx_thread_context_save将根据保存中断点落入的区域进行保存当前线程执行现场:

当保存中断点位于无线程执行时的空循环指令区域时,不保存任何寄存器;

当保存中断点位于正在运行的线程指令区域和中断例程指令区域时将SPSR、sl,ip,lr,r0,r1,r2,r3寄存器保存到当前中断模式的堆栈中,即IRQ 模式下的堆栈中;然后递增系统状态变量_tx_thread_system_state的计数,系统状态变量_tx_thread_system_state的计数表示当前中断嵌套层数,也表示当前位于中断模式中;

b、实现支持中断嵌套功能的_tx_thread_irq_nesting_start函数,为了使中断服务例程ISR的堆栈与线程堆栈相分离,首先将处理器模式切换为系统模式,中断处理例程ISR就在系统模式下运行,将系统模式下的lr寄存器压入堆栈中,用以保护嵌套中断发生时POI所在函数的返回地址,函数返回,然后调用中断服务例程ISR,进行异步事件处理,即进行相应中断源的事件处理;

具体过程如下:

首先将临时寄存器r0,r1,r2,r3压入当前模式堆栈中,当前模式为IRQ模式,然后通过中断嵌套层数变量_tx_thread_system_state判断中断点是否位于ISRID中;

若该变量不为零,则表示指令发生在ISRID中,执行递增_tx_thread_system_state,再通过当前线程指针变量判断中断点是否发生在RTPID,若发生在RTPID,则将SPSR,sl,ip,lr寄存器压入当前模式堆栈中,然后返回位置IRQ Processing Return;否则,丢弃在压入堆栈的4个寄存器,再返回位置IRQ Processing Return;

若该变量等于0,则表示指令未发生在ISRID中则执行递增_tx_thread_system_state,然后将SPSR,sl,ip,lr寄存器压入当前模式堆栈中,再返回位置IRQ Processing Return。

c.实现支持中断嵌套功能的_tx_thread_irq_nesting_end函数,当ISR执行完成后,调用_tx_thread_irq_nesting_end函数,回复系统模式下的lr寄存器,即将 lr弹出堆栈,切换回中断模式,进行恢复现场或进行内核剥夺操作;_tx_thread_irq_nesting_end函数的功能与上述_tx_thread_irq_nesting_start函数所实现的功能是对称的,先恢复SYS模式下的lr,然后将处理器模式从SYS切换回IRQ模式,最后调用_tx_thread_context_restore函数禁止中断,递减中断嵌套层数,根据终端嵌套层数当前是否为中断嵌套状态,当系统状态变量_tx_thread_system_state的计数不为0时,为中断嵌套情况,即中断点位于中断例程指令区域ISRID,直接将压入堆栈的内容反向顺序弹出,恢复ISR执行现场;若无嵌套则进行内核剥夺操作的判断;

d.内核剥夺是指保存中断点所属线程的执行现场,调度更高优先级的线程执行,使其获得CPU的控制权。中断嵌套处理完成后,恢复系统模式下的lr寄存器,然后将系统的模式切换回中断模式,进行恢复执行现场或进行内核剥夺操作;

恢复执行现场或进行内核剥夺操作的方法,即实现函数_tx_thread_context_restore的方法为:

在_tx_thread_context_restore函数中,根据中断点的位置有以下情况:

5.1)当系统状态变量_tx_thread_system_state的计数不为0时,为中断嵌套情况,即中断点位于中断例程指令区域ISRID,直接将压入堆栈的内容反向顺序弹出,恢复中断例程执行现场;

5.2)当系统状态变量的计数为0时,说明中断点位于ILID,直接切换为特权模式,并观察剥夺禁止变量:

当剥夺禁止变量_tx_thread_preempt_disable不为0时,中断点位于不可剥夺指令区域,恢复当前线程执行现场;

当剥夺禁止变量_tx_thread_preempt_disable为0时,中断点位于可剥夺指令区域,如不存在更高优先级的就绪线程,则恢复当前线程执行现场;否则,保存被中断线程的中断上下文,然后调用线程调度函数执行高优先级的就绪线程,实现内核剥夺操作。

当满足内核剥夺条件时,需要保存之前中断发生时当前线程的执行现场,首先构建IRQ Context并将其压入线程堆栈以保护被中断线程的现场,然后恢复先前压入到IRQ堆栈中的spsr,sl,ip,lr寄存器,其中spsr为中断点指令位置的cpsr寄存器,lr为中断点指令位置;将lr传送到r1寄存器,以使SVC模式能够访问;切换到SVC模式,并保持中断禁止;将r1寄存器保存的中断点指令位置压入线程堆栈;为将SVC模式下中断点位置的r4-r9,sl,fp,ip,lr寄存器入栈;使用r4临时保存cpsr;切换到IRQ模式并保持中断禁止;恢复IRQ模式下临时寄存器r0-r3;切换到SVC模式并保持中断禁止;为将临时寄存器r0-r3压入线程堆栈;将r4所保存的cpsr和IRQ Context标识常数1压入线程堆栈;将堆栈指针sp寄存器保存到线程控制块TCB中;保存当前线程的时间片计数到TCB中;最后,调用线程调度函数_tx_thread_schedule执行更高优先级线程。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1