基于stm32的简单多任务切换设计

发布者:自由探索最新更新时间:2018-08-31 来源: eefocus关键字:stm32  多任务切换 手机看文章 扫描二维码
随时随地手机看文章

系统数据:

1)当前的PID

2)所有的进程总数PAMOUNT

 

//多任务系统的初始化

1.  设置MSP值

2.  设置临时的PSP值(因为这段实际上只在启动定时器之前有效)

3.  设置CONTROL[1]=1(设置双堆栈),马上会自动切换到PSP上

4.  设置PID=0,设置PAMOUNT=0

5.  设置为进程信息表起始地址到PLIST(注意进程信息表是向上生长的)

6.  设置为进程堆栈分配的起始地址到PSTACK(堆栈是向下生长的)

//调用AddTask添加任务

1.      写入配置信息到任务表中(任务起始地址,堆栈地址(首次进行分配)xPSR等等)

a)        至于输入参数,就存放在任务的堆栈中

//启动任务切换

1.  设置SysTick定时器的详细配置(定时间,开中断)

2.  启动定时器

//进程的切换过程

1.      当中断触发时,硬件会按照下表自动进行寄存器的入栈(如果当响应异常时,当前的代码正在使用PSP,则压入PSP,即使用线程堆栈;否则压入MSP,使用主堆栈。一旦进入了服务例程,就将一直使用主堆栈),通常Systick中断都是在PSP的情况下发生的,所以数据压入PSP中。



2.      入栈完毕,将堆栈切换到MSP,开始执行SysTick服务程序:

a)        将当前的堆栈切换为MSP

b)        取得进程堆栈指针,将堆栈指针备份到PID备份区域

c)        将R4到R11存储到PID对应的程序堆栈区域

d)        开始执行程序计算下一个PID=PID+1>PAMOUNT?1: PID+1;

e)        读取下一个PID进程堆栈指针,并将堆栈中的备份恢复到到R4到R11寄存器中

f)         将下一个进程PID的堆栈地址(弹出r4-r11后的地址)写到psp中

g)        进行中断返回,同时这样会触发中断返回的硬件过程,硬件会将堆栈切换为PSP并将PSP的内容恢复到相应寄存器中

3.      出栈完毕,硬件自动清除NVIC寄存器

4.      现场恢复完毕,继续执行任务

 

//任务的退出

1.      在写入进程信息的时候,已经把lr寄存器的值设置成为了ExitTask函数的地址,所以,当函数退出之后,会自动执行收尾。

 

 

 

补充资料:

1.      关于堆栈

a)        堆栈是向下生长的

b)        堆栈指针总是指向最后被压入堆栈的数据

c)        只有在CONTROL[1]=1时,才会使用双堆栈

d)        因为 C M 3 使用的是向下生长的满栈,所以 MSP 的初始值必须是堆栈内存的末地址加1 。
举例来说,如果你的堆栈区域在 0x20007C00 ‐ 0x20007FFF 之间,那么 MSP 的初始值就必须是0 x 20008000。

e)        在handler模式下CONTROL[1]不可以写入1,但是可以读取PSP的值

f)         堆栈的地址指针会和4对齐,例如:向sp写入0x20006001或者0x20006002或者0x20006003时,会自动变成0x20006000,而写入0x20006004就是直接写入0x20006004

g)        堆栈总是指向最后一个元素的,当写入四个字节的字时,会先指针减去4,再进行入栈。当堆栈指针为sp=0x20006004时,写入一个字  0x12345678时,会在0x20006000字节、0x20006001字节、0x20006002字节、0x20006003字节分别写入0x78、0x56、0x34、0x12。要想执行类似的操作可以使用存储指令(例如str)将数据存到0x20006000单元,会达到相同的效果


关键字:stm32  多任务切换 引用地址:基于stm32的简单多任务切换设计

上一篇:STM32学习之:定时器 软件计时
下一篇:STM32实验1:定时器中断同时产生两路不同频率的信号

推荐阅读最新更新时间:2024-03-16 16:12

STM32——EEPROM
一、I2C接口读写EEPROM(AT24C02) ——主模式,分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。 1、I2C接口初始化 与其他对GPIO 复用的外设一样,它先调用了用户函数I2C_GPIO_Confi g() 配置好 I 2 C 所用的 I/O端口,然后再调用用户函数 I2C_Mode_Confi gu() 设置 I 2 C 的工作模式,并使能相关外设的时钟。 void I2C_EE_Init(void) { I2C_GPIO_Config(); I2C_Mode_Config(); /* 根据头文件 i2c_ee. 14 h 中的定义来选择 EEPROM 要写入的地址 */
[单片机]
<font color='red'>STM32</font>——EEPROM
STM32启动代码学习
第一部分:汇编指令学习 1.伪指令 1).EQU EQU伪指令:用来为一个数字常量、或一个和内核寄存器相关的数值或一个和程序计数器相关的数值定义的一个符号名称。类似于C语言中的#define 。 格式: name EQU expr{ , type} 格式: 名称 EQU 表达式(,类型) 例如: Stack_Size EQU 0X00000400 //定义1k字节的栈空间 Heap_Size EQU 0x00000200 //定义512字节的堆空间 2).AREA AREA伪指令:用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如:|1_test| 。 格式:
[单片机]
<font color='red'>STM32</font>启动代码学习
使用gcc工具链进行Linux环境下的stm32开发
处于好奇和学习Linux的目的,准备开始在虚拟机VMware的Ubuntu9.10操作系统下搭建stm32的开发环境。整个过程包括:安装gcc工具链---- 建立工程目录--- 编写Makefile,连接文件--- 编译生成可执行文件--- 下载测试。 我的工程资源:http://download.csdn.net/detail/xiaoxiaoxingkongo/9732047 工程建立参考连接:http://blog.csdn.net/embbnux/article/details/17616809 烧录参考链接:http://blog.csdn.net/ybhuangfugui/article/details/52597
[单片机]
stm32 timer1/pwm 笔记
//--------------------------------TIMER1 先说下RCC时钟 //-------------------------RCC(具体参考所用芯片) AHB所连接的时钟 * RCC_AHBPeriph_DMA1,RCC_AHBPeriph_DMA2,RCC_AHBPeriph_SRAM * RCC_AHBPeriph_FLITF,RCC_AHBPeriph_CRC,RCC_AHBPeriph_FSMC * RCC_AHBPeriph_SDIO APB1所连接的时钟 * RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RC
[单片机]
初学stm32-库函数开发流水灯实现
库函数开发概述 1.库函数开发步骤及总结: 库函数总结. 2.STM32库函数本质上依旧是寄存器编程,只是为了方便应用封装成了函数。所以用户的应用程序也可以绕过库函数,直接对寄存器编程,参考博客: 寄存器开发.。 寄存器编程的代码效率最高。不过,开发难度大,查阅相关手册比较多,开发效率相对低,产品周期长,可维护性较差,可移植性、阅读性差 库函数特性则与寄存器编程相反。在一些代码要求高效率的情况下,对寄存器编程是非常必要的。同时,对寄存器的学习与操作,将非常有助于我们在出错时进行程序调试。 点灯代码实现 led.c void Led_Init(void) { //库函数初始化步骤1:定义一个xxx_InitTy
[单片机]
STM32外设驱动篇——DHT11温湿度传感器
已在STM32上进行过测试。本例使用PC0引脚连接DHT11的data引脚。 main函数中调用下面代码中的DTH11_test函数即可。 //数据定义: //----以下变量均为全局变量-------- //----温度高8位== U8T_data_H------ //----温度低8位== U8T_data_L------ //----湿度高8位== U8RH_data_H----- //----湿度低8位== U8RH_data_L----- //----校验 8位 == U8checkdata----- u8 U8T_data_H,U8T_data_L,U8RH_d
[单片机]
stm325个串口的配置函数 STM32串口如何发送数据
5个串口的配置函数和收发数据函数代码: #include “stm32f10x.h” #include “misc.h” #include “stm32f10x_gpio.h” #include “stm32f10x_usart.h” void USART1_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
[单片机]
stm325个串口的配置函数 <font color='red'>STM32</font>串口如何发送数据
STM32单片机对TFTLCD的驱动设计
看了TFTLCD和FSMC(灵活的静态存储控制器)的简介,还是一知半解,不知所云。 TFTLCD使用80并口,80 并口有如下一些信号线: CS: TFTLCD 片选信号。 WR:向 TFTLCD 写入数据。 RD:从 TFTLCD 读取数据。 D[15: 0]: 16 位双向数据线。 RST:硬复位 TFTLCD。 RS:命令/数据标志( 0,读写命令; 1,读写数据)。 只是记住FSMC在使用的时候要初始化和使能就行了。 关于lcd.c这个文件竟然接近3000行,好吧,我是写不出来,只能在主函数里调用了。 main.c: intmain(void) { u8x=0; u8lcd_id[12];//存放LCDID字符串
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved