从头写一个实时操作系统(CPU任务切换)(汇编)
实时操作系统(Real Time Operating System,简称RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,调度一切可利用的资源完成实时任务,并控制所有实时任务协调一致运行的操作系统。提供及时响应和高可靠性是其主要特点。 (来源:百度百科) 实时操作系统要实现的最基本的功能便是任务的切换,与裸机程序不同,在实时操作系统中,每个任务都会拥有其专属的任务堆栈用于任务变量的存储,个人认为操作系统中最难以理解之处就是涉及到汇编部分的CPU现场保存和新任务的切换。 我们这次将在STM32F4(cortex-M4 内核)上简单的实现使用汇编完成任务的切换,首先简单的写一下一下C语言部分的代码,我们需要写两个任务函数(Task1、Task2),这两个函数会在运行中不断的进行切换。 void Task1(){ while(1){ printf("1"); } } void Task2(){ while(1){ printf("2"); } } 除了任务的执行代码外,我们还需要为两个任务初始化堆栈,我们简单的为两个任务风别分配200个32为的空间。 STM32的堆栈地址是从高地址向低地址生长的,即入栈地址减一,因此我们的堆栈地址从我们分配的数组的最后一个元素地址开始即 &TASK1_Stack[199] ,接着我们假设该任务已经被切换出,且此时CPU的所有寄存器都已经保存完毕,我们给他们赋予初值,除了 PS 和 LR 以及PSR 之外 我们可以随意赋值,PS为该任务的入口即Task1 函数的地址,PC该任务结束时返回的地址,我们让任务结束时运行EDN_Handle函数。 static unsigned int TASK1_Stack[200]; static unsigned int TASK2_Stack[200]; void task_init(){ /// 初始化 任务的堆栈 /// STM32 的堆栈是从 高地址 --》 低地址 Task1_stack_p = &TASK1_Stack[200-1]; Task2_stack_p = &TASK2_Stack[200-1]; /// 此时 两个任务的堆栈指针都存在 了 Task_X_stack_p 中 *(--Task1_stack_p) = 0x01000000uL; // 程序状态寄存器 PSR *(--Task1_stack_p) = (unsigned int)Task1; // 程序开始地址 PC *(--Task1_stack_p) = (unsigned int)END_Handle; *(--Task1_stack_p) = 0x00001234uL; // R12 *(--Task1_stack_p) = 0x7788521AuL; // R3 *(--Task1_stack_p) = 0x7788521BuL; // R2 *(--Task1_stack_p) = 0x7788521CuL; // R1 *(--Task1_stack_p) = 0x00000001uL; // R0 *(--Task1_stack_p) = 0x7788521AuL; // R11 *(--Task1_stack_p) = 0x7788521BuL; // R10 *(--Task1_stack_p) = 0x7788521CuL; // R9 *(--Task1_stack_p) = 0x7788521DuL; // R8 *(--Task1_stack_p) = 0x7788521EuL; // R7 *(--Task1_stack_p) = 0x7788521FuL; // R6 *(--Task1_stack_p) = 0x7788521FuL; // R5 *(--Task1_stack_p) = 0x7788521FuL; // R4 实时操作系统要想实现任务的调度,就必须有时间的度量,在一个任务运行一段时间之后切换到下一个该执行的任务,以保证系统的实时性,因此我们必须让系统在指定的时间段进行任务的调度,在STM32中我们可以使用StsTick计数器的中断实现任务的切换,但是在STM32 中硬件为我们提供了另外一个中断(PendSV)顾名思义该中断是可以挂起的,在STM32中一般都会使用PendSv中断去执行任务的中断,因为其可挂起的特性,可以使程序在运行时先执行其他外设所产生的中断,在这些中断执行完毕后再去进行任务的调度,以此保证其他中断能够及时的得到相应,因此我们要在Systick的中断中去开启PendSV中断。以下代码中我们在Systick中断中找到接下来要运行的任务,使用 PENDSV( )函数开启PendSV中断。 ...