从零手写操作系统之RVOS硬件定时器-05

这篇具有很好参考价值的文章主要介绍了从零手写操作系统之RVOS硬件定时器-05。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


本系列参考: 学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春 整理而来,主要作为xv6操作系统学习的一个前置基础。

RVOS是本课程基于RISC-V搭建的简易操作系统名称。

课程代码和环境搭建教程参考github仓库: https://github.com/plctlab/riscv-operating-system-mooc/blob/main/howto-run-with-ubuntu1804_zh.md

前置知识:

  • RVOS环境搭建-01
  • RVOS操作系统内存管理简单实现-02
  • RVOS操作系统协作式多任务切换实现-03
  • RISC-V 学习篇之特权架构下的中断异常处理
  • 从零手写操作系统之RVOS外设中断实现-04

RISC-V 定时器中断

定时器中断属于本地中断的一类:
从零手写操作系统之RVOS硬件定时器-05

Core Local INTerrupt:

从零手写操作系统之RVOS硬件定时器-05
Core Local Interrupt(CLINT)是一个与处理器核心相关的中断控制器,它负责处理特定核心的计时器中断和软件中断。

CLINT位于RISC-V系统中的物理内存地址空间,它是一个全局共享的设备,被所有的处理器核心共享和访问。CLINT的作用是为每个处理器核心提供计时器中断和软件中断的控制。

CLINT通常具有以下功能和组成部分:

  1. Timer Interrupts(计时器中断):CLINT包含一个或多个计时器,用于生成定时中断。每个计时器都与特定的处理器核心关联,当计时器计数达到预设的值时,CLINT会生成一个中断信号,通知相应的处理器核心。

  2. Software Interrupts(软件中断):CLINT可以接收来自处理器核心的软件中断请求。软件中断是由软件代码触发的一种中断请求,用于实现系统调用、任务切换和异常处理等功能。

  3. 中断控制寄存器(Interrupt Control Registers):CLINT包含一组用于配置和控制中断的寄存器,包括计时器设置寄存器、中断使能寄存器、中断优先级寄存器等。这些寄存器用于配置中断参数、使能或禁用中断,并设置中断的优先级。

总而言之,CLINT是一个处理器核心本地的中断控制器,它提供定时器中断和软件中断的功能,并通过相关的寄存器进行配置和控制。每个处理器核心都可以访问和配置CLINT,以实现对中断的管理和处理。


RISC-V CLINT 介绍

从零手写操作系统之RVOS硬件定时器-05

寄存器 (Timer 部分)

从零手写操作系统之RVOS硬件定时器-05

全局唯一,表示即使存在多个核,也只会存在一个mtime寄存器

mtime是RISC-V架构中的一个特殊寄存器,用于表示机器模式下的计时器值。它是Machine Timer(机器计时器)的缩写。

mtime寄存器通常由硬件提供,用于跟踪系统运行的时间。它的值会不断增加,可以用于测量程序的执行时间、进行时间相关的操作和调度等。

在RISC-V中,mtime寄存器是一个64位的寄存器,可用于测量长时间间隔,通常以时钟周期或计时器滴答数的形式表示。它的精度和计时精度取决于硬件实现和操作系统的支持。

在操作系统或应用程序中,可以使用mtime寄存器来实现计时器、延时函数、性能统计等功能。通过读取mtime寄存器的值,可以获得当前的计时器数值,进而进行时间计算和处理。

需要注意的是,访问mtime寄存器通常需要特权级别的权限。在特权级别较低的用户态,可能无法直接读取或写入mtime寄存器,需要通过系统调用或特权级别切换来访问。具体的访问权限和操作方式取决于系统的实现和配置。

  • mtime寄存器的递增原理是由硬件实现确定的,通常是由时钟或计时器驱动的。

  • 在一个基于时钟的系统中,系统时钟会以固定的频率进行振荡,产生一个稳定的时钟信号。这个时钟信号会被用作各种硬件模块和功能的时序控制。

  • mtime寄存器会根据系统时钟信号的脉冲进行递增。每当一个时钟脉冲到达,mtime寄存器的值会自动加1。这样,随着时钟信号的不断变化,mtime寄存器的值也会不断地增加。

  • 递增速度取决于时钟的频率。如果系统时钟频率为1 MHz,那么每秒钟mtime寄存器的值就会增加1000000。因此,可以根据mtime寄存器的递增速度来进行时间计算和测量。

  • 需要注意的是,mtime寄存器的递增是硬件自动完成的,无法通过软件或程序直接控制。程序可以通过读取mtime寄存器的值来获取当前的计时器数值,但无法直接修改或控制其递增过程。递增过程是由硬件实现和时钟信号控制的,程序只能观察和利用其递增的结果。

从零手写操作系统之RVOS硬件定时器-05
mtimecmp寄存器是RISC-V架构中的一个定时器比较寄存器(Timer Compare Register)。它用于与mtime寄存器进行比较,以实现定时器中断的触发。

mtime寄存器的值与mtimecmp寄存器的值相等时,会触发一个定时器中断。这种机制允许程序根据需要设置定时器中断的触发时机。

具体而言,程序可以通过向mtimecmp寄存器写入一个比较值,来指定何时触发定时器中断。当mtime寄存器的值达到或超过这个比较值时,定时器中断被触发,执行相应的中断处理程序。

通过使用mtimecmp寄存器,程序可以实现定时器相关的功能,如定时任务调度、时间片轮转调度、精确延时等。它为程序提供了一种基于时间的触发机制,使得程序能够按照预定的时间间隔执行特定的操作。

需要注意的是,具体的定时器中断触发机制和中断处理程序的实现方式可能会有所不同,取决于具体的处理器和操作系统。程序需要根据所使用的平台和系统进行相应的配置和编程。

硬件定时器初始化代码如下:

/* 10000000 ticks per-second */
#define CLINT_TIMEBASE_FREQ 10000000

/* interval ~= 1s */
#define TIMER_INTERVAL CLINT_TIMEBASE_FREQ


void timer_init()
{
	/*
	 * On reset, mtime is cleared to zero, but the mtimecmp registers 
	 * are not reset. So we have to init the mtimecmp manually.
	 */
	//定时器模块初始化---传入interval间隔大约为1s
	timer_load(TIMER_INTERVAL);

	/* enable machine-mode timer interrupts. */
	//开启次级中断中的定时器中断
	w_mie(r_mie() | MIE_MTIE);

	/* enable machine-mode global interrupts. */
	//开启全局中断
	w_mstatus(r_mstatus() | MSTATUS_MIE);
}
/* load timer interval(in ticks) for next timer interrupt.*/
void timer_load(int interval)
{
	/* each CPU has a separate source of timer interrupts. */
	//获取当前hartId
	int id = r_mhartid();
	//设置mtimecmp寄存器的值为mtime寄存器的值+interval
	*(uint64_t*)CLINT_MTIMECMP(id) = *(uint64_t*)CLINT_MTIME + interval;
}

经过如上设置后,大约1秒后,会触发一次时钟中断。


从零手写操作系统之RVOS硬件定时器-05
mtime中断发生时,处理器核心(hart)会设置mip寄存器的MTIP位,表示发生了定时器中断。

在处理定时器中断时,通常需要在mtimecmp寄存器中写入新的值以清除mip.MTIP位。具体的操作步骤如下:

  1. 响应定时器中断,进入中断处理程序。
  2. 在中断处理程序中,读取mtime寄存器的当前值,可以使用类似于uint64_t curr_time = r_mtime();的方式获取。
  3. 根据需要,计算下一个定时器中断应该发生的时间,得到一个新的比较值。
  4. 将新的比较值写入mtimecmp寄存器,以设置下一个定时器中断的触发时刻。
  5. 清除mip寄存器的MTIP位,以告知处理器中断已经处理完毕。可以使用类似于w_mip(r_mip() & ~MIP_MTIP);的方式清除。

通过在中断处理程序中更新mtimecmp寄存器,程序可以实现周期性的定时器中断,不断触发指定时间间隔的操作。同时,清除mip.MTIP位可以确保处理器核心在中断处理程序执行完毕后正确地处理下一个定时器中断。

需要注意的是,具体的操作方式可能因处理器和操作系统的不同而有所差异。因此,以上描述仅为一般情况下的操作流程,具体的实现方式需要参考所使用的平台和系统的文档或相关编程接口。

我们需要在trap_handler处理函数中新增对定时器中断的处理:

reg_t trap_handler(reg_t epc, reg_t cause)
{
	reg_t return_pc = epc;
	reg_t cause_code = cause & 0xfff;
	
	if (cause & 0x80000000) {
		/* Asynchronous trap - interrupt */
		switch (cause_code) {
		case 3:
			uart_puts("software interruption!\n");
			break;
	    //新增对定时器中断的处理		
		case 7:
			uart_puts("timer interruption!\n");
			timer_handler();
			break;
		case 11:
			uart_puts("external interruption!\n");
			external_interrupt_handler();
			break;
		default:
			uart_puts("unknown async exception!\n");
			break;
		}
	} else {
		/* Synchronous trap - exception */
		printf("Sync exceptions!, code = %d\n", cause_code);
		panic("OOPS! What can I do!");
		//return_pc += 4;
	}

	return return_pc;
}

从零手写操作系统之RVOS硬件定时器-05

  • 定时器中断具体处理函数
void timer_handler() 
{ 
    //记录定时器中断触发次数
	_tick++;
	printf("tick: %d\n", _tick);
    //设置下一次定时器中断触发时机
	timer_load(TIMER_INTERVAL);
}

总体框架流程

从零手写操作系统之RVOS硬件定时器-05


硬件定时器的应用

时间管理

从零手写操作系统之RVOS硬件定时器-05
从零手写操作系统之RVOS硬件定时器-05

/* interval ~= 1s */
#define TIMER_INTERVAL CLINT_TIMEBASE_FREQ

static uint32_t _tick = 0;

测试

我们这里简单测试一下定时器中断运行效果:

void start_kernel(void)
{
	uart_init();
	uart_puts("Hello, RVOS!\n");

	page_init();

	trap_init();

	plic_init();
    //初始化定时器模块
	timer_init();

	sched_init();

	os_main();

	schedule();

	uart_puts("Would not go here!\n");
	while (1) {}; // stop here!
}

从零手写操作系统之RVOS硬件定时器-05文章来源地址https://www.toymoban.com/news/detail-475881.html

到了这里,关于从零手写操作系统之RVOS硬件定时器-05的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 物联网操作系统-软件定时器(software timer)

    软件定时器就是\\\"闹钟\\\",你可以设置闹钟, ⚫ 在 30 分钟后让你起床工作 ⚫ 每隔 1 小时让你例行检查机器运行情况 软件定时器也可以完成两类事情: ⚫ 在\\\"未来\\\"某个时间点,运行函数 ⚫ 周期性地运行函数 日常生活中我们可以定无数个\\\"闹钟\\\",这无数的\\\"闹钟\\\"要基于一个真实

    2024年02月21日
    浏览(37)
  • 9.物联网操作系统之软件定时器,实现一个闹钟

    一。软件定时器概念及应用 1.软件定时器定义         就是软件实现定时器。 2.FreeRTOS软件定时器介绍         如上图所示,Times的左边为设置定时器时间,设置方式可以为任务设置或者中断设置;Times的右边为定时器的定时响应,使用CallBack响应。  3.FreeRTOS软件定时器工作

    2024年02月12日
    浏览(38)
  • 操作系统研究:面向软硬件协同的车载操作系统驶入快车道

    已剪辑自: https://mp.weixin.qq.com/s?__biz=MzA4NTcwMDQwMg==mid=2650818860idx=1sn=06f15812b17092f123c4a4ad9ddd3f52chksm=84271371b3509a67b629ffc5b02d3509141a62b2169bf1ae725122a8a5e0930a474c8fd42ad1scene=21#wechat_redirect 佐思汽研发布**《2022年全球与中国汽车操作系统研究报告》**。 基础操作系统:国外厂商精细化打磨功能

    2024年02月12日
    浏览(34)
  • [Linux]查看硬件及操作系统信息

    1、 主板信息 #查看BIOS信息 dmidecode | grep -A 28 “BIOS Information” #查看主板型号信息 dmidecode |grep -A 10 “Base Board Information” dmidecode -t baseboard 2,、cpu信息 #通过/proc文件系统 cat /proc/cpuinfo #通过查看开机信息 dmesg | grep -i ‘cpu’ dmidecode -t processor 3、 硬盘信息 #查看分区情况 fdisk -

    2024年02月06日
    浏览(42)
  • 什么是硬件编程,C 语言如何进行硬件编程?C 语言常用的操作系统有哪些?

    硬件编程是指使用编程语言与硬件交互,控制硬件设备的行为和功能。其中,C语言是一种广泛用于硬件编程的高级编程语言。 C语言通过直接操作内存来进行硬件编程。它提供了一些特殊的和库函数,使得开发者可以直接访问和操作硬件设备的寄存器、端口和外设等。

    2024年02月15日
    浏览(46)
  • 【Linux】操作系统与冯诺依曼体系——深度解析(软硬件层面)

    ​ 前言 大家好吖,欢迎来到 YY 滴 Linux系列 ,热烈欢迎! 本章主要内容面向接触过Linux的老铁,从软硬件层面向大家介绍操作系统与冯诺依曼体系, 主要内容含: 欢迎订阅 YY 滴Linux专栏!更多干货持续更新!以下是传送门! 订阅专栏阅读: YY 的《Linux》系列 ❀❀❀❀❀ 【

    2024年02月13日
    浏览(32)
  • 【Linux】1、操作系统、计算机硬件和软件、Linux 介绍

    🖥️ 计算机由 硬件 和 软件 组成 🖥️ 硬件:计算机中由 电子 、 机械 和 光电元件 等组成的各种物理装置的总称 🖥️ 如:CPU、内存、硬盘驱动器、光盘驱动器、各种扩展卡、连接线、电源、鼠标、键盘 🖱️ 软件(software): 用户和计算机硬件之间构建的桥梁 🖱️ 操作

    2023年04月26日
    浏览(39)
  • D5渲染器电脑硬件配置Vol.1——操作系统丨显卡

    D5 有什么电脑配置需求?电脑配置明明够了却带不动D5?显卡好多分类我需要什么显卡?...... 许多刚接触 D5 的用户对 D5 需要的电脑硬件配置疑问较多,这次一个合集解答所有问题,后续会根据内容升级更新本系列,收藏免走丢。 D5渲染器 采用实时光线追踪技术,该技术

    2023年04月21日
    浏览(33)
  • Java 使用 oshi 获取当前服务硬件信息(操作系统、CPU、内存、磁盘)

    这里需要引入两个依赖包: HardWareUtil: CpuInfo: JvmInfo: MemoryInfo: SysFile: SystemDetails: SizeEnum: 控制台输出: CpuInfo(cpuNum=16, total=16501.0, sys=329.0, used=657.0, wait=0.0, free=15419.0) JvmInfo(total=2.64241152E8, max=4.211081216E9, free=2.5297664E8, version=11.0.18, home=C:Program FilesJavajdk-11) SystemDetails(

    2024年02月05日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包