我是靠谱客的博主 自信寒风,最近开发中收集的这篇文章主要介绍c语言实现stm32多线程,自己动手写STM32多任务调度器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

首先介绍几个寄存器,这几个寄存器只能在汇编或内联汇编时才能访问,C语言是访问不到的

R0-R12,都可作为临时变量存储,跟C语言的变量差不多,不过汇编中的存储变量是用寄存器,而且不用声明,全局可见,不分全局和局部,而且是32位的

比如想计算1+1,结果放在r0中

mov r0,0x01

add r0,0x01

df71f3d6c44399bbe8c8b3a46a2f6bca.png

图片来自互联网,互联网来自<<Cortex-M3权威指南>>

R13(MSP/PSP)堆栈寄存器,汇编指令PUSH,POP会影响R13的值,

PUSH {R0} //R0的值将被压入栈内 R13-4

POP{R1}    //将SP所指向的内存赋值给R1 SP+4

b50cc07852df747276c449fc40b4eb09.png

R14 :是连接寄存器(LR),用于在调用子程序时存储返回地址,应该是不能用mov mrs msr访问的,只能用pop push保存R15 是程序计数器(PC),每条指令前都对应一个地址,把这个地址赋值给R15,程序就立即跳过去执行地址对应的程序xRPS特殊功能寄存器组 详细内容请参考<<Cortex-M3权威指南>>

之前用过UCOS,可是他每个死循环任务下面必须有一个延时函数,才可以把调度权限交还给系统,自然这个延时函数上面也不可以有死循环,

不然将永远卡在死循环上,别的任务也就不能再被调用了

<code class="lang-cpp">int main(void)

{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;GPIO_InitTypeDef&nbsp;&nbsp;GPIO_InitStructure;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;Stm32_Clock_Init(9); //系统时钟设置

&nbsp;&nbsp;&nbsp;&nbsp;delay_init(72);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//延时初始化

&nbsp;&nbsp;&nbsp;&nbsp;uart_init(72,9600);&nbsp;&nbsp;//串口初始化为9600

&nbsp;&nbsp;&nbsp;&nbsp;LED_Init();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//初始化与LED连接的硬件接口&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;SysTick_Configuration();

&nbsp;&nbsp;&nbsp;&nbsp;OSInit();

&nbsp;&nbsp;&nbsp;&nbsp;OSTaskCreate( TaskStart,&nbsp;&nbsp;&nbsp;&nbsp;//task pointer

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(void *)0,&nbsp;&nbsp;//parameter

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(OS_STK *)&amp;TASK_START_STK[START_STK_SIZE-1],&nbsp;&nbsp;&nbsp;&nbsp;//task stack top pointer

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;START_TASK_Prio );&nbsp;&nbsp;//task priority

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;OSStart();

&nbsp;&nbsp;&nbsp;&nbsp;return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

}

//开始任务

void TaskStart(void * pdata)

{

&nbsp;&nbsp;&nbsp;&nbsp;pdata = pdata;

&nbsp;&nbsp;&nbsp;&nbsp;OS_ENTER_CRITICAL();&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;OSTaskCreate(TaskLed, (void * )0, (OS_STK *)&amp;TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio);

&nbsp;&nbsp;&nbsp;&nbsp;OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&amp;TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio);

&nbsp;&nbsp;&nbsp;&nbsp;OSTaskSuspend(START_TASK_Prio); //suspend but not delete

&nbsp;&nbsp;&nbsp;&nbsp;OS_EXIT_CRITICAL();

}

//任务1

//控制DS0的亮灭.

void TaskLed(void *pdata)

{

&nbsp;&nbsp;&nbsp;&nbsp;while(1)

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LED0 = !LED0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSTimeDlyHMSM(0,0,1,100);&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;}

}

//任务2

//控制DS1的亮灭.

void TaskLed1(void *pdata)

{

&nbsp;&nbsp;&nbsp;&nbsp;while(1)

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LED1 = !LED1;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSTimeDlyHMSM(0,0,1,300);&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;}

}</code>

正文开始:

我写的这个调度系统是用stm32 定时器中断调度任务的,任务中不需要ucos那种延时函数,定时器每隔一段时间中断当前任务,保存现场,恢复第二个任务的现场,这时PC寄存器被改为第二个任务上次中断前执行的位置然后退出中断,,从任务二上次中断前的位置继续执行调度原理:

参考<<Cortex-M3权威指南>>中 第九章 中断的具体行为

当 C M 3开始响应一个中断时内核会自动 把 8个寄存器(R0-R3,R12,LR,PC,xPSR)的值压入栈,最关键的是PC,他直接决定了中断退出以后开始执行的位置,R0-R3,R12则保存了一些中间变量,保证了恢复现场以后程序正确执行

程序流程:                                                                       标志:↓↓↓

进入main() ----> 初始化GPIO,时钟,定时器,开中断 ---->进入任务0 ---->定时器中断时间到 ---->开始进入中断 ---->系统自动把8个寄存器(R0-R3,R12,LR,PC,xPSR)的值压入栈 ---->进入中断函数TIM3_IRQHandler(此时SP堆栈指针正指向R0,R0+4后,指向R1)

<code class="lang-cpp">TIM3_IRQHandler PROC

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PUSH&nbsp;&nbsp;&nbsp;&nbsp; {r4,lr}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r4,MSP

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,r4

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,r0,#8

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r4,r0

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,|L0.640|

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r4,[r0,#0]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRQHandler

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;POP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{r4,pc}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

extern Task *task;

int main(void)

{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;task = new Task(); //创建任务管理对象 这是一个C++类对象

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;Init();//初始化 时钟 串口 GPIO

&nbsp;&nbsp;&nbsp;&nbsp;Timerx_Init(20,7199);//初始化TIM3,开中断,每2ms进一次中断

&nbsp;&nbsp;&nbsp;&nbsp;TIM3-&gt;CNT = 0x01;//意义不明 不要也行

&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;&nbsp;//內联汇编

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bl Task0 //跳转到任务1

&nbsp;&nbsp;&nbsp;&nbsp;}

//&nbsp;&nbsp;while (true);

//&nbsp;&nbsp;delete task;

}

int temp = 0;

void Task0(void) //任务1

{

&nbsp;&nbsp;&nbsp;&nbsp;while (true)

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LED0 = !LED0;

&nbsp;&nbsp;&nbsp;&nbsp;}

}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

void Task1(void) //任务2

{

&nbsp;&nbsp;&nbsp;&nbsp;while (true)

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LED1 = !LED1;

&nbsp;&nbsp;&nbsp;&nbsp;}

}</code>

<code class="lang-cpp">class Task //任务管理类

{

public:Task(void) //构造函数,初始化时会自动调用

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reg_Buff[0][6]=((unsigned int)&amp;Task0) ; //初始化任务0的指针

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reg_Buff[1][6]=((unsigned int)&amp;Task1) ; //初始化任务1的指针

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reg_Buff[0][6]=Reg_Buff[1][7]=0x61000000 ; //初始化xRSP

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Current = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Next = 1;

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;public: static const unsigned char Count = Task_Count;

&nbsp;&nbsp;&nbsp;&nbsp;public: unsigned char Current; //当前任务

&nbsp;&nbsp;&nbsp;&nbsp;public: unsigned char Next ;&nbsp;&nbsp;&nbsp;&nbsp;//下一个任务

&nbsp;&nbsp;&nbsp;&nbsp;public: volatile unsigned int Reg_Buff[Task_Count][8];

&nbsp;&nbsp;&nbsp;&nbsp;public: void&nbsp;&nbsp;&nbsp;&nbsp;Start_Next() //更新至下一个任务

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Current + 1 &lt; Count) ? Current++ : Current = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Next + 1 &lt; Count) ? Next++ : Next = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Next != 0 &amp;&amp; (Next - Current) != 1)

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (true)

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

};</code><code class="lang-cpp">Task *task ;

unsigned int Address_BASE = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

void IRQHandler(void)

{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIM_ClearITPendingBit(TIM3, TIM_IT_Update);&nbsp;&nbsp;//清除TIMx的中断待处理位:TIM 中断源

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE]&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][0]]//R0

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0x4]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][1]]//R1

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0x8]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][2]]//R2

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0xc]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][3]]//R3

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0x10]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][4]]//R12

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0x14]

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][5]]//R13 LR

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0x18]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][6]]//R14 PC

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [Address_BASE , 0x1c]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [&amp;task-&gt;Reg_Buff[task-&gt;Current][7]]//R15 xRSP

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*↑↑↑保存当然运行中的任务现场↑↑↑*/

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][0]]//R0

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][1]]//R1

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0x4]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][2]]//R2

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0x8]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][3]]//R3

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0xc]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][4]]//R12

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0x10]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][5]]//R13 LR

//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0x14]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][6]]//R14 PC

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//orr r5, 0x01

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0x18]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ldr r5, [&amp;task-&gt;Reg_Buff[task-&gt;Next][7]]//R15 xRSP

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r5, [Address_BASE, 0x1c]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*↑↑↑恢复上一个任务的现场↑↑↑*/

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;task-&gt;Start_Next(); //下一个任务

&nbsp;&nbsp;&nbsp;&nbsp;}

}

extern "C"

{

&nbsp;&nbsp;&nbsp;&nbsp;void TIM3_IRQHandler(void)&nbsp;&nbsp; //TIM3中断&nbsp;&nbsp;中断中不能有太多东西,否则进中断时压栈太多 MSP不容易计算

&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__ASM

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mrs r4, msp

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add r4, 0x08

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str r4, [&amp;Address_BASE]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bl&nbsp;&nbsp;&nbsp;&nbsp;IRQHandler

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

}</code>

最后

以上就是自信寒风为你收集整理的c语言实现stm32多线程,自己动手写STM32多任务调度器的全部内容,希望文章能够帮你解决c语言实现stm32多线程,自己动手写STM32多任务调度器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部