开发一个RISC-V上的操作系统(八)—— 抢占式多任务(Preemptive Multitasking)

news2024/11/24 7:40:34

目录

一、抢占式多任务

二、代码实现

三、上板测试


本节的代码在仓库的 06_Preemptive_Muti_Task 目录下,仓库链接:riscv_os: 一个RISC-V上的简易操作系统

本文代码的运行调试会在前面开发的RISC-V处理器上进行,仓库链接:cpu_prj: 一个基于RISC-V指令集的CPU实现

在第五节的内容中,我们实现了协作式多任务,这一节我们要实现的是抢占式多任务。

一、抢占式多任务

我们先回忆一下协作式和抢占式多任务的概念。

  • 协作式多任务(Cooperative Mutitasking):协作式环境下,下一个任务被调度的前提是当前任务主动放弃处理器。
  • 抢占式多任务(Preemptive Multitasking):抢占式环境下,操作系统完全决定任务调度方案,操作系统可以剥夺当前任务对处理器的使用,并且将处理器提供给其他任务

可以看到,在协作式多任务中,需要用户程序主动放弃处理器,其他程序才能运行,这种调度方式十分不合理(万一有一个用户程序不懂谦让,那整个系统就乱了)。

而在抢占式多任务中,任务的调度完全由操作系统决定,采用统一的调度方式,这样就防止了某些用户程序不释放处理器。

在这一节,我们会利用第七节实现的硬件定时器来实现简单的抢占式调度(每个任务运行一个 tick 的时间)。

二、代码实现

大致步骤如下,当中断发生时,进入 trap_handler 函数,如果是定时器中断则进入 timer_handler 函数,在 timer_handler 函数中调用了 schedule 函数,从而实现任务切换的效果:

timer_handler 函数代码如下:

void timer_handler()
{
        timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) & ~(TIMER_INT_PENDING)));
        _tick++;
        printf("tick: %d\n", _tick);

        timer_load(TIMER_INTERVAL);

        schedule();
}

和之前不同的是,context 上下文还需要额外保存 mepc 值,switch_to 函数最后的返回由 ret 改成了 mret(这样switch_to 函数就不需要返回,直接通过 mret 跳转到下一个任务上下文的 mepc 处执行)。 

# void switch_to(struct context *next);
# a0: pointer to the context of the next task
.globl switch_to
.align 4
switch_to:
        # switch mscratch to point to the context of the next task
        csrw    mscratch, a0
        # set mepc to the pc of the next task
        lw      a1, 124(a0)
        csrw    mepc, a1

        # Restore all GP registers
        # Use t6 to point to the context of the new task
        mv      t6, a0
        reg_restore t6

        # Do actual context switching.
        # Notice this will enable global interrupt
        mret

.end

三、上板测试

将程序烧录到板子上后,打开串口调试助手,现象如下:

可以看到任务随着 tick 的增加而切换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/873688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

heap pwn 入门大全 - 1:glibc heap机制与源码阅读(上)

本文为笔者学习heap pwn时,学习阅读glibc ptmalloc2源码时的笔记,与各位分享。可能存在思维跳跃或错误之处,敬请见谅,欢迎在评论中指出。本文也借用了部分外网和其他前辈的素材图片,向各位表示诚挚的感谢!如…

MySQL修改编码

插入中文乱码,我电脑上没有出现,我只是来记录一下 MySQL版本: 8.0.34Windows 查看编码 mysql中输入下面的命令 show variables like ‘character_%’; 乱码的一般是图片中划红线的部分不是utf8 character_set_database是设置数据库的默认编码的 character_set_ser…

面试热题(回文链表)

给定一个链表的 头节点 head ,请判断其是否为回文链表。 如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。 回文链表类似于回文串,正读倒读的顺序是一样的,那么我们怎么去判断一个链表是否是回文链表呢&…

7.2.tensorRT高级(2)-学习深度学习中涉及的线程知识

目录 前言1. 多线程2. 问答环节2.1 线程启动相关问题2.2 线程启动函数参数相关问题 总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次…

7. 延迟队列

延迟队列 7.1. 延迟队列概念 延时队列,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望 在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时间被处理的 元素的队列。 7…

第二章-算法

第二章-算法 数据结构和算法的关系 算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。 算法的特性 算法有五个基本特征:输入、输出、有穷性、确定性和可行性。 输入:算法具…

LVS集群和nginx负载均衡

目录 1、基于 CentOS 7 构建 LVS-DR 群集。 2、配置nginx负载均衡。 1、基于 CentOS 7 构建 LVS-DR 群集。 1.部署LVS负载调度器 1>安装配置工具 [rootnode6 ~]# yum install -y ipvsadm 2>配置LVS虚拟IP(VIP地址) [rootnode6 ~]# ifconfig ens…

Tesseract用OpenCV进行文本检测

我没有混日子,只是辛苦的时候没人看到罢了 一、什么是Tesseract Tesseract是一个开源的OCR(Optical Character Recognition)引擎,OCR是一种技术,它可以识别和解析图像中的文本内容,使计算机能够理解并处理…

Dalsa线阵相机说明(Linea Color GigESeries 2k and 4K)

文章目录 一. Dalsa相机软件整体架构二. 相机编号说明以及软件要求三. 相机硬件参数三. 相机基本参数四. 软件参数设置列表1. Sensor Control Category2. I/O Control Category3. Counter and Timer Control Category4. Advanced Processing Control Category(1) 平场校正介绍(…

蚂蚁聚合支付系统源码完美版+附安装教程

这是我上个月花重金购买的四fang系统源码,现在分享给大家。 源码内附安装教程,20多项功能及安全方面的更新文档,源码说明等,小白也能轻松搭建。 能够轻松应对高并发,等以前版本无法应对的并发问题,也不会被…

JIRA:项目管理的秘密武器

引言 在当今动态且快速变化的商业环境中,项目管理已经成为任何组织成功的关键因素。能够有效地管理项目,保证项目在设定的时间和预算内按照预期的质量完成,是每个项目经理的目标。为了实现这个目标,项目经理需要依赖强大的工具&a…

由于找不到vcruntime140_1.dll,无法继续执行代码该怎么修复呢?

我最近遇到了一个vcruntime140_1.dll的问题,导致我的某些应用程序无法正常运行。当我第一次遇到这个问题时,我对这个dll文件的作用一无所知。我开始搜索并了解了vcruntime140_1.dll是Microsoft Visual C Redistributable的一部分,并为使用Vis…

FreeRTOS(计数信号量)

资料来源于硬件家园:资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、计数信号量的定义与应用 1、计数信号量的定义 2、计数信号量的应用 二、计数信号量的运作机制 1、任务间计数信号量的实现 三、计数信号量常用的API函数 1、计数信号量典型流程…

泛型编程| 模板初阶——懒人福音!

目录 前言介绍 函数模板 函数模板格式 函数模板的原理 函数模板的实例化 隐式实例化 显示实例化 模板参数匹配规则 类模板 总结 前言介绍 之前c语言实现swap函数的时候,我们不仅要修改参数的类型,还要修改函数的名字 而在学完函数重载之后&am…

东南大学齿轮箱故障诊断(Python代码,MSCNN结合LSTM结合注意力机制模型,代码有注释)

运行代码要求: 代码运行环境要求:Keras版本>2.4.0,python版本>3.6.0 1.东南大学采集数据平台: 数据 该数据集包含2个子数据集,包括轴承数据和齿轮数据,这两个子数据集都是在传动系动力学模拟器&am…

Android JNI实现锅炉压力显示系统详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 第一步创建GuoLu.c文件 // // Created by DELL on 2023/8/13. // #include <stdio.h…

Python 潮流周刊#15:如何分析 FastAPI 异步请求的性能?

你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。标题取自其中一则分享&#xff0c;不代表全部内容都是该主题&#xff0c;特此声明。 本周刊精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源…

记录一下关于word存放代码出现的问题

如下图所示&#xff0c;从 Word 中复制代码并粘贴到其他地方&#xff0c;例如文本编辑器或代码编辑器中&#xff0c;有时会出现额外的连字符或破折号。这是因为 Word 使用了特定的字符编码和格式&#xff0c;而这些字符在代码中可能不被支持或解析为特殊字符。   可见有时从…

Java线程调度以及算法

线程调度概况 Java的线程调度程序是JVM的一部分&#xff0c;它决定应该运行哪个线程。无法保证线程调度程序将选择运行哪个可运行线程。 一次只能有一个线程在一个进程中运行。线程调度程序主要使用抢占式或时间切片调度来调度线程。 抢占式调度与时间分片的区别 在抢占式调…

边缘计算:下一代计算模式的突破

章节一&#xff1a;引言 随着物联网、人工智能和大数据等技术的不断发展&#xff0c;计算需求变得越来越复杂&#xff0c;传统的云计算模式已经难以满足快速增长的数据处理需求。在这样的背景下&#xff0c;边缘计算作为一种全新的计算模式崭露头角&#xff0c;为我们带来了更加…