<code class="lang-cpp">int main(void) { GPIO_InitTypeDef GPIO_InitStructure; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口初始化为9600 LED_Init(); //初始化与LED连接的硬件接口 SysTick_Configuration(); OSInit(); OSTaskCreate( TaskStart, //task pointer (void *)0, //parameter (OS_STK *)&TASK_START_STK[START_STK_SIZE-1], //task stack top pointer START_TASK_Prio ); //task priority OSStart(); return 0; } //开始任务 void TaskStart(void * pdata) { pdata = pdata; OS_ENTER_CRITICAL(); OSTaskCreate(TaskLed, (void * )0, (OS_STK *)&TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio); OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio); OSTaskSuspend(START_TASK_Prio); //suspend but not delete OS_EXIT_CRITICAL(); } //任务1 //控制DS0的亮灭. void TaskLed(void *pdata) { while(1) { LED0 = !LED0; OSTimeDlyHMSM(0,0,1,100); } } //任务2 //控制DS1的亮灭. void TaskLed1(void *pdata) { while(1) { LED1 = !LED1; OSTimeDlyHMSM(0,0,1,300); } }</code>
<code class="lang-cpp">TIM3_IRQHandler PROC PUSH {r4,lr} MRS r4,MSP MOV r0,r4 ADD r0,r0,#8 MOV r4,r0 LDR r0,|L0.640| STR r4,[r0,#0] BL IRQHandler POP {r4,pc} ENDP</code>----->生成汇编文件后可以看到,进入TIM3_IRQHandler函数先把R4和LR压栈(这是编译器自动做的),MSP堆栈指针 - 8 ----->MRS r4,MSP 保存栈指针 ----->指针+8(对前面R4和LR的补偿)对准 8个被自动压栈的寄存器的R0 ----->保存指针到全局变量Address_BASE ----->bl IRQHandler 调用任务调度程序 ----->清除中断待处理位 ----->根据之前保存的栈地址,加载8个寄存器保存当前任务现场 -----> 调用任务二的地址-----> task->Start_Next(); 更新任务标志-----> 退出中断 并 恢复被修改了返回地址的8个寄存器 -----> 执行任务1-----> 定时器中断时间到 ---->进入中断 -----> 保存任务1现场-----> 恢复任务0 ----->退出中断 ----->goto 标志;
<code class="lang-cpp">#include "../h/main.h" extern Task *task; int main(void) { task = new Task(); //创建任务管理对象 这是一个C++类对象 Init();//初始化 时钟 串口 GPIO Timerx_Init(20,7199);//初始化TIM3,开中断,每2ms进一次中断 TIM3->CNT = 0x01;//意义不明 不要也行 __asm //內联汇编 { bl Task0 //跳转到任务1 } // while (true); // delete task; } int temp = 0; void Task0(void) //任务1 { while (true) { LED0 = !LED0; } } void Task1(void) //任务2 { while (true) { LED1 = !LED1; } }</code>
<code class="lang-cpp">class Task //任务管理类 { public:Task(void) //构造函数,初始化时会自动调用 { Reg_Buff[0][6]=((unsigned int)&Task0) ; //初始化任务0的指针 Reg_Buff[1][6]=((unsigned int)&Task1) ; //初始化任务1的指针 Reg_Buff[0][6]=Reg_Buff[1][7]=0x61000000 ; //初始化xRSP Current = 0; Next = 1; } public: static const unsigned char Count = Task_Count; public: unsigned char Current; //当前任务 public: unsigned char Next ; //下一个任务 public: volatile unsigned int Reg_Buff[Task_Count][8]; public: void Start_Next() //更新至下一个任务 { (Current + 1 < Count) ? Current++ : Current = 0; (Next + 1 < Count) ? Next++ : Next = 0; // if (Next != 0 && (Next - Current) != 1) // { // while (true) // { // } // } } };</code>
<code class="lang-cpp">Task *task ; unsigned int Address_BASE = 0; void IRQHandler(void) { if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源 __asm { ldr r5, [Address_BASE] str r5, [&task->Reg_Buff[task->Current][0]]//R0 ldr r5, [Address_BASE , 0x4] str r5, [&task->Reg_Buff[task->Current][1]]//R1 ldr r5, [Address_BASE , 0x8] str r5, [&task->Reg_Buff[task->Current][2]]//R2 ldr r5, [Address_BASE , 0xc] str r5, [&task->Reg_Buff[task->Current][3]]//R3 ldr r5, [Address_BASE , 0x10] str r5, [&task->Reg_Buff[task->Current][4]]//R12 // ldr r5, [Address_BASE , 0x14] // str r5, [&task->Reg_Buff[task->Current][5]]//R13 LR ldr r5, [Address_BASE , 0x18] str r5, [&task->Reg_Buff[task->Current][6]]//R14 PC ldr r5, [Address_BASE , 0x1c] str r5, [&task->Reg_Buff[task->Current][7]]//R15 xRSP /*↑↑↑保存当然运行中的任务现场↑↑↑*/ ldr r5, [&task->Reg_Buff[task->Next][0]]//R0 str r5, [Address_BASE] ldr r5, [&task->Reg_Buff[task->Next][1]]//R1 str r5, [Address_BASE, 0x4] ldr r5, [&task->Reg_Buff[task->Next][2]]//R2 str r5, [Address_BASE, 0x8] ldr r5, [&task->Reg_Buff[task->Next][3]]//R3 str r5, [Address_BASE, 0xc] ldr r5, [&task->Reg_Buff[task->Next][4]]//R12 str r5, [Address_BASE, 0x10] // ldr r5, [&task->Reg_Buff[task->Next][5]]//R13 LR // str r5, [Address_BASE, 0x14] ldr r5, [&task->Reg_Buff[task->Next][6]]//R14 PC //orr r5, 0x01 str r5, [Address_BASE, 0x18] ldr r5, [&task->Reg_Buff[task->Next][7]]//R15 xRSP str r5, [Address_BASE, 0x1c] /*↑↑↑恢复上一个任务的现场↑↑↑*/ } task->Start_Next(); //下一个任务 } } extern "C" { void TIM3_IRQHandler(void) //TIM3中断 中断中不能有太多东西,否则进中断时压栈太多 MSP不容易计算 { __ASM { mrs r4, msp add r4, 0x08 str r4, [&Address_BASE] bl IRQHandler } } }</code>
[修改于 8年11个月前 - 2015/06/05 14:26:47]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |