目录

  • 一、通过STM32CubeMX生成代码
  • 二、下载LiteOS源代码
  • 三、开始移植
    • 文件替换
    • 代码修改
    • 修改配置文件
    • 配置menuconfig

通过前面的准备工作,我们开始正式进入STM32F401CCU6移植LiteOS的征程(如果未搭建好环境的,可以点击下面链接进行阅读)。
开始前准备

一、通过STM32CubeMX生成代码

打开STM32CubeMX软件,如下图所示

点击File,出现

选择New Project,出现

在左侧勾选STM32F,双击右侧的STM32F401CCUx,如下图所示

进入图形化配置STM32F401CCUx的界面。接下来配置STM32F401CCU6的基本功能,笔者手上的是一块STM32F401CCU6的最小系统板,如下图所示,

通过原理图可以知道,板上的板载LED灯是由PC13所控制,我们配置PC13的引脚,如下图所示

选择其为GPIO_Output模式,接着配置定时器Tim3,如下图所示

配置USART1,如下图所示

记住这个波特率115200Bit/s、数据位8Bits和停止位1Bits,在后面串口调试助手中也需要如此配置。
配置时钟源RCC,如下图所示

选择外部时钟晶振,STM32F401CCU6这个最小系统板,板上的晶振是25MHz,接着点击Clock Configuration,配置时钟相关参数,如下图所示

即只要不超过图中84MHz max的这个参数即可,后面的参数同理,如此配置后,定时器100us向上计数一次,当计数器大于50000时,计数器重新计数。

填写Project Manager配置,如下图所示


最后点击GENERATE CODE,生成了裸板代码,复制到Ubuntu中即可。若想要测试裸板工程是否配置成功,可以在文件夹中的Core/Src/main.c中的main函数中实现闪烁灯,代码如下

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM3_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);HAL_Delay(500);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

在Makefile文件目录下的终端执行make命令后,得到了后缀为.bin文件和.hex文件,选择其一烧录(烧录软件可以使用官方的STM32IDE,这样就不用安装STM32CubeMX软件)进STM32F401CCU6即可,观察板载LED灯是否闪烁。

二、下载LiteOS源代码

通过上面的步骤,我们就已经准备好了前期所有的工作内容,接下来就是开始移植。从gitee官网上下载LiteOS的源代码,推荐使用git直接拉取源代码,因为笔者之前用网页下载的ZIP源代码压缩包里面缺少了几个文件目录,导致一直编译失败,拉取源代码如下

git clone https://gitee.com/LiteOS/LiteOS.git

由于gitee是国内的开源网站,因此下载速度较快。

三、开始移植

文件替换

首先找一个targets/STM32F4xx系列的文件,将其拷贝成名字为STM32F401_CCU6的文件夹名(笔者找了STM32F407系列的工程文件),依旧放置于targets文件夹下,进入STM32F401_CCU6文件夹内,将裸板工程里面Core/Src/system_stm32f4xx.c、gpio.c、tim.c、usart.c替换掉STM32F401_CCU6/Src下面的system_stm32f4xx.c、gpio.c、tim.c、usart.c四个文件,将Drivers\CMSIS\Device\ST\STM32F4xx\Include/stm32f401xc.h替换掉STM32F401_CCU6/Inc/stm32f407xx.h,将Core/Inc/ gpio.h、tim.h usart.h、stm32f4xx_hal_conf.h替换掉STM32F401_CCU6/Inc/gpio.h、tim.h usart.h、stm32f4xx_hal_conf.h四个文件。

代码修改

将STM32F401_CCU6/include/asm/platform.h中

#include "stm32f407xx.h"

替换成

#include "stm32f401xc.h"

把STM32F401_CCU6/Src/main.c中的HardwareInit函数中修改成

VOID HardwareInit(VOID)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM3_Init();
}

在STM32F401_CCU6/include/hisoc/clock.h中添加

#define get_bus_clk()  SystemCoreClock

SystemCoreClock函数在裸板程序的main.c中,笔者的SystemCoreClock如下

void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){Error_Handler();}
}

将其拷贝进sys_init.c即可。
在STM32F401_CCU6/Inc/tim.h中,添加以下代码

#include "los_typedef.h"
#include "platform.h"
extern TimControllerOps g_cpupTimerOps;

在STM32F401_CCU6/Src/tim.c中,添加以下代码

#include "sys_init.h"
#include "los_hwi.h"
VOID TimInit(VOID)
{MX_TIM3_Init();
}
VOID TimerHwiCreate(VOID)
{UINT32 ret;ret = LOS_HwiCreate(TIM_IRQ, 0, 0, TIM3_IRQHandler, 0); // 16: cortex-m irq num shiftif (ret != 0) {printf("ret of TIM3 LOS_HwiCreate = %#x\n", ret);return;}HAL_TIM_Base_Start_IT(&htim3);
}
UINT64 GetTimerCycles(VOID)
{static UINT64 bacCycle;static UINT64 cycleTimes;UINT64 cycles = 0;UINT64 swCycles = htim3.Instance->CNT;if (swCycles < bacCycle) {cycleTimes++;}bacCycle = swCycles;cycles = swCycles + cycleTimes * TIMER3_RELOAD;return cycles;
}
TimControllerOps g_cpupTimerOps = {.timInit = TimInit,.timHwiCreate = TimerHwiCreate,.timGetTimerCycles = GetTimerCycles
};

在STM32F401_CCU6/Inc/gpio.h中,添加以下代码

#include "stm32f4xx_hal.h"

在STM32F401_CCU6/Inc/usart.h中,添加以下代码:

#include "stm32f4xx_hal.h"
#include "los_typedef.h"
#include "uart.h"
extern UartControllerOps g_genericUart;

在STM32F401_CCU6/Src/usart.c中,添加以下代码

VOID UsartInit(VOID)
{MX_USART1_UART_Init();
}
VOID UsartWrite(const CHAR c)
{(VOID)HAL_UART_Transmit(&huart1, (UINT8 *)&c, 1, DEFAULT_TIMEOUT);
}
UINT8 UsartRead(VOID)
{UINT8 ch;(VOID)HAL_UART_Receive(&huart1, &ch, sizeof(UINT8), 0);return ch;
}
STATIC VOID UartHandler(VOID)
{(VOID)uart_getc();
}
INT32 UsartHwi(VOID)
{if (huart1.Instance == NULL) {return LOS_NOK;}HAL_NVIC_EnableIRQ(USART1_IRQn);__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_TC);(VOID)LOS_HwiCreate(NUM_HAL_INTERRUPT_UART, 0, 0, UartHandler, NULL);__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);return LOS_OK;
}
UartControllerOps g_genericUart = {.uartInit = UsartInit,.uartWriteChar = UsartWrite,.uartReadChar = UsartRead,.uartHwiCreate = UsartHwi
};

修改链接脚本,注意要先改完裸板程序中的.ld文件才能用裸板程序中的.ld文件替代LiteOS文件,在裸板程序的.ld文件中添加以下字段

/* used by the startup to initialize liteos vector */
_si_liteos_vector_data = LOADADDR(.vector_ram);/* Initialized liteos vector sections goes into RAM, load LMA copy after code */
.vector_ram :
{
. = ORIGIN(RAM);
_s_liteos_vector = .;
*(.data.vector)    /* liteos vector in ram */
_e_liteos_vector = .;
} > RAM AT> FLASH
. = ALIGN(8);
__los_heap_addr_start__ = .;
__los_heap_addr_end__ = ORIGIN(RAM) + LENGTH(RAM) - _Min_Stack_Size - 1;

注意要对着原来的liteos.ld文件将字段放在合适的位置。

修改配置文件

修改STM32F401_CCU6/Makefile文件,找到USER_SRC字段,在字段中添加跟其他语句一样的一句

$(LITEOSTOPDIR)/targets/$(LITEOS_PLATFORM)/Src/gpio.c

注意换行要用“\”符号添加在末尾,如果gpio.c已经添加,也可以将自己写的.c文件放进去,编译时会一同编译,USER_INC字段同理,为引入的头文件。

找到targets/bsp目录下的Makefile文件中

else ifeq ($(LOSCFG_PLATFORM_STM32F407_ATK_EXPLORER), y)

复制一份放置在下一个else ifeq前面,将其中的LOSCFG_PLATFORM_STM32F407_ATK_EXPLORER改成LOSCFG_PLATFORM_STM32F401_CCU6,STM32F407ZGTX_HAL_SRC改成STM32F401_CCU6_HAL_SRC,修改完成的代码如下

else ifeq ($(LOSCFG_PLATFORM_STM32F401_CCU6), y)
STM32F401_CCU6_HAL_SRC = \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c \drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.cLOCAL_SRCS = $(STM32F401_CCU6_HAL_SRC)

保存后退出。
修改targets/bsp.mk文件,找到STM32F407_ATK_Explorer Options这个字段的代码,拷贝一份粘贴在下方另一个Opitons上面,修改其中的STM32F407_ATK_EXPLORER为STM32F401_CCU6,STM32F407xx为STM32F401xC,修改后代码如下

######################### STM32F401_CCU6 Options #######################
else ifeq ($(LOSCFG_PLATFORM_STM32F401_CCU6), y)LITEOS_CMACRO_TEST += -DSTM32F401xcHAL_DRIVER_TYPE := STM32F4xx_HAL_Driver

修改targets/Kconfig.stm32文件,在config LOSCFG_PLATFORM字段下添加

    default "STM32F401_CCU6"       if LOSCFG_PLATFORM_STM32F401_CCU6

STM32F401_CCU6是文件夹的名字,LOSCFG_PLATFORM_STM32F401_CCU6字段是前面步骤中填写的字段。在下面的choice中的help字段中添加

STM32F401_CCU6

在往下的字段中添加代码

config LOSCFG_PLATFORM_STM32F401_CCU6bool "STM32F401_CCU6"select LOSCFG_USING_BOARD_LDselect LOSCFG_ARCH_CORTEX_M4select LOSCFG_CORTEX_M_NVICselect LOSCFG_CORTEX_M_SYSTICKselect LOSCFG_DRIVER_HAL_LIB

在tool/build/config中复制一份STM32F407_ATK_Explorer.config并重命名为STM32F401_CCU6.config,将STM32F401_CCU6.config中的STM32F407_ATK_EXPLORER替换为STM32F401_CCU6字段。将STM32F401_CCU6.config拷贝到LiteOS主目录下,并修改成.config名字。

配置menuconfig

到了这一步已经可以进行LiteOS组件的裁剪,使用

make menuconfig

出现一个菜单,如下图所示

选项说明:

选项 说明
Compiler 选择编译器类型和编译选项
Targets 选择目标开发板
Kernel 裁剪内核
Lib 标准库的裁剪
Compat 选择CMSIS标准库的版本,最新版本为2
Demos 各种官方测试用的demo
Debug 可以选择-g调试选项和打开shell进行交互

操作按键如下图:

操作说明:

操作 说明
空格/Enter 切换选中和未选中状态
ESC 退出
S 保存
符号说明
C 切换显示模式

保存后退出,注意如果是第一次保存,要保持网络通畅,因为配置完后会自动下载一些东西。等待执行完毕,查看是否报错,若无报错,则使用

make -j8

进行编译,若报错则排查可能报错的原因。
出错原因可以在这查找是否有错误信息,LiteOS移植过程中的常见错误

编译成功后的结果图

STM32F401CCU6移植华为LiteOS相关推荐

  1. 基于STM32F103移植华为LiteOS物联网系统

    基于STM32F103移植华为LiteOS物联网系统 本实验是通过学习野火的<物联网操作系统 LiteOS开发实战指南>参考学习的. 1.移植前的准备 LiteOS 的源码可从 LiteO ...

  2. 操作系统实验读者写者程序源码_SAST Weekly | STM32F103系列开发板移植华为LiteOS操作系统...

    SAST weekly 是由电子工程系学生科协推出的科技系列推送,内容涵盖信息领域技术科普.研究前沿热点介绍.科技新闻跟进探索等多个方面,帮助同学们增长姿势,开拓眼界,每周更新,欢迎关注!欢迎愿意分享 ...

  3. 移植华为LiteOS

    利用华为LiteOS 创建两个任务.任务A 使用PA7引脚点亮LED,每500毫秒交替闪烁.任务B 使用PA8引脚点亮LED,每1000毫秒交替闪烁. 1.STM32CubeMX 创建裸机工程 关于如 ...

  4. 【华为云技术分享】STM32L476移植华为LiteOS系列教程---开发前的准备 2

    一.准备开发工具 STM32CubeMX用于生成工程文件:STM32CubeMX下载地址 IoT Studio用于编译.烧写和调试自己的工程文件和硬件:IoT Studio下载地址 最新的LiteOS ...

  5. 【华为云技术分享】STM32L476移植华为LiteOS系列教程---Kconfig 6

    摘要:Kconfig是一款基于python优秀的配置软件,之前没有做过Linux开发的同学们可能不知道这是啥,所以这篇文章想向大家说明Kconfig在IoT Studio中的重要性,以及一些相关的简单 ...

  6. 【华为云技术分享】STM32L476移植华为LiteOS系列教程------背景知识 1

    一.这篇文章想向大家说明一个问题,我们开发单片机的本质是什么? 在最早的开发中,我们没有Keil.IAR等等一系列好用的单片机集成开发环境,注意这里的"集成",是指将多个软件其中有 ...

  7. 华为LiteOS操作系统基础知识入门与内核移植

    LiteOS操作系统是华为在2015年发布的一个轻量级的面向物联网的操作系统,同时也是华为物联网1+2+1物联网解决方案的组成部分,此操作系统具备零配置,自发现,自组网的特点,让LiteOS的终端物联 ...

  8. arm armcm33 pack包_华为Liteos移植到stm32F03ZE

    华为Liteos和物联网设备侧sdk移植到stm32F03ZE霸道板子上 啥是LIteos "开源免费"的实时操作系统,集成了 LwM2M.CoAP.mbed TLS.LwIP 全 ...

  9. 小熊派移植华为 LiteOS-M(基于MDK)

    文章目录 小熊派移植华为 LiteOS-M(基于MDK) 前言 一.软硬件介绍 1.1 小熊派开发板 1.2 LiteOS介绍 1.3 移植前言 二.CubeMX 配置 三.获取源码 四.源码移植 4 ...

  10. 手把手教你丨小熊派移植华为 LiteOS-M

    摘要:本文详细讲解如何移植 LiteOS 到小熊派. 本文分享自华为云社区<小熊派移植华为 LiteOS-M(基于MDK)>,作者: JeckXu666. 前言 之前使用小熊派实现了鸿蒙动 ...

最新文章

  1. hexo 博客框架 可用作知识库
  2. 6 种不同情况下写的代码
  3. android内存代码,Android内存优化(五) Lint代码扫描工具
  4. 自己动手:修改crx文件制作自己的Chrome Apps
  5. jquery 网页局部打印总结
  6. JavaScript实现多项式哈希算法(附完整源码)
  7. try catch对异常进行输出到日志、_java安全编码指南之:异常处理
  8. PIL中分离通道发生“AttributeError: 'NoneType' object has no attribute 'bands'”
  9. jremind V0.1.3.0添加透明
  10. go 变量大写_28. 一文了解Go语言中编码规范
  11. C++ cin 详解之终极无惑
  12. 将代码提交到码云步骤
  13. 修改sqlserver编码为utf8_修改Matlab默认编码格式为UTF-8
  14. Spark 学习笔记01
  15. 马什么梅?I什么N?浅谈 web 前端开发中的国际化
  16. 神通数据库连接Oracle的Dblink
  17. 基于PLC和组态软件的多方式运行小车控制系统设计
  18. 如何用计算机设计动画,用电脑制作3D动画的详细过程是怎样的?
  19. 网络安全之防病毒网关
  20. git 中使用git add . 命令时候报如下警warning: LF will be replaced by CRLF in …….

热门文章

  1. 对硬盘进行分区时,GPT和MBR有什么区别?
  2. html 英文自动换行,CSS解决英文自动换行有关问题
  3. html设置表格列宽百 分比,WPS解决实现单页显示 高分辨率显示器百分之百比例下双页改单页方法...
  4. win10虚拟机连接不上内网服务器,win10系统虚拟机无法连接网络的解决方法
  5. 创建批处理文件.bat文件(删除指定文件夹下的文件及文件夹并循环)
  6. 一阶系统和二阶系统动态响应分析
  7. Spring(六)——声明式事物控制
  8. OpenWRT 使用USB 4G上网卡
  9. word中字号与磅值(pt字体)的对应关系
  10. 机器学习入门实例三——线性回归预测店铺销售额