【GD32F427开发板试用】在IAR环境中移植RTX5
本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:吴金刚
0.前言
首先感谢极术社区和兆易创新给了这次试用GD32F427开发板的机会。
板子做的虽然简约,但是自带了GD-link所以一根USB线既实现了供电又实现了下载调试,必须赞一个, 而且还支持FS-USB和HS-USB两个USB接口,测试USB就更方便了。GD的单片机我并不陌生,目前也一直在用GD32F10x系列做产品,所以拿到板子后很快就能上手,下面就基于这块试用板介绍一下实时操作系统RTX5的移植过程。
说起RTX实时操作系统,相信使用过Keil-MDK环境的人都知道,它最开始是和Keil-MDK绑定在一起的,在Keil-MDK可以很方便的使用,几乎不需要过多移植工作,就能让系统跑起来,使用非常方便。后来随着CMSIS软件包的独立和开源,RTX就成为了CMSIS软件包的一部分,并且ARM还给RTX套了一层壳叫RTOS(RTOS2),这是一个基于Cortex-M处理器的通用RTOS接口,通过这层接口可以快速方便的切换不同的实时操作系统,目前除了支持RTX5还支持FreeRTOS。
RTX5的主要特点:
- 开源免费,Apache2.0授权,几乎随意商用;
- 任务调度方式灵活多样,支持时间片,抢占式和合作式调度;
- 零中断延迟,这里的零中断延迟是指ISR的中断相应时间和没有使用
RTX5系统是一样的,也就是说用于Cortex-M3/M4/M7的RTX5内核库中没有关闭中断的操作,这点应该算是RTX5一个很大的优势,像Ucos-II,Ucos-III和FreeRTOS内核的很多地方关中断操作,关中断操作对实时性有哪些危害呢?比如此时某个任务正在调用系统API函数,而且此时中断正好关闭了,也就是进入到了临界区中,这个时候如果有一个紧急的中断事件被触发,这个中断就不能得到及时执行,必须等到中断开启才可以得到执行,如果关中断时间超过了紧急中断能够容忍的限度,危害是可想而知的。
- 确定性,指在在定义的时间内处理事件和中断,RTX5 提供完全确定性的行为,这意味着在预定义时间内(期限)处理事件和中断,这个主要得益于RTX5的零中断延迟特性。
1.准备
因为Keil-MDK对RTX5支持的很好, 移植也很方便这里就不详细说明,有兴趣的可以参考安富莱电子的《RTX5内核教程》,里面对RTX5的详细系统特性和在Keil-MDK中使用调试方法介绍。我这里主要介绍在IAR环境中的移植和简单使用。除了准备好GD32F427开发板还需做以下准备:
- IAR开发环境,版本要使用7.4以上版本,我这里使用的版本是8.40.2;
- IAR_GD32F4xx_ADDON.3.0.0.exe IAR 环境补丁,下载地址:https://gd32mcu.com/download/…
- GD32开发板的官方例程GD32F4xx_Demo_Suites,https://gd32mcu.com/download/…
- RTX5源码,https://github.com/ARM-softwa…
只需要用到/CMSIS/RTOS2目录内的文件。
2.移植
2.1 安装IAR环境补丁
直接运行IAR_GD32F4xx_ADDON.3.0.0.exe,目录会自动选择IAR所在的目录,注意如果电脑上安装了多个版本的IAR需要确定使用版本和安装目录一致。安装成功后可以连接开发板打开官方例程中的例程验证一下,如果例程能够正常跑起来就说明已经安装成功了。
2.2 添加RTX5文件
这里我基于GD32427V_START_Demo_Suites\Projects\03_EXTI_Key_Interrupt_mode这个例程来添加RTX5操作系统文件,首先把RTX源码目录放到GD32F4xx_Demo_Suites_V2.6.1\GD32F4xx_Firmware_Library中,在IAR工程目录中新建一个RTOS2文件夹,然后把以下文件添加到工程中:
\RTOS2\RTX\Source\IAR\irq_armv7m.s
\RTOS2\Source\os_systick.c
\RTOS2\RTX\Config\RTX_Config.c
\RTOS2\Config\RTX_Config.h
\RTOS2\RTX\Source\rtx_delay.c
\RTOS2\RTX\Source\rtx_evflags.c
\RTOS2\RTX\Source\rtx_evr.c
\RTOS2\RTX\Source\rtx_kernel.c
\RTOS2\RTX\Source\rtx_lib.c
\RTOS2\RTX\Source\rtx_memory.c
\RTOS2\RTX\Source\rtx_mempool.c
\RTOS2\RTX\Source\rtx_msgqueue.c
\RTOS2\RTX\Source\rtx_mutex.c
\RTOS2\RTX\Source\rtx_semaphore.c
\RTOS2\RTX\Source\rtx_system.c
\RTOS2\RTX\Source\rtx_thread.c
\RTOS2\RTX\Source\rtx_timer.c
2.3 工程配置
工程选项中增加路径和宏定义
2.4 RTX5简单配置和增加移植代码
由于RTX5内核使用了SVC_Handler、PendSV_Handler和SysTick_Handler这三个系统中断所以要把gd32f4xx_it.c中的中断函数删掉,需要注意的是开发板中的毫秒延时是基于SysTick_Handler的,所以需要重新开启一个新的定时器中断或者使用软件延时解决,这里我直接使用了软件延时,代码如下:
/** * [delay_1us]* @Brief 微秒延时, 软件阻塞延时, 精度稍差, 主要用于系统运行前外设初始化中延时操作* @Param count 微秒*/
void delay_1us(uint32_t count)
{count *= 50u;while(--count);
}/** * [delay_1ms]* @Brief 毫秒延时, 软件阻塞延时, 精度稍差, 主要用于系统运行前外设初始化中延时操作* @Param count 毫秒*/
void delay_1ms(uint32_t count)
{while(--count){delay_1us(1000u);}
}
RTX5的配置文件是RTX_Config.h, 这里简单介绍以下几个宏的配置,其他的根据需要设定或者保持默认就可以了。
OS_DYNAMIC_MEM_SIZE: 全局动态内存大小,RTX5支持动态创建系统组件(线程,信号量,消息队列等等),这些内存开销都来自这里,默认为32768Byte;
OS_TICK_FREQ: 内核嘀嗒频率, 默认1000Hz;
OS_ROBIN_ENABLE: 是否使能时间片调度,1表示使用时间片调度;
OS_ROBIN_TIMEOUT: 定义线程时间片线程切换超时的滴答数;
增加以下两个线程名的宏定义,这是RTX5的两个系统线程:
/* OS定时器线程的名称 */
#define OS_TIMER_THREAD_NAME "threadTimer"/* 空闲线程的名称 */
#define OS_IDLE_THREAD_NAME "threadIdle"
测试思路:系统启动后创Start线程,这个线程主要打印当前正在运行的线程数量和线程名称,user按键中断中发送线程标志到启动线程,启动线程检测到标志后创建或者删除User线程;
首先在main中初始化内核并创建启动线程:
/*!\brief main function\param[in] none\param[out] none\retval none
*/
int main(void)
{/* enable the LEDs GPIO clock */rcu_periph_clock_enable(RCU_GPIOC);/* configure LED2 GPIO port */gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);/* reset LED2 GPIO pin */gpio_bit_reset(GPIOC, GPIO_PIN_6);/* flash the LED for test */led_flash(1);/* enable the key clock */rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_SYSCFG);/* configure key pin as input */gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);/* enable and set key EXTI interrupt to the lowest priority */nvic_irq_enable(EXTI0_IRQn, 2U, 0U);/* connect key EXTI line to key GPIO pin */syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN0);/* configure key EXTI line */exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);exti_interrupt_flag_clear(EXTI_0);osKernelInitialize(); /* RTOS内核初始化 *//* 创建启动线程 */threadIdStart = osThreadNew(TaskStart, NULL, &threadAttrStart); osKernelStart(); /* 开启多线程运行RTOS *//* 不应该运行到这里 */SysPrintf("system error!\n");while(1);
}
修改gd32f4xx_it.c中的按键中断服务函数:
/*!\brief this function handles external lines 0 interrupt request\param[in] none\param[out] none\retval none
*/
void EXTI0_IRQHandler(void)
{if(RESET != exti_interrupt_flag_get(EXTI_0)){/* 向启动线程发动线程标志1 */osThreadFlagsSet(threadIdStart, 1);/* 清中断标志 */exti_interrupt_flag_clear(EXTI_0);}
}
线程任务的实现:
//debug 输出到IAR的Terminal, IAR必须设置为半主机模式, 另外必须取消fputc函数的重定义
#define SysPrintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
//#define SysPrintf(fmt, ...) osThreadId_t threadIdStart = NULL; //启动线程
osThreadId_t threadIdUser = NULL; //用户线程//启动线程参数
const osThreadAttr_t threadAttrStart =
{.name = "threadStart", /* 线程名称 */.attr_bits = osThreadDetached, /* 线程属性 */.priority = osPriorityLow, /* 线程优先级 */.stack_size = 1024, /* 线程栈大小,如果不指定则按照默认值设置 */
};//用户线程参数
const osThreadAttr_t threadAttrUser =
{.name = "threadUser", /* 线程名称 */.attr_bits = osThreadDetached, /* 线程属性 */.priority = osPriorityHigh, /* 线程优先级 */.stack_size = 1024, /* 线程栈大小,如果不指定则按照默认值设置 */
};/** * [TaskUser]* @Brief 按键控制的用户线程, 目前只实现LED闪烁* @Param argument $argument$*/
void TaskUser(void *argument)
{for(;;){/* turn on the LED */gpio_bit_set(GPIOC, GPIO_PIN_6);osDelay(500);/* turn off the LED */gpio_bit_reset(GPIOC, GPIO_PIN_6);osDelay(500);}
}/** * [TaskStart]* @Brief 启动线程, 这里创建系统功能线程和初始定时器* @Param argument $argument$*/
void TaskStart(void *argument)
{osThreadId_t osIdArr[10];int osThreadNum;int flgComm = 0;SysPrintf(">>>>> 基于GD32F427V-START移植RTX5测试demo <<<<<\n\n", osThreadNum);for(;;){ /* 检索线程 */osThreadNum = osThreadEnumerate(osIdArr, 10);/* 打印当前的线程个数 */SysPrintf("线程个数: %d\n-------------------------\n", osThreadNum);/* 打印线程名 */for(--osThreadNum; osThreadNum>=0; osThreadNum--){SysPrintf("%d线程名: %s \n", osThreadNum, osThreadGetName(osIdArr[osThreadNum])); }SysPrintf("\n");/* 等待按键的标志组,1秒超时 */flgComm = osThreadFlagsWait(1, osFlagsWaitAny, 1000u);if(1 == flgComm){/* 测试线程的创建和终止 */if(threadIdUser != NULL){/* 删除用户线程 */osThreadTerminate(threadIdUser);threadIdUser = NULL;}else{/* 创建用户线程 */threadIdUser = osThreadNew(TaskUser, NULL, &threadAttrUser); } }}
}
3.测试
下载程序, 打开IAR的Terminal I/O并运行程序,然后系统打印出当前的线程个数为3,并输出线程名称。第一次按下User按键User线程被创建,线程数为4。第二次按下User键,User线程被删除此时线程个数恢复到3。
至此RTX5的移植和简单测试就完成了,欢迎各位批评指正。现将测试包分享给各位(附件下载作为备份):
链接:https://pan.baidu.com/s/14IKYivC53SrxV7ZpM2EMDQ
提取码:2mv0
相关文章:
【GD32F427开发板试用】在IAR环境中移植RTX5
本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:吴金刚 0.前言 首先感谢极术社区和兆易创新给了这次试用GD32F427开发板的机会。 板子做的虽然简约,但是自带了GD-link所以一根USB…...
MySQl学习(从入门到精通15)
MySQl学习(从入门到精通15)第 18 章_MySQL 8 其它新特性1. MySQL 8 新特性概述1. 1 MySQL 8. 0 新增特性1. 2 MySQL 8. 0 移除的旧特性2. 新特性 1 :窗口函数2. 1 使用窗口函数前后对比2. 2 窗口函数分类2. 3 语法结构2. 4 分类讲解1. 序号函…...
前端构建工具 Vite
文章目录参考环境构建工具构建工具的主要功能目前主流的前端构建工具Vite为什么使用 Vite冷启动WebpackVite热更新优化热更新优化预构建依赖Webpack VS ViteVite 的缺点首屏性能懒加载与 Vite 相关的基本操作获取create-vite创建项目Project nameSelect a frameworkSelect a va…...
若依框架---PageHelper分页(十)
在前几天的文章中,我们介绍了PageHelper的分页方法,研读代码定位到了ExecutorUtil.pageQuery(...)方法,并阅读到了其中的部分代码。 今天我们将看到重要的SQL修改代码。 getPageSql 我们接着看代码: if (!dialect.beforePage(…...
苹果手机专用蓝牙耳机有哪些?与iphone兼容性好的蓝牙耳机
蓝牙耳机摆脱了线缆的束缚,在地以各种方式轻松通话。自从蓝牙耳机问世以来,一直是行动商务族提升效率的好工具,苹果产品一直都是受欢迎的数码产品,下面推荐几款与iphone兼容性好的蓝牙耳机。 第一款:南卡小音舱蓝牙耳…...
CS-TPGS;壳聚糖修饰维生素E;Chitosan-g-TPGS
Chitosan-g-TPGS,CS-TPGS壳聚糖修饰维生素E聚乙二醇1000琥珀酸酯外观呈现白色固体或者粘稠液体。长期保存需要在-20℃,避光,干燥条件下存放,注意取用一定要干燥,避免频繁溶冻。 维生素E聚乙二醇琥珀酸酯(简称TPGS)是维生素E的水溶性衍生物,由维生素E琥珀酸酯的羧基与…...
easyx的基本使用(万字解析)
easyx的基本使用一.基本框架1.创建文件2.创建窗体-initgraph,closegraph,getchar二.简单的绘制1.圆形-circle2.坐标系统-setorigin,setaspectratio三.简单图形1.绘制点-putpixel2.简单的直线-line3.矩形-rectangle4.椭圆-ellipse5.圆角矩形-roundrect6.扇形-pie7.圆弧-arc四.多…...
基于OpenCV 的车牌识别
基于OpenCV 的车牌识别 车牌识别是一种图像处理技术,用于识别不同车辆。这项技术被广泛用于各种安全检测中。现在让我一起基于 OpenCV 编写 Python 代码来完成这一任务。 车牌识别的相关步骤 1. 车牌检测:第一步是从汽车上检测车牌所在位置。我们将使用…...
C#【必备技能篇】Winform跨线程更新进度条的实例
文章目录实例一:【方便理解,常用!】源码:运行效果:实例二:【重在理解代码本身】源码:运行效果:参考:实例一:【方便理解,常用!】 跨线…...
(1分钟速通面试) 矩阵分解相关内容
矩阵分解算法--总结QR分解 LU分解本篇博客总结一下QR分解和LU分解,这些都是矩阵加速的操作,在slam里面还算是比较常用的内容,这个地方在isam的部分出现过。(当然isam也是一个坑,想要出点创新成果的话 可能是不太现实的 短期来讲 哈…...
this指向
(1)在全局环境中的this——window 无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。 "use strict"console.log(this); //windowconsole.log(thiswindow);//true (…...
安卓小游戏:小板弹球
安卓小游戏:小板弹球 前言 这个是通过自定义View实现小游戏的第三篇,是小时候玩的那种五块钱的游戏机上的,和俄罗斯方块很像,小时候觉得很有意思,就模仿了一下。 需求 这里的逻辑就是板能把球弹起来,球…...
7、单行函数
文章目录1 函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数及分类2 数值函数2.1 基本函数2.2 角度与弧度互换函数2.3 三角函数2.4 指数与对数2.5 进制间的转换3 字符串函数4 日期和时间函数4.1 获取日期、时间4.2 日期与时间戳的转换4.3 获取月份、星期、星…...
华为机试题:HJ56 完全数计算(python)
文章目录博主精品专栏导航知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方法2、print() :打印输出。3、整型int() :将指定进制…...
opencv——傅里叶变换、低通与高通滤波及直方图等操作
1、傅里叶变换a、傅里叶变换原理时域分析:以时间为参照进行分析。频域分析:相当于上帝视角一样,看事物层次更高,时域的运动在频域来看就是静止的。eg:投球——时域分析:第1分钟投了3分,第2分钟投…...
【NGINX入门指北】 进阶篇
nginx 进阶篇 文章目录nginx 进阶篇一、Nginx Proxy 服务器1、代理原理2、proxy代理3、proxy缓存一、Nginx Proxy 服务器 1、代理原理 正向代理 内网客户机通过代理访问互联网,通常要设置代理服务器地址和端口。 反向代理 外网用户通过代理访问内网服务器&…...
Python中关于@修饰符、yeild关键词、next()函数的基本功能简述
关于修饰符:其实就是将修饰符下面的函数当成参数传给它上面的函数。 def a(x):print(a)adef b():print(b) 其效果等价为: def a(x):print(a)def b():print(b)a(b())有个记忆诀窍,的下面哪个函数最近,谁就是儿子,谁就…...
结合Coverity扫描Spring Boot项目进行Path Manipulation漏洞修复
本篇介绍使用Coverity 扫描基于Spring Boot 项目中的Path Manipulation 漏洞, 进而解决风险,并且可以通过扫描。 什么样的代码会被扫描有路径操纵风险? 在Spring Boot 项目中, 实验了如下的场景: 1. Control 中 file path 作为参数传递的会被扫描,单纯服务方法不会 场…...
【FFMPEG源码分析】从ffplay源码摸清ffmpeg框架(一)
ffplay入口 ffmpeg\fftools\ffplay.c int main(int argc, char **argv) {/*******************start 动态库加载/网络初始化等**************/int flags;VideoState *is;init_dynload();av_log_set_flags(AV_LOG_SKIP_REPEATED);parse_loglevel(argc, argv, options);/* regis…...
C++蓝桥杯 基础练习,高精度加法,输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
C蓝桥杯 基础练习,高精度加法 问题描述 输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。 定义一…...
MySQL面试题:SQL语句的基本语法
MySQL目录一、数据库入门1. 数据管理技术的三个阶段2. 关系型数据库与非关系型数据库3. 四大非关系型数据库a. 基于列的数据库(column-oriented)b. 键值对存储(Key-Value Stores)c. 文档存储(Document Storesÿ…...
Fluid-数据编排能力原理解析
前言本文对Fluid基础功能-数据编排能力进行原理解析。其中涉及到Fluid架构和k8s csi driver相关知识。建议先了解相关概念,为了便于理解,本文使用JuiceFS作为后端runtime引擎。原理概述Fuild数据编排能力,主要是在云原生环境中,能…...
并发线程、锁、ThreadLocal
并发编程并发编程Java内存模型(JMM)并发编程核心问题—可见性、原子性、有序性volatile关键字原子性原子类CAS(Compare-And-Swap 比较并交换)ABA问题Java中的锁乐观锁和悲观锁可重入锁读写锁分段锁自旋锁共享锁/独占锁公平锁/非公平锁偏向锁/轻量级锁/重…...
CMMI-结项管理
结项管理(ProjectClosing Management, PCM)是指在项目开发工作结束后,对项目的有形资产和无形资产进行清算;对项目进行综合评估;总结经验教训等。结项管理过程域是SPP模型的重要组成部分。本规范阐述了结项管理的规程&…...
网络通信协议是什么?
网络通信基本模式 常见的通信模式有如下2种形式:Client-Server(CS) 、 Browser/Server(BS) 实现网络编程关键的三要素 IP地址:设备在网络中的地址,是唯一的标识。 端口:应用程序在设备中唯一的标识。 协议: 数据在网络中传输的…...
阶段5:Java分布式与微服务实战
目录 第33-34周 Spring Cloud电商实战 一、Eureka-server模块开发 1、引入依赖 2、配置文件 3、启动注解 一、Eureka-server模块开发 第33-34周 Spring Cloud电商实战 一、Eureka-server模块开发 1、引入依赖 父项目依赖:cloud-mall-practice springboot的…...
我的创作纪念日
目录 机缘 收获 日常 憧憬 机缘 其实本来从大一上学期后半段(2017)就开始谢谢零星的博客,只不过当时是自己用hexo搭建了一个小网站,还整了个域名:jiayoudangdang.top,虽然这个早就过期; 后来发现了CSDNÿ…...
Qml学习——动态加载控件
最近在学习Qml,但对Qml的各种用法都不太熟悉,总是会搞忘,所以写几篇文章对学习过程中的遇到的东西做一个记录。 学习参考视频:https://www.bilibili.com/video/BV1Ay4y1W7xd?p1&vd_source0b527ff208c63f0b1150450fd7023fd8 目…...
设计模式之职责链模式
什么是职责链模式 职责链模式是避免请求发送者与接受者耦合在一起,让多个对象都可以接受到请求,从而将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理为止。 职责链模式包含以下几个角色: …...
MySQL入门篇-MySQL 8.0 延迟复制
备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL 延迟复制 概述 MySQL的复制一般都很快,虽然有时候因为 网络原因、大事务等原因造成延迟,但是这个无法人为控制。 生产中可能会存在主库误操作,导致数据被删除了,Oracl…...
平潭综合实验区建设局网站/优秀营销软文100篇
转载原地址 http://www.cnblogs.com/darrenji/p/3951065.html 转载于:https://www.cnblogs.com/wphl-27/p/5956140.html...
网站开发框架参考文献/华为手机软文范文300
微服务架构 什么是微服务架构: 简而言之,微服务架构风格这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这祥轻里的机制来相互通信。 这些服…...
扁平化设计网站建设/厦门seo专业培训学校
提到直播大多数人首先想到的可能是各种直播平台,比如花椒斗鱼虎牙YY ,这些直播平台中按照主播风格的不同,又可以分为美女直播、游戏直播、教育直播或者财经直播。除了开始的美女、才艺直播外,其他是直播和细分行业的结合。那么提到…...
传奇怎么做网站/it培训机构出来能找到工作吗
摘要:主要讲解一些比较常用的bootstrap扩展,比如字体图标(font awesome)、时间选择器、按钮等,这些扩展确实非常强大,能在bootstrap的基础上为我们增加不少光彩。 一、Font Awesome 1.1 介绍 font awesome是…...
怎么制作网站维护公告效果/新一轮疫情最新消息
微信开始严打第三方网页强制跳转行为,禁止使用提供诱导或强制点击跳转阅读全文功能,违规导流网站一律封杀!微信方面表示,近期大量用户投诉,在微信中打开第三方网站链接内容总是出现诱导或强制点击才能阅读链接全文行为,…...
做网站预付款是多少/怎么有自己的网站
紧接上一博客:https://blog.csdn.net/m0_37607945/article/details/106437625 从客户端日志中可以看到nacos注册成功,并且从日志可以看出相关类是: com.alibaba.cloud.nacos.registry.NacosServiceRegistry 并搜索日志,在对应行打…...