c语言实现stm32多线程,自己动手写STM32多任务调度器

本文介绍了如何使用C语言在STM32上自制一个基于定时器中断的任务调度系统,避免了如UCOS等操作系统中每个任务必须包含延时函数的限制。通过定时器中断切换任务,保存和恢复任务现场,实现了多任务的并行执行。详细讨论了寄存器的使用,以及任务调度的关键步骤和代码实现。
摘要由CSDN通过智能技术生成

首先介绍几个寄存器,这几个寄存器只能在汇编或内联汇编时才能访问,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;&n

  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值