[RISCV]为RISC-V移植FreeRTOS系列之三 -- 时基

前言

书接上回,上回说到我们已经做好了准备,所谓万事具备,就差一场东风,而能吹动FreeRTOS这条大船的是什么呢?没错,聪明的你已经猜到了,是时基。

有过其他MCU移植经验的小伙伴应该知道,时基是操作系统的心跳,所有的操作,包括任务切换,抢占等等都是基于时基,在STM32中,我们一般用systick(滴答计时器)作为时基,而在riscv中,我们用mechine timer(以下简称mtime)作为时基。


作者:wangyijieonline
链接:https://blog.csdn.net/wangyijieonline/article/details/109721689
来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载必须注明出处。


本文部分参考官方Guide:Using FreeRTOS on RISC-V Microcontrollers
在其中有这么一段:

In summary, to build FreeRTOS for a RISC-V core you need to:
1, Include the core FreeRTOS source files and the FreeRTOS RISC-V port layer source files in your project.
2, Ensure the assembler’s include path includes the path to the header file that describes any chip specific implementation details.
3, Define either a constant in FreeRTOSConfig.h or a linker variable to specify the memory to use as the interrupt stack.
4, Define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS in FreeRTOSConfig.h.
5, For the assembler, #define portasmHANDLE_INTERRUPT to the name of the function provided by your chip or tools vendor for handling external interrupts.
6, Install the FreeRTOS trap handler.

翻译一下:

要为 RISC-V 内核构建 FreeRTOS,您需要:
1、在项目中包括核心 FreeRTOS 源文件和 FreeRTOS RISC-V 端口层源文件。
2、确保汇编器的包含路径包括描述任何芯片特定实现详细信息的标头文件的路径。
3、定义 FreeRTOSConfig.h 中的常量或链接器变量以指定要用作中断堆栈的内存。
4、在 freeRTOScong.h configMTIME_BASE_ADDRESS定义configMTIMECMP_BASE_ADDRESS和定义。
5、对于汇编#define portasmHANDLE_INTERRUPT,请使用芯片或工具供应商为处理外部中断而提供的功能的名称。
6、安装 FreeRTOS 陷阱处理程序。

可以看到,在第4条,特意提到了两个defination configMTIME_BASE_ADDRESSconfigMTIMECMP_BASE_ADDRESS,在之前,我们在FreeRTOSconfig.h中定义过如下的define,这就是我们这一节要展开讲的。
在这里插入图片描述

mtime的初始化

在使用时基之前要先定义,而这个初始化应该是在FreeRTOS的任务调度之前完成,而实际,这件事做的确实很晚,是在vTaskStartScheduler();函数里执行的,具体的调用路径:

vTaskStartScheduler();		//./FreeRTOS/Source/task.c
	|	xPortStartScheduler();		//./FreeRTOS/Source/portable/GCC/RISC-V/port.c
			|	vPortSetupTimerInterrupt();		//./FreeRTOS/Source/portable/GCC/RISC-V/port.c

#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )

	void vPortSetupTimerInterrupt( void )
	{
	uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;
	volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( ( configMTIME_BASE_ADDRESS ) + 4UL ); /* 8-byte typer so high 32-bit word is 4 bytes up. */
	volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configMTIME_BASE_ADDRESS );
	volatile uint32_t ulHartId;

		__asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) );
		pullMachineTimerCompareRegister  = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) );

		do
		{
			ulCurrentTimeHigh = *pulTimeHigh;
			ulCurrentTimeLow = *pulTimeLow;
		} while( ulCurrentTimeHigh != *pulTimeHigh );

		ullNextTime = ( uint64_t ) ulCurrentTimeHigh;
		ullNextTime <<= 32ULL; /* High 4-byte word is 32-bits up. */
		ullNextTime |= ( uint64_t ) ulCurrentTimeLow;
		ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;
		*pullMachineTimerCompareRegister = ullNextTime;

		/* Prepare the time to use after the next tick interrupt. */
		ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;
	}

#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIME_BASE_ADDRESS != 0 ) */

mtime是包在riscv的ISA里的,只要确定好两个寄存器地址,一个MTIME_BASE_ADDRESS,一个MTIMECMP_BASE_ADDRESS,那基本就没啥问题了。
下面附上mtime的reg mem map(一共就俩64位寄存器。。。):
在这里插入图片描述
在这里插入图片描述

总结

当时基跑起来以后,其他的就无关MCU架构了,又成了一种上层软件的东西,我们的目的,机制与策略分离,再一次完美地实现。

好的,打完收工,下回说说上面的第5和第6条。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: rt-thread是一个轻量级的实时操作系统,并且它可以被移植到不同的处理器架构上,包括RISC-V。移植rt-thread到RISC-V处理器需要进行一些步骤。 首先,需要根据RISC-V处理器的体系结构和指令集特性,进行rt-thread的适配和修改。这可能涉及到整理处理器的文件和寄存器初始化的代码,以匹配RISC-V的特性。 其次,需要编写RISC-V处理器对应的启动代码,这些代码的目的是初始化处理器并设置一些必需的环境变量,例如堆栈指针和中断向量表。 接下来,需要实现RISC-V处理器的硬件抽象层(HAL),包括时钟管理、中断管理、内存管理和设备驱动等。这些代码将负责处理处理器底层的硬件操作和通信。 然后,根据目标RISC-V处理器的内存映射和外设配置,进行rt-thread的内核配置和编译。这包括选择所需的组件、功能和驱动器,并进行相应的配置。 最后,在RISC-V处理器上运行rt-thread,并进行测试和调试。这可能包括验证系统的稳定性、性能和功能。如果有必要,还可以进行性能优化和问题修复。 通过以上步骤,就可以成功地将rt-thread移植RISC-V处理器上,并实现在该处理器上运行实时操作系统的功能。这样可以为RISC-V处理器提供更多的应用和开发选择。 ### 回答2: rt-thread是一个开源的实时操作系统,支持多种硬件平台。而RISC-V是一种基于开源指令集架构的处理器架构。要将rt-thread移植RISC-V平台,需要进行以下步骤: 1. 首先,需要了解RISC-V处理器的初步知识,包括其指令集、寄存器、内存架构等等。这样才能更好地理解RISC-V的工作方式和特性。 2. 接下来,需要根据RISC-V处理器的特点,对rt-thread进行修改和适配。这包括对内核的调度器、中断处理、任务管理等进行适配,以使其能够在RISC-V平台上正常工作。 3. 在适配过程中,需要根据RISC-V的指令集架构,对rt-thread的汇编代码进行修改。这涉及到对寄存器、堆栈、内存访问等方面的调整,以确保rt-thread能够在RISC-V上正确运行。 4. 还需要根据RISC-V平台的硬件特性,对rt-thread的设备驱动进行适配。这包括对串口、GPIO、定时器等外设的驱动程序进行修改,以使其能够与RISC-V平台上的硬件相匹配。 5. 最后,进行一系列的测试和验证,确保rt-thread在RISC-V平台上的正常运行。这包括对实时性、稳定性、性能等方面进行测试,以验证移植的正确性和可靠性。 综上所述,rt-thread移植RISC-V平台需要对rt-thread进行修改和适配,同时还需要对汇编代码和设备驱动程序进行调整。最终需要进行测试和验证,以确保rt-thread在RISC-V平台上的正常工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山猫Show

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值