嵌入式操作系统的多线程机制研究与实现 |
|
|
r是调用者传递给创建函数的参数,ThreadId是线程ID号。在这个函数当中,只有一个参数(Parameter)用于调用时将参数传递给创建函数,并且定义为unsigned int类型。这是因为有些编译器(比如realview和kEil MDK的编译器)不能识别结构体作为函数的参数。所以当需要传递多个参数时,可以将结构体的指针作为传递参数。参数stack指向了调用时申请用来作为线程堆栈的空间。严格来说,stack指向的是申请到的heap,它向下增长。线程创建函数首先进行安全检查,比如stack所指向的空间大小是否大于最小需求等。然后在线程堆栈中填充线程TCB,之后便是填充寄存器的值,寄存器的顺序必须是和调度时压堆的顺序相对应,最后是将线程加入进程的线程队列,如果需要马上运行线程,则将线程状态置为就绪。图3是基于Cortrex-M3内核的线程创建时堆栈的示例图。对于Cortex-M3,堆栈指针必须4字节对齐,这一点可能和别的处理器不一样,因为Cortex-M3的ESP的最后两位没有用。而应用程序申请的空间并不能一定保证会是4字节对齐的5,所以必须做好对齐处理。前面已经提到过,应用程序申请到的是heap,它向下增长,但是堆栈是向上增长的,如图3中stack就是这段空间的地址,而堆栈是向上增长,所以填充线程堆栈时要注意顺序。图3的“模拟中断压栈”部分是按Cortex-M3产生中断时压栈顺序填充的,在这部分之后就是我们自己的压栈部分,如图3中的R14-R0和ESP。完成ESP的填充后,就是将线程TCB中的状态变量置为就绪,最后打开中断。因为ThreadCreate()函数是在应用程序中被调用的,所以在ThreadCreate()函数的执行过程当中任何情况都有可能发生,因而必须在关键步骤时关中断。 线程创建后,就在进程的ThreadQueue队列中加入了一个节点,当下一次启动线程调度器后就会运行这个线程。 3.2 线程切换 线程切换广泛的应用于其它线程功能函数中,比如线程延时,自旋锁,旗标等调用当中[7]。线程切换有三个基本的工作要做,分别是:安全检查,将线程置为等待状态和启动线程调度器。安全检查是对线程的状态和资源进行简要的检查,有时程序的运行安全要求要高于速度等其它一切要求,特别是在医疗电子产品的设计当中。以上一页 [1] [2] [3] [4] [5] [6] [7] 下一页 |
|
|
|
上一个论文: 谈操作系统中的死锁问题 下一个论文: 操作系统教学方法研究 |
|