手写RTOS(课程回顾)

2023-05-16

什么是程序

X86
X86在调用函数的时候传递在参数是从栈中取出的,需要哪些参数提前按一定顺序入栈即可。第一个出栈的就对应第一个参数,依次类推。函数返回值存在eax中。
ARM
arm函数调用参数传递顺序是从r0~r3,第一个参数在r0中,第二个参数在r1中,依次类推。参数超过4个,则要先入栈,从第五个参数开始从栈中取。函数返回值放在r0中。

手写RTOS(课程回顾)

基于模板https://gitee.com/zeng-hanhan/hand-write-rtos
模板已经实现
1)自定义串口输出打印函数,2)定时器中断功能,3)可在模拟器运行 。。。。。

创建目录: rtos 文件:task.c task.h

工程目录结构:
请添加图片描述

核心

请添加图片描述

task.c文件:

实现创建任务函数

第一次运行任务,需要初始化栈,将 返回地址 设置为 任务函数指针。
中断结束就跳转到 该地址 执行。

请添加图片描述

void create_task(task_function *f, void *param, char *stack, int stack_len){
	int *top = (int *)(stack + stack_len);
	/* 伪造现场 */
	top -= 16;
	// r4~r11
	top[0] = 0;
	top[1] = 0;
	top[2] = 0;
	top[3] = 0;
	top[4] = 0;
	top[5] = 0;
	top[6] = 0;
	top[7] = 0;
	// r0~r3
	top[8] = (int)param;
	top[9] = 0;
	top[10] = 0;
	top[11] = 0;
	// r12 lr
	top[12] = 0;
	top[13] = 0;
	// 返回地址 任务入口
	top[14] = (int)f;
	//psr
	top[15] = (1<<24);//指令集
	/* 记录栈的位置 */
	task_stacks[task_count++] = (int)top;
}

开始任务函数: 将全局变量 task_running 置为1 ,实际在中断中开启执行任务
定时器中断时检测该变量,是否创建任务,避免还没创建任务就在中断运行。

void task_start(void){
	task_running = 1;
	while(1);
}

中断

中断函数为汇编,

保存现场后调用c函数 SysTick_Handler

SysTick_Handler_asm PROC
				;保存r4~r11
				STMDB SP!,{R4 - R11}
				STMDB SP!,{LR}
				
				MOV R0, LR	;LR是特殊值
				ADD R1, SP, #4
				
				BL SysTick_Handler	;不破坏r4~r11
				
				LDMIA SP!, {R0} 
				LDMIA SP!, {R4 - R11} 
				
				BX R0
				ENDP

SysTick_Handler 函数:
int cur_task:全局变量 当前任务
int is_task_running(void): 函数 判断是否有任务已经创建
int get_stack (int task_index): 获取任务的栈
void set_task_stack(int task,int sp): 修改 task 的栈顶为sp
均在 task.c 实现

判断要 ”创建任务” 还是 ”启动第一个任务” 还是 ”切换任务”
如果还没创建任务直接返回, 相当于啥也不做
启动第一个任务设置当前任务 cur_task = 0,
跳到 StartTask_asm运行,从当前任务的栈中恢复寄存器
效果是把伪造的现场写入寄存器后结束中断并从伪造的 返回地址(任务入口函数) 运行。
** 切换任务 **在中断发生就已经保存了所有寄存器
只需要获取下一个任务栈,把栈和特殊的 lr 值交给 StartTask_asm 汇编函数 恢复下一个任务的寄存器 开始下一个任务的执行。

void SysTick_Handler(int LR,int old_sp)
{
	int stack, pre_task, new_task;
	
	SCB_Type * SCB = (SCB_Type *)SCB_BASE_ADDR;
	
	/* clear exception status */
	SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
	
	/* 如果还没创建任务  */
	if(!is_task_running()){
		return;
	}
	/* 启动第一个任务或者切换 */	
	if(cur_task == -1){
		/* 启动第一个任务 */
		cur_task = 0;
		/* 从栈恢复寄存器 */
		//
		stack = get_stack(cur_task);
		StartTask_asm(stack, LR);		/* 开始任务需要把栈中的值读入到 寄存器 用汇编做 */
	}
	else{
		/* 切换任务 */
		pre_task = cur_task;
		new_task = get_next_task();	//下一个任务
		
		if(pre_task != new_task){
			/* 保存pre_task:r4~r11 
			 * 在汇编中已经保存
			 */
			
			/* 更新sp */
			set_task_stack(pre_task, old_sp);
			
			/* 切换new_task */
			stack = get_stack(new_task);
			cur_task = new_task;
			StartTask_asm(stack, LR);
		}
	}

StartTask_asm

从任务栈恢复寄存器

StartTask_asm PROC
				;从任务的栈 把r4-r11读出来写入寄存器
				;r0存有任务的栈 r1有LR(特殊的值)
				LDMIA R0!, {R4 - R11} 		
				;更新SP
				MSR MSP, R0
				;触发硬件中断返回; 
				BX R1
				
				ENDP
ROC
				;从任务的栈 把r4-r11读出来写入寄存器
				;r0存有任务的栈 r1有LR(特殊的值)
				LDMIA R0!, {R4 - R11} 		
				;更新SP
				MSR MSP, R0
				;触发硬件中断返回; 
				BX R1
				
				ENDP
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手写RTOS(课程回顾) 的相关文章

  • 通过Linux学习RTOS

    通过Linux学习RTOS 原文 xff1a http blog csdn net zoomdy article details 50549901 mingdu zheng at gmail dot com RTOS应用很广 xff0c 种
  • RTOS信号量、邮箱、队列与事件

    一 定义 信号量 xff0c 邮箱 xff0c 队列的最大不同在于它们发送的内容不同 1 信号量是一个触发信号 xff0c 也是一个计数器 xff0c 等待接收信号的任务一般只有接收到信号才可以执行 xff0c 否则任务一直暂停 xff08
  • HW-RTOS 概述

    文章目录 1 背景介绍1 1 OS 实时难题1 2 Linux 实时补丁1 3 Xenomai 43 Linux 双内核1 4 HW RTOS1 5 More 2 优化点1 xff1a API2 1 原理介绍2 1 1 Software A
  • STM32使用RTOS BootLoader跳转app进入异常中断问题

    一 问题描述 在boot中不使用RTOS xff0c 跳转到APP中 xff0c APP可以正常运行 但是boot中使用RTOS跳转到APP中 xff0c 程序配置完时钟后就会进入MemManage Handler错误中断 二 解决方法 1
  • RTOS流和消息缓冲器

    RTOS流和消息缓冲器 任务间通信和同步 可从FreeRTOS V10 0 0获得 介绍 流缓冲区是 RTOS任务 的RTOS任务 xff0c 并且是任务通信原语的中断 与大多数其他FreeRTOS通信原语不同的是 xff0c 它们针对单读
  • 基于Cortex-M的RTOS上下文切换详解及FreeRTOS实例

    文章目录 1 Cortex M MCU特性 1 1 操作模式 1 2 寄存器 1 2 1 核心寄存器 1 2 2 浮点寄存器 Floating Point registers 1 2 3 特殊寄存器 Special Registers 1
  • NuttX RTOS

    目录 综述 NuttX是什么 看看这些文件和功能 它怎么会是一个小小的操作系统呢 xff1f NuttX讨论组 你想谈谈NuttX的特性吗 xff1f 你需要帮助吗 xff1f 问题吗 错误吗 下载 我在哪里可以买到NuttX xff1f
  • RT-Thread uart2串口dma idle接收不断帧

    硬件STM32F407 IDE使用RT Thread Studio uart2串口使用这两个引脚 功能 IO端口 UART2 TX PA2 UART2 RX PA3 UART2 DMA接收配置 先使能DMA接收 RX缓冲区可以稍微调大些 b
  • Threadx 定时器timer

    文章目录 定时器管理结构 定时器链表 定时器激活链表 定时器工作原理 定时器API 定时器创建 tx timer create 删除定时器 tx timer delete 修改 tx timer change Threadx 操作系统定时器
  • Azure RTOS定价(ThreadX 等)

    Azure RTOS定价 Azure RTOS定价 https azure microsoft com zh cn pricing details rtos 使嵌入式 IoT 开发和连接变得轻松 Azure RTOS 是一种易于使用 经过市
  • PlatformIO - 静态代码分析(Static Code Analysis)

    关于 静态代码分析 相信大部分的嵌入式开发者或多或少在日常的开发中都有所了解 但可能在实际的开发中我们使用的并不多也不习惯通过工具对我们编写的代码进行静态扫描而是完全依赖于在开发板上运行然后基于运行结果来判断自己所编写的代码的好坏 是否有b
  • FreeRTOS(1):任务

    目录 一 FreeRTOS 介绍 什么是 FreeRTOS 为什么选择 FreeRTOS FreeRTOS 资料与源码下载 FreeRTOS 实现多任务的原理 二 移植 FreeRTOS 到STM32 手动移植 使用CubeMX快速移植 快
  • [uC/OS-III] 22. 互斥量

    1 互斥量的基本概念 互斥量又称互斥信号量 本质也是一种信号量 不具备传递数据功能 是一种特殊的二值信号量 它和信号量不同的是 它支持互斥量所有权 递归访问以及防止优先级翻转的特性 用于实现对临界资源的独占式处理 任意时刻互斥量的状态只有两
  • FreeRTOS-创建删除任务

    1 FreeRTOSConfig h文件 FreeRTOSConfig h配置文件作用 对FreeRTOS进行功能配置和裁剪 以及API函数的使能 相关的宏可以分为三大类 INCLUDE 配置FreeRTOS中可选的API函数 config
  • 自己动手写RTOS:02-在M3内核上实现pendsvc

    自己动手写RTOS 自己动手写RTOS 01基础知识和理论部分 自己动手写RTOS 02 在M3内核上实现pendsvc 文章目录 自己动手写RTOS 一 M3内核的相关知识 1 1寄存器 1 2特殊寄存器 1 3堆栈 二 pendSVC实
  • Nuttx操作系统(三):构建模式

    1 1 Nuttx构建配置以及模式 Nuttx有三种不同的构建配置 FLAT构建 这种构建是所代码驻留在公共地址空间中 1 应用 内核以及board logic在一个flat地址环境中 2 所有的地址空间具有相同的属性 PROTECTED构
  • 将 DKM 项目链接到内核映像 (VIP) 项目作为 VxWorks Workbench4 中的子项目/额外模块

    如何将 DKM 项目与内核映像 VIP 项目链接 加载 以便我可以从内核映像项目的 usrAppInit c 调用 DKM 项目 应用程序 的入口点函数 以在启动时自动启动应用程序 有人可以描述步骤或向我指出任何文档吗 将 DKM 项目添加
  • 抢占和上下文切换的区别

    一点介绍 我目前正在编写一个小型 读微型 RTOS 内核 它应该与内核中的大多数内容是一体的 然而 我找不到关于下面列出的一些事情的太多信息 这会很有帮助 除此之外 它实际上不是某种大学项目 而是我按照自己的意愿做的事情 回答所有问题的一个
  • Micriμm μC/OS-III RTOS 中的分配和释放

    我们使用 Micrium 的 C OS III RTOS 和 Renesas 的 RX62N 我们构建了一个必须动态分配和释放数据的系统 我们发现了功能malloc and free 与 RTOS 配合得不好 然而 RTOS 为此提供了一个
  • 开始使用 Real Time Linux 编程的最佳方式是什么?

    虽然我用C实现了很多项目 但我对操作系统完全陌生 我在 Discovery board STM32 上尝试了实时 Linux 并得到了闪烁 LED 的正确结果 但我并没有真正理解整个过程 因为我只是按照步骤操作 并且无法在互联网上找到每个步

随机推荐

  • 工薪族巧理财之定期存款中整存整取、零存整取、存本取息之间的微妙区别

    银行的官方术语先给大家普及一下 xff1a 定期存款是在存款时约定存储时间 一次或按期分次 在约定存期 存入本金 xff0c 整笔或分期平均支取本金利息的一种储蓄 按存取方式定期存款分为整存整取定期存款 零存整取定期存款 存本取息定期存款
  • no module named win32com.client错误解决

    无论什么时候 xff0c 你在运行的时候发现有importError no module named win32com client这个提示 你都可以这么解决 xff1a 请下载http sourceforge net projects p
  • java.util.concurrent同步框架(AQS论文中文翻译)

    java util concurrent同步框架 摘要目录和主题描述一般条款关键字1 介绍 xff1a 需求设计实现4 使用方式5 性能6 结论7 致谢 Doug Lea SUNY Oswego Oswego NY 13126 dl 64
  • POJ2287 田忌赛马---贪心算法

    田忌赛马 题目详见http poj org problem id 61 2287 田忌赛马大家都听过 xff0c 可是如果不是上中下三等马 xff0c 而是很多匹马 xff0c 优劣有很多种分类 xff0c 就不仅仅是321的问题了 这个很
  • 贪心算法详解

    之前讲过动态规划DP xff0c 现在来说说贪心 贪心算法在解决问题的策略上目光短浅 xff0c 只根据当前已有的信息就做出选择 xff0c 而且一旦做出了选择 xff0c 不管将来有什么结果 xff0c 这个选择都不会改变 也就是说贪心对
  • 搜索智能提示suggestion,附近点搜索

    第三十六 三十七章 搜索智能提示suggestion xff0c 附近地点搜索 作者 xff1a July 致谢 xff1a caopengcs 胡果果 时间 xff1a 二零一三年九月七日 题记 写博的近三年 xff0c 整理了太多太多的
  • 多重继承及虚继承中对象内存的分布

    多重继承及虚继承中对象内存的分布 这篇文章主要讲解G 43 43 编译器中虚继承的对象内存分布问题 xff0c 从中也引出了dynamic cast和static cast本质区别 虚函数表的格式等一些大部分C 43 43 程序员都似是而非
  • Linux日志服务器配置

    配置日志服务器 环境 xff1a tibet xff1a 10 11 3 57 gaplinux xff08 日志服务器 xff09 xff1a 10 11 3 3 修改tibet上的 etc hosts xff0c 增加如下代码 xff1
  • 【Google】25匹马的角逐

    问题是这样的 xff1a 一共有25匹马 xff0c 有一个赛场 xff0c 赛场有5个赛道 xff0c 就是说最多同时可以有5匹马一起比赛 假设每匹马都跑的很稳定 xff0c 不用任何其他工具 xff0c 只通过马与马之间的比赛 xff0
  • HDOJ 1058 Humble Numbers解题报告【DP】

    Humble Numbers 题目详见http acm hdu edu cn showproblem php pid 61 1058 开始拿到这个题目的时候还纠结了半天 xff0c 英语很差的话这个题是不可能AC的 而我就是其中之一 Hum
  • 背包问题详解

    背包问题 背包问题 Knapsack problem 是一种组合优化的NP完全问题 问题可以描述为 xff1a 给定一组物品 xff0c 每种物品都有自己的体积和价值 xff0c 在限定的总体积内 xff0c 我们如何选择 xff0c 才能
  • 楼教主男人必解八题之 Coins 解题报告

    楼教主男人必解八题之 Coins 解题报告 题目详见http acm hdu edu cn showproblem php pid 61 2844 这个题目和POJ1742是一个题目 xff0c 也是楼教主的男人八题之一 说的是给出N种硬币
  • 如何证明程序的正确性?

    什么样的程序才是正确的 xff1f 如何来保证程序是正确的 xff1f 测试 xff1f NO xff01 采用测试方法确实可以发现程序中的错误 xff0c 但却不能保证和证明程序中没有错误 xff01 先来看一些概念 xff0c 有关 程
  • 平摊分析

    平摊分析 我们经常在处理数据结构的时间复杂度的时候 xff0c 大多数操作代价很低 xff0c 可是由于某些个别操作的代价较高 xff0c 导致最后求得时间复杂度的上界不是那么的紧凑 在平摊分析中 xff0c 执行一系列数据结构操作所需要的
  • intel realsense t265+rtabmap实现地形扫描(效果欠佳)

    1 intel realsense t265驱动安装 https blog csdn net crp997576280 article details 109544456 2 Rtabmap 安装 https blog csdn net z
  • Windows10下RTABMAP+T265实现三维建图

    安装Rtabmap xff1a Installation introlab rtabmap Wiki github com 文件为RTABMap 0 20 16 win64 cuda11 1 exe 安装intel realsense t2
  • 树莓派3B+(以及老版本)内网穿透 frp 后外网ssh或者vrc server连接

    1 服务器配置 xff0c 服务器选择Debian 或者 CentOS 开一个服务器 然后用ssh连上 xff0c ssh可以用本地xshell或putty连接 也可以用网页版ssh连接 先进入管理员模式 xff0c 免得后面一直sudo
  • 在雪豹10.6.2(Mac OS X)上安装Oracle10g

    1 Install preparation 基本环境 xff1a Snow Leopard10 6 2 xff0c Oracle10 2 0 4 打开Mac的终端 xff0c 执行 xff1a sudo i 创建oinstall组和orac
  • 一个开源AC算法源码分析

    ps1 本文不讲AC算法的原理及数学证明 xff0c 具体请参考这篇文章 xff1a efficient string matching an aid to bibliographic search pdf ps2 源码主页 xff1a m
  • 手写RTOS(课程回顾)

    什么是程序 X86 X86在调用函数的时候传递在参数是从栈中取出的 xff0c 需要哪些参数提前按一定顺序入栈即可 第一个出栈的就对应第一个参数 xff0c 依次类推 函数返回值存在eax中 ARM arm函数调用参数传递顺序是从r0 r3