RH850F1L 移植freeRTOS

article/2025/11/6 16:48:52

学习基于GHS将freeRTOS移植到RH850 F1L的过程

移植过程参考github的一个教程,其中有部分修改优化,但是不多。

GitHub - mikisama/FreeRTOS_RH850: FreeRTOS port for Renesas RH850

支持gcc、ghs、ccrh、IAR 4种编译器。

有问题一起讨论,也可以直接按照github上的参考一步步移植。

freeRTOS下载

直接到官网下载即可

FreeRTOS - Free RTOS Source Code Downloads, the official FreeRTOS zip file release download

下载完成后,目录如下:

  •  图片中的点c是RTOS的源文件,这些不用动,直接拿来用。
  • portable中是平台依赖相关的文件,也是我们需要动手移植修改的。
  • include文件是API接口文件,代码中使用的时候直接include对应文件即可

移植前准备

RH850 F1L这款芯片比较特殊,用的不是标准的ARM核,而是瑞萨自己开发的,这样对移植工作比较麻烦,特别是关于freeRTOS任务栈初始化、任务启动和切换,这些和mcu底层相关性大的地方,大部分需要查阅瑞萨官方资料。

freeRTOS从启动到开始任务调度之前需要完成下面几件事?

  • 任务栈初始化
  • 执行first task
  • 任务切换(task yield)
  • sys tick 任务调度(涉及任务状态的保存)
  • OS无限循环任务调度

相应的MCU相关的配置有:

  • 中断向量表配置
  • sys tick中断配置
  • 系统堆栈配置

移植

后面就直接把对应的移植过程一一总结

1、freeRTOS portable目录

 展开MemMang和GHS(本人用的编译器)文件夹:

 

 heap_4.c这个不用修改,GHS下面的三个文件需要移植

2、任务栈初始化

port.c中:

StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack,TaskFunction_t pxCode,void * pvParameters )
{/* Simulate the stack frame as it would be created by a context switch* interrupt. */*( pxTopOfStack ) = ( StackType_t ) 0x30303030;         /* R30 (EP) */*( --pxTopOfStack ) = ( StackType_t ) prvTaskExitError; /* R31 (LP) */*( --pxTopOfStack ) = ( StackType_t ) pvParameters;     /* R6       */*( --pxTopOfStack ) = ( StackType_t ) 0x07070707;       /* R7       */*( --pxTopOfStack ) = ( StackType_t ) 0x08080808;       /* R8       */*( --pxTopOfStack ) = ( StackType_t ) 0x09090909;       /* R9       */*( --pxTopOfStack ) = ( StackType_t ) 0x10101010;       /* R10      */*( --pxTopOfStack ) = ( StackType_t ) 0x11111111;       /* R11      */*( --pxTopOfStack ) = ( StackType_t ) 0x12121212;       /* R12      */*( --pxTopOfStack ) = ( StackType_t ) 0x13131313;       /* R13      */*( --pxTopOfStack ) = ( StackType_t ) 0x14141414;       /* R14      */*( --pxTopOfStack ) = ( StackType_t ) 0x15151515;       /* R15      */*( --pxTopOfStack ) = ( StackType_t ) 0x16161616;       /* R16      */*( --pxTopOfStack ) = ( StackType_t ) 0x17171717;       /* R17      */*( --pxTopOfStack ) = ( StackType_t ) 0x18181818;       /* R18      */*( --pxTopOfStack ) = ( StackType_t ) 0x19191919;       /* R19      */*( --pxTopOfStack ) = ( StackType_t ) 0x01010101;       /* R1       */*( --pxTopOfStack ) = ( StackType_t ) 0x02020202;       /* R2       */*( --pxTopOfStack ) = ( StackType_t ) portINITIAL_PSW;  /* EIPSW    */*( --pxTopOfStack ) = ( StackType_t ) pxCode;           /* EIPC     */*( --pxTopOfStack ) = ( StackType_t ) 0x20202020;       /* R20      */*( --pxTopOfStack ) = ( StackType_t ) 0x21212121;       /* R21      */*( --pxTopOfStack ) = ( StackType_t ) 0x22222222;       /* R22      */*( --pxTopOfStack ) = ( StackType_t ) 0x23232323;       /* R23      */*( --pxTopOfStack ) = ( StackType_t ) 0x24242424;       /* R24      */*( --pxTopOfStack ) = ( StackType_t ) 0x25252525;       /* R25      */*( --pxTopOfStack ) = ( StackType_t ) 0x26262626;       /* R26      */*( --pxTopOfStack ) = ( StackType_t ) 0x27272727;       /* R27      */*( --pxTopOfStack ) = ( StackType_t ) 0x28282828;       /* R28      */*( --pxTopOfStack ) = ( StackType_t ) 0x29292929;       /* R29      */return pxTopOfStack;
}

3、first task接口实现

_vPortStartFirstTask:mov _pxCurrentTCB, r2               # SP = pxCurrentTCB->pxTopOfStackld.w 0[r2], r2ld.w 0[r2], sppopsp r20 - r29                     # Restore General Purpose Register (callee save register)popsp r6 - r7ldsr r7, EIPC                       # Restore EIPCldsr r6, EIPSW                      # Restore EIPSWpopsp r1 - r2                       # Restore General Purpose Register (caller save register)popsp r6 - r19dispose 0, {ep, lp}eiret

4、任务切换task yield

_vPortYieldHandler:prepare {ep, lp}, 0pushsp r6 - r19                     # Save General Purpose Register (caller save register)pushsp r1 - r2stsr EIPSW, r6                      # Save EIPSWstsr EIPC, r7                       # Save EIPCpushsp r6 - r7pushsp r20 - r29                    # Save General Purpose Register (callee save register)mov _pxCurrentTCB, r2               # pxCurrentTCB->pxTopOfStack = SPld.w 0[r2], r2st.w sp, 0[r2]jarl _vTaskSwitchContext, lpmov _pxCurrentTCB, r2               # SP = pxCurrentTCB->pxTopOfStackld.w 0[r2], r2ld.w 0[r2], sppopsp r20 - r29                     # Restore General Purpose Register (callee save register)popsp r6 - r7ldsr r7, EIPC                       # Restore EIPCldsr r6, EIPSW                      # Restore EIPSWpopsp r1 - r2                       # Restore General Purpose Register (caller save register)popsp r6 - r19dispose 0, {ep, lp}eiret

5 tick 任务调度

_vISRWrapper:prepare {ep, lp}, 0pushsp r6 - r19                     # Save General Purpose Register (caller save register)pushsp r1 - r2stsr EIPSW, r6                      # Save EIPSWstsr EIPC, r7                       # Save EIPCpushsp r6 - r7//pushsp r20 - r30					#		  Save General Purpose Register (callee save register)mov _xInterruptNesting, r6ld.w 0[r6], r7cmp 0x0, r7                         # if ( xInterruptNesting == 0 )bne aa                              # {mov _pxCurrentTCB, r2               #     pxCurrentTCB->pxTopOfStack = SPld.w 0[r2], r2                      #     SP = MainStackTopst.w sp, 0[r2]                      # }mov ___ghsend_stack, sp
aa:add 0x1, r7                         # xInterruptNesting++st.w r7, 0[r6]stsr EIIC, r6                       # Save EI level Interrupt Causeei                                  # Enable interrupt (enable interrupt nesting)jarl _vISRHandler, lp               # Call the ISR Handlerdi                                  # Disable interrupt (disable interrupt nesting)mov _xInterruptNesting, r6ld.w 0[r6], r7cmp 0x0, r7                         # if ( xInterruptNesting > 0 )be bb                               # {add -1, r7                          #     xInterruptNesting--st.w r7, 0[r6]                      # }
bb:cmp 0x0, r7bne dd                              # if ( xInterruptNesting == 0 )mov _xPortSwitchRequired, r6        # {ld.w 0[r6], r7                      #     if ( xPortSwitchRequired )cmp 0x0, r7                         #     {be ccst.w r0, 0[r6]                      #         xPortSwitchRequired = pdFALSEmov _pxCurrentTCB, r2               #         SP = pxCurrentTCB->pxTopOfStackld.w 0[r2], r2ld.w 0[r2], sppushsp r20 - r29                    #         Save General Purpose Register (callee save register)st.w sp, 0[r2]                      #         pxCurrentTCB->pxTopOfStack = SPjarl _vTaskSwitchContext, lp        #         vTaskSwitchContext()mov _pxCurrentTCB, r2               #         SP = pxCurrentTCB->pxTopOfStackld.w 0[r2], r2ld.w 0[r2], sppopsp r20 - r29                     #         Restore General Purpose Register (callee save register)jr dd                               #     }
cc:                                     #     elsemov _pxCurrentTCB, r2               #     {ld.w 0[r2], r2                      #         SP = pxCurrentTCB->pxTopOfStackld.w 0[r2], sp                      #     }
dd:                                     # }//popsp r20 - r30                     #         Restore General Purpose Register (callee save register)popsp r6 - r7ldsr r7, EIPC                       # Restore EIPCldsr r6, EIPSW                      # Restore EIPSWpopsp r1 - r2                       # Restore General Purpose Register (caller save register)popsp r6 - r19dispose 0, {ep, lp}eiret

6 OS系统定时器配置

为OS提供心跳。

void ApiSysClkOstm0Init(uint32_t os_ticks)
{Os_Enable_OS_CPU_Ticks();ICOSTM0 = (0 << 12) | /* clear interrupt flag */(0 << 7) |  /* unmask interrupt */#ifdef INT_VECT_EBASE_DIRECT//(0 << 6) |  /* direct method */#else(1 << 6) |  /* table reference method */#endif(0x7 << 0);   /* interrupt priority lowest */OSTM0.CMP = (OSTM_PCLK / os_ticks) - 1;OSTM0.CTL = 0X01U;OSTM0.EMU = 0X00U;
}

7 中断配置

中断向量表地址索引有2种方法

Direct Vector Method和Table Reference Method

各路中断需要做相应的配置去使能哪一种。


http://chatgpt.dhexx.cn/article/GYVCJ3rE.shtml

相关文章

瑞萨RH850 FCL、FDL和EEL库的配置和使用

目录 1、FCL库 1.1、配置FCL库 1.2、使用FCL库 2、FDL库 2.1、配置FDL库 2.2、使用FDL库 3、EEL库 瑞萨RH850 Flash中有两种存储类型&#xff1a;Mapping of Code Flash Memory和Mapping of Data Flash Memory。 Mapping of Code Flash Memory存储代码&#xff0c;Mappi…

基于IAR for RH850的瑞萨RH850 FCL库用法介绍

博主联系方式&#xff1a;QQ&#xff1a;1256153255 &#xff0c;email&#xff1a;1256153255qq.com website for get 瑞萨RH850F1x开发板和瑞萨E1仿真器 1、简介 本文介绍了RH850 FCL的使用以及相关的经验技巧&#xff0c;使用的环境如下 MCU&#xff1a;瑞萨RH850F1K 型号…

瑞萨RH850开发环境搭建

简述 本文介绍瑞萨RH850开发环境搭建。 内部包含cancasexl的驱动安装&#xff0c;canoe的软件安装&#xff0c;IAR的软件安装&#xff0c;E1的自检等。 当前版本&#xff1a;V1.0 email&#xff1a;1256153255qq.com website for get 瑞萨RH850开发板 and 瑞萨E1仿真器 变…

2、RH850外设时钟选择及配置

前言 上一篇文章完成了RH850时钟源寄存器配置&#xff0c;外设要正常工作&#xff0c;必须要配置对应的时钟&#xff0c;这篇文章说明RH850外设时钟配置。 时钟选择寄存器 下面表格是RH850-F1K技术规格书列出的外设时钟寄存器。 外设时钟寄存器基本都相同&#xff0c;如TAUJ代表…

3、RH850端口说明及及复用功能配置

RH850端口有3种工作模式 通用IO口(普通数字口)。PMC控制寄存器对应bit为0。软件配置复用模式。PMC控制寄存器对应bit为1。PIPC寄存器对应bit为0。硬件直接连接模式。PMC控制寄存器对应bit为1。PIPC寄存器对应bit为1。 主要控制寄存器 PIPC 0: 端口由软件配置(software I/O c…

10、RH850 CAN通讯功能和配置

前言: CAN 是 Controller Area Network 的缩写&#xff08;以下称为 CAN&#xff09;&#xff0c;是 ISO国际标准化的串行通信协议。 在当前的汽车产业中&#xff0c;出于对安全性、舒适性、方便性、低公害、低成本的要求&#xff0c;各种各样的电子控制系统被开发了出来。由于…

瑞萨RH850芯片在IAR和CS+编译环境下设置堆(heap)和栈(stack)的大小

博主联系方式&#xff1a;QQ&#xff1a;1256153255 &#xff0c;邮箱&#xff1a;1256153255qq.com 点击这里了解RH850开发板 点击这里了解瑞萨E1仿真器 点击这里了解GHS Multi 在实际使用RH850开发的过程中&#xff0c;有时会需要调整芯片的堆栈空间大小。 对于RH850芯片&…

播放rtmp在线网站及播放器

2019独角兽企业重金招聘Python工程师标准>>> 网站地址 http://www.cutv.com/demo/live_test.swf 推流地址 rtmp://ip:8005/live/32010020160918113426717107expxqe 或者采用flash player 也可以 -----------------------------------------------------------------…

rtmp/rtsp播放器

相信大家在做rtmp、rtsp直播的时候&#xff0c;最大的困惑就是选个靠谱的播放器&#xff0c;直播的延迟&#xff0c;一定意义上说&#xff0c;90%的取决于播放器的好坏。 那啥样的播放器才是靠谱的播放器呢&#xff1f;笔者以为&#xff0c;稳定、低延迟、支持路数多&#xff0…

网页可以播放RTMP视频流?支持RTMP的网页播放器

随着4G/5G网络的发展&#xff0c;以及有限带宽越来越大&#xff0c;人们对视频直播的需求也越来越多。不仅普通的互联网直播发展很快&#xff0c;传统的安防监控也开始互联网化&#xff0c;走起了互联网直播的路。雪亮工程、明厨亮灶、手机看店、智慧幼儿园监控等等都是将传统的…

rtmp播放器,使用videojs播放,稳定

rtmp播放器测试dome下载 https://download.csdn.net/download/zhou_yongzhe/10923743 三步走 1.把video-jsplay文件夹下的文件放到nginx服务器的html文件夹下&#xff08;Ubuntu系统nginx的路径为、usr/local/nginx/html/&#xff09; 2.启动ngixn 3.如果是本机测试&#x…

RTMP播放器网页互联网直播音视频流媒体播放器EasyPlayer-RTMP-iOS播放H265格式的视频源

背景分析 RTMP是Real Time Messaging Protocol&#xff08;实时消息传输协议&#xff09;的首字母缩写。该协议基于TCP&#xff0c;是一个协议族&#xff0c;包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议&#xff0c;主要用…

windows下支持H265的rtmp ffplay播放器 ffmpeg的编译

前几天在项目中添加了rtmp对H265的支持&#xff0c;需要推流端 服务器端 以及播放器三个方面的处理。功能已经实现 &#xff0c;感兴趣的可以 去我的上一篇文章看下。 RTMP 推送H265的实现&#xff08;推流端、服务器、播放端&#xff09;ffmpeg 播放H265 之前是在的播放器是在…

服务器(公网推rtmp流),网页本地(qq浏览器)播放rtmp流,且可切换rtmp流播放。使用了video.js、videojs-flash.js、jquery-3.4.1.js和我自己写的一个js

问题&#xff1a; 最开始我想在下拉列表的值发生变化时将video标签包含的source标签里面的src中的rtmp流直接替换掉&#xff0c;达到切换rtmp源播放的目的&#xff0c;但是一直无法生效&#xff0c;最后我想每个源直接做一个html页面&#xff0c;发现如果有几百个源就需要做很多…

Android手机RTMP播放工具(APK,支持秒开)

Android手机RTMP播放工具是一款可以在安卓手机播放rtmp流的工具&#xff0c;基于FFmpegopenCV开发。 下载地址&#xff1a;Android手机RTMP播放工具&#xff08;APK&#xff0c;支持秒开&#xff09;-C文档类资源-CSDN下载

rtmp http mp4 网页播放器

对于页面上如何播放rtsp视频时&#xff0c;项目经过查阅资料后最终采用转成rtmp流在进行播放。在播放时调研了一下网页播放器&#xff0c;最终选择ckplayer。还有一款叫萤石云内部调用得也是ckplayer。 1. ckplayer(http://www.ckplayer.com/) ckplayer是国内网页上播放视频的…

QT实现低延迟的RTSP、RTMP播放器

好多开发者在QT环境下实现RTMP或RTSP播放时&#xff0c;首先考虑到的是集成VLC&#xff0c;集成后&#xff0c;却发现VLC在延迟、断网重连、稳定性等各个方面不尽人意&#xff0c;无法满足上线环境需求。本文以调用大牛直播SDK&#xff08;官方&#xff09;的Windows平台播放端…

【技术分享】如何实现功能完备性能优异的RTMP、RTSP播放器?

技术背景 这几年&#xff0c;我们对接了太多有RTSP或RTMP直播播放器诉求的开发者&#xff0c;他们当中除了寻求完整的解决方案的&#xff0c;还有些是技术探讨&#xff0c;希望能借鉴我们播放端的开发思路或功能特性&#xff0c;完善自己的产品。 忙里偷闲&#xff0c;今天我…

高稳定、低延时、高并发RTMP播放器流媒体音视频播放器EasyPlayer-RTMP-iOS器如何将核心代码打包成静态库

背景分析 RTMP是Real Time Messaging Protocol&#xff08;实时消息传输协议&#xff09;的首字母缩写。该协议基于TCP&#xff0c;是一个协议族&#xff0c;包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议&#xff0c;主要用…

Windows平台RTMP、RTSP播放器录像模块精细化控制

技术背景 上篇文章&#xff0c;我们介绍了Unity平台RTMP、RTSP播放器录像功能&#xff0c;这里&#xff0c;我们详细的介绍下&#xff0c;做个RTSP或RTMP拉流端录像模块有哪些需要考虑的技术点&#xff1f; 在我们常规的考量&#xff0c;RTMP或RTSP流录制&#xff0c;无非就是…