本帖最后由 xinmeng_wit 于 2023-3-18 10:13 编辑
#申请原创#
一、介绍
embOS是由SEGGER公司推出的实时嵌入式操作系统(RTOS),自1992年以来,embOS一直是嵌入式市场工程师首选的实时操作系统。它提供了易用性,并保证任何嵌入式设备都能100%确定实时操作。该实时操作系统具有高度可移植性,并且在所有平台上完全兼容源代码,因此可以轻松地将应用程序移植到不同的内核。使用信号量、邮箱和事件等通信机制,可以轻松地创建任务并安全地相互通信。
embOS是商业RTOS,公司使用需要购买,但是对于个人非商业用途是完全免费的,只提供库,不提供源代码。
本文将embOS移植到国民技术的N32G45X开发板上。
二、embOS包下载
SEGGER官网提供了很多的示例程序,包括不同的IDE/编译器和不同的处理器内核的示例包,可以根据需要选择下载。
网址:https://www.segger.com/downloads/embos/
因为国民N32G45X是ARM cortex-M系列MCU,同时我这边使用的IDE是keil MDK,所以我选择下载“embOS for Cortex-M and KEIL compiler”这个包。
下载以后,解压后如下:
再进入到Start文件夹下,会有三个文件夹,说明如下:
三、开始移植
首先进入BoardSupport文件夹,里面有各个厂家的芯片的配合好的例程我们可以选择一个我们比较熟悉的一个厂家作为base进行移植。
我就选择比较熟悉的ST,然后进入ST文件夹,可以看到SEGGER为ST各种型号的mcu都有适配。
因为国民N32G45X是cortex-M4内核的,所以我这里选择STM32F429_STM32F429ZI_Nucleo这个工程作为基础进行修改。
但是,为了不影响原来的STM32F429_STM32F429ZI_Nucleo工程,将STM32F429_STM32F429ZI_Nucleo文件夹及其里面的所有内容复制一份并重命名为N32G45X。
双击打开N32G45X文件夹下的keil工程
打开之后可以看到工程中包含的相关文件,需要修改/替换的文件我都做了标注。
可以看到涉及到替换或者修改的文件只有4个,分别为BSP.c , RTOSInit_STM32F4xx.c, system_stm32f4xx.c 和startup_stm32f429_439xx.s
先进行文件替换,按照下面的步骤来:
1、除将system_stm32f4xx.c 和startup_stm32f429_439xx.s从工程中移
2、将国民N32的这两个文件复制到相应的文件夹中(N32G45X\DeviceSupport),同时对应的.h文件也要一并替换,另外,N32的n32g45x_conf.h文件也要放进去。
替换完成后如下:
3、将system_n32g45x.c和startup_n32g45x.s加入到keil工程中,加入后如下:
到这里文件替换的操作就做完了。
可以开始进行代码修改了。
1、修改启动文件,也就是startup_n32g45x.s
启动文件只需要增加4含代码,将Stack_Mem,Stack_Size和Stack_Limit变量导出,因为embOS会用到这三个变量,修改完成后如下:
2、修改RTOSInit_STM32F4xx.c文件
RTOSInit_STM32F4xx.c文件只需要修改一行,将stm32的头文件换成n32的头文件,完成后如下:
3、修改n32g45x_conf.h文件
因为我们没有向工程文件夹中添加国民技术N32的官方库文件,所有很多类似n32g45x_xx.h这种文件是找不到的,编译会报错。
这里我们直接注释掉这些头文件,修改完成后如下:
4、修改BSP.c
实际上,到这里关于embOS的移植就已经完成了,BSP.c只是为了测试embOS能否正常工作的一个测试文件,里面只涉及到对led的配置,与embOS的移植没有关系。
为了能够直接使用官方提供的测试例程,我们还是来修改一下BSP.c,让led能够适配我们的开发板。
我使用的是开发板是国民官方的开发板版N32G45XVL-STB,板载三个用户led,我们只使用其中两个,分别接在PA8和PB5。
BSP.c修改完成后如下,为了能够让大家直接拿去使用,我就直接贴代码:
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2022 SEGGER Microcontroller GmbH *
* *
* Internet: segger.com Support: support_embos@segger.com *
* *
**********************************************************************
* *
* embOS * Real time operating system *
* *
* Please note: *
* *
* Knowledge of this file may under no circumstances *
* be used to write a similar product or a real-time *
* operating system for in-house use. *
* *
* Thank you for your fairness ! *
* *
**********************************************************************
* *
* OS version: V5.18.0.0 *
* *
**********************************************************************
----------------------------------------------------------------------
File : BSP.c
Purpose : BSP for the ST STM32F429_Nucleo board
-------- END-OF-HEADER ---------------------------------------------
*/
#include "BSP.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define RCC_BASE_ADDR (0x40021000u)
#define RCC_APB2PCLKEN (*(volatile unsigned int*)(RCC_BASE_ADDR + 0x18u))
#define RCC_LED0PORT_BIT (2) //PORT A
#define RCC_LED1PORT_BIT (3) //PORT B
#define GPIOA_BASE_ADDR (0x40010800u)
#define GPIOA_PL_CFG (*(volatile unsigned int*)(GPIOA_BASE_ADDR + 0x00u))
#define GPIOA_PH_CFG (*(volatile unsigned int*)(GPIOA_BASE_ADDR + 0x04u))
#define GPIOA_PBSC (*(volatile unsigned int*)(GPIOA_BASE_ADDR + 0x10u))
#define GPIOA_POD (*(volatile unsigned int*)(GPIOA_BASE_ADDR + 0x0Cu))
#define GPIOB_BASE_ADDR (0x40010C00u)
#define GPIOB_PL_CFG (*(volatile unsigned int*)(GPIOB_BASE_ADDR + 0x00u))
#define GPIOB_PH_CFG (*(volatile unsigned int*)(GPIOB_BASE_ADDR + 0x04u))
#define GPIOB_PBSC (*(volatile unsigned int*)(GPIOB_BASE_ADDR + 0x10u))
#define GPIOB_POD (*(volatile unsigned int*)(GPIOB_BASE_ADDR + 0x0Cu))
#define LED0_BIT ( 8) // LED0 (green) - PA8
#define LED1_BIT ( 5) // LED2 (blue) - PB5
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* BSP_Init()
*/
void BSP_Init(void) {
//
// Initialize port for LEDs (sample application)
//
RCC_APB2PCLKEN |= (1u << RCC_LED0PORT_BIT);
if(LED0_BIT > 7)
{
GPIOA_PH_CFG &= ~(15u << (LED0_BIT - 8) * 4); // Reset mode; sets port to input
GPIOA_PH_CFG |= (3u << (LED0_BIT - 8) * 4); // Set to output mode
GPIOA_PBSC |= (1u << (LED0_BIT + 15)); // Initially clear LED, LED OFF
}
RCC_APB2PCLKEN |= (1u << RCC_LED1PORT_BIT);
if(LED1_BIT > 7)
{
GPIOB_PH_CFG &= ~(15u << (LED1_BIT - 8) * 4); // Reset mode; sets port to input
GPIOB_PH_CFG |= (3u << (LED1_BIT - 8) * 4); // Set to output mode
GPIOB_PBSC |= (1u << (LED1_BIT + 15)); // Initially clear LED, LED OFF
}
else
{
GPIOB_PL_CFG &= ~(15u << LED1_BIT * 4); // Reset mode; sets port to input
GPIOB_PL_CFG |= (3u << LED1_BIT * 4); // Set to output mode
GPIOB_PBSC |= (1u << (LED1_BIT + 15)); // Initially clear LED, LED OFF
}
}
/*********************************************************************
*
* BSP_SetLED()
*/
void BSP_SetLED(int Index) {
if (Index == 0) {
GPIOA_PBSC |= (1u << LED0_BIT); // Switch on LED0
} else if (Index == 1) {
GPIOB_PBSC |= (1u << LED1_BIT); // Switch on LED1
} else if (Index == 2) {
//GPIOB_ODR |= (1u << LED2_BIT); // Switch on LED2
}
}
/*********************************************************************
*
* BSP_ClrLED()
*/
void BSP_ClrLED(int Index) {
if (Index == 0) {
GPIOA_PBSC |= (1u << (LED0_BIT + 15)); // Switch off LED0
} else if (Index == 1) {
GPIOB_PBSC |= (1u << (LED1_BIT + 15)); // Switch off LED1
} else if (Index == 2) {
//GPIOB_ODR &= ~(1u << LED2_BIT); // Switch off LED2
}
}
/*********************************************************************
*
* BSP_ToggleLED()
*/
void BSP_ToggleLED(int Index) {
if (Index == 0) {
GPIOA_POD ^= (1u << LED0_BIT); // Toggle LED0
} else if (Index == 1) {
GPIOB_POD ^= (1u << LED1_BIT); // Toggle LED1
} else if (Index == 2) {
//GPIOB_ODR ^= (1u << LED2_BIT); // Toggle LED2
}
}
/****** End Of File *************************************************/
到这里代码虽然修改完了,但是还需要配置一下工程,因为现在keil里面的芯片选的还是STM32f29,需要进行更改,主要有如下几个地方:
最后一步,编译并下载到开发板:
出现了我们最愿意看到的结果:
此时,下载到开发板,然后重新reset一下开发板,就能看到两个LED灯开发闪烁,红灯50ms翻转一次,绿灯200ms翻转一次,对比非常明显。
在OS_StartLEDBlink.c里面有两个TASK,分别为:
static void HPTask(void) {
while (1) {
BSP_ToggleLED(0);
OS_TASK_Delay(50);
}
}
static void LPTask(void) {
while (1) {
BSP_ToggleLED(1);
OS_TASK_Delay(200);
}
}
如果不放心,可以修改一下led的闪烁频率,看看是否真的移植成功了。
可以确定,真的移植成功了,非常完美的让国民技术N32 mcu用上了商业RTOS --embOS。
|
通俗易懂,步骤完整,思路清晰。
由于embOS的特殊性,显得较为小众,但是这不是妨碍技术研究的理由,作者很详细的描述了整个移植过程,排版舒适,配图清晰,仅观版面便让读者感到舒适,很棒哦!
很好的应用文章