Files
stm32f407ve_black/PORTING_GUIDE.md

11 KiB
Raw Blame History

项目移植指南

1. 项目架构概述

本项目采用分层架构设计,主要分为以下几个层次:

1.1 分层结构

  • HAL层硬件抽象层负责硬件抽象将不同MCU的硬件操作封装为统一接口
  • BSP层板级支持包:负责板级配置和初始化
  • Module层模块层实现具体功能模块如LED、UART、Delay等
  • Middleware层中间件层:提供通用功能,如日志记录等
  • Application层应用层:用户应用代码

1.2 核心目录结构

├── BSP/           # 板级支持包
│   ├── Inc/       # BSP头文件
│   └── Src/       # BSP源文件
├── Core/          # 核心应用代码
├── Drivers/       # 官方驱动库
├── HAL/           # 硬件抽象层
│   ├── Inc/       # HAL头文件
│   │   └── arch/  # 架构特定头文件
│   └── Src/       # HAL源文件
│       └── arch/  # 架构特定源文件
├── Middlewares/   # 中间件
└── Modules/       # 功能模块

2. HAL层移植

2.1 HAL层架构

HAL层采用分层设计分为通用层和架构特定层

  • 通用层:提供统一的硬件抽象接口,如hal_gpio.hhal_uart.h
  • 架构特定层针对不同MCU架构的具体实现hal_stm32f4_gpio.c

2.2 支持的架构

目前支持以下架构:

  • STM32F1
  • STM32F4默认
  • STM32F7
  • STM32L4

2.3 添加新架构支持

要添加新的MCU架构支持请按照以下步骤进行

  1. HAL/Inc/hal.h中添加架构定义

    #define HAL_ARCH_NEW_MCU 4  // 添加新的架构定义
    
  2. HAL/Inc/arch/目录下创建新的架构目录

    mkdir -p HAL/Inc/arch/new_mcu
    
  3. 创建架构特定头文件hal_new_mcu.h

    #ifndef HAL_NEW_MCU_H
    #define HAL_NEW_MCU_H
    
    #include "stm32xxxx_hal.h"  // 替换为新MCU的HAL头文件
    #include "../../hal_gpio.h"
    #include "../../hal_uart.h"
    #include "../../hal_delay.h"
    
    void hal_new_mcu_init(void);
    
    #endif /* HAL_NEW_MCU_H */
    
  4. HAL/Src/arch/目录下创建新的架构目录

    mkdir -p HAL/Src/arch/new_mcu
    
  5. 实现架构特定的GPIO驱动hal_new_mcu_gpio.c

    #include "hal.h"
    #include "hal_gpio.h"
    #include "stm32xxxx_hal.h"
    
    void hal_new_mcu_gpio_init(void) {
        // 实现GPIO初始化
    }
    
    void hal_new_mcu_gpio_write_pin(hal_gpio_port_t port, hal_gpio_pin_t pin, hal_gpio_pin_state_t state) {
        // 实现GPIO写操作
    }
    
    // 实现其他GPIO函数...
    
  6. 实现架构特定的UART驱动hal_new_mcu_uart.c

    #include "hal.h"
    #include "hal_uart.h"
    #include "stm32xxxx_hal.h"
    #include "stm32xxxx_hal_uart.h"
    
    void hal_new_mcu_uart_init(void) {
        // 实现UART初始化
    }
    
    void hal_new_mcu_uart_send(hal_uart_instance_t instance, const uint8_t *data, size_t length) {
        // 实现UART发送
    }
    
    // 实现其他UART函数...
    
  7. 更新HAL/Inc/hal.h中的架构包含

    #elif HAL_TARGET_ARCH == HAL_ARCH_NEW_MCU
    #include "arch/new_mcu/hal_new_mcu.h"
    
  8. 更新各HAL驱动文件添加新架构支持

    #elif HAL_TARGET_ARCH == HAL_ARCH_NEW_MCU
        hal_new_mcu_gpio_init();
    

3. BSP层移植

3.1 BSP层架构

BSP层负责板级配置和初始化主要包含以下组件

  • 板级配置结构体bsp_board_config_t,定义了板子的硬件配置
  • 板级初始化:负责初始化板子的硬件资源
  • 板级管理器bsp_board_manager.c,负责管理多个板子配置

3.2 添加新板子支持

要添加新的板子支持,请按照以下步骤进行:

  1. 创建新的板子配置文件new_board.c

    #include "bsp_board.h"
    #include "bsp_config.h"
    #include "hal_gpio.h"
    #include "hal_uart.h"
    
    // 实现默认初始化函数
    static void default_led_init(const void* config) {
        // LED初始化实现
    }
    
    // 实现其他默认初始化函数...
    
    // 定义板子配置
    const bsp_board_config_t new_board_config = {
        .name = "NEW_BOARD",
        .led = {
            .port = HAL_GPIO_PORT_A,
            .pin = HAL_GPIO_PIN_6,
            .mode = HAL_GPIO_MODE_OUTPUT_PP,
            .speed = HAL_GPIO_SPEED_MEDIUM,
            .pull = HAL_GPIO_PULL_NO
        },
        // 配置其他外设...
        .led_init = default_led_init,
        // 配置其他初始化函数...
        .clock_speed = 168000000,
        .uart_count = 6
    };
    
  2. bsp_board.h中添加extern声明

    extern const bsp_board_config_t new_board_config;
    
  3. bsp_board_manager.c中添加新板子配置

    /* Forward declarations for board configurations */
    extern const bsp_board_config_t new_board_config;
    
    /**
     * @brief List of supported board configurations
     */
    static const bsp_board_config_t* supported_boards[] = {
        &stm32f407vet6_board_config,
        &new_board_config,  // 添加新板子配置
        /* Add more board configurations here */
    };
    
  4. 创建新的板子配置头文件bsp_config_new_board.h

    #define BOARD_NAME "NEW_BOARD"
    
    /**
     * @brief LED hardware configuration
     */
    #define BSP_LED_PORT    HAL_GPIO_PORT_A
    #define BSP_LED_PIN     HAL_GPIO_PIN_6
    
    /**
     * @brief UART hardware configuration
     */
    #define BSP_UART_INSTANCE BSP_UART_INSTANCE_1
    #define BSP_UART_BAUDRATE 115200
    #define BSP_UART_PARITY HAL_UART_PARITY_NONE
    #define BSP_UART_STOPBITS HAL_UART_STOPBITS_1
    #define BSP_UART_DATABITS HAL_UART_DATABITS_8
    
  5. 在编译时选择目标板子 通过修改BSP/Src/bsp_board.c中的current_board_index或在编译命令中定义宏来选择目标板子。

4. 模块层移植

4.1 模块层架构

模块层实现具体的功能模块如LED、UART、Delay等。每个模块包含

  • 模块配置结构体:定义模块的配置参数
  • 模块实例结构体:保存模块的状态
  • 模块API:提供模块的操作接口

4.2 添加新模块

要添加新的功能模块,请按照以下步骤进行:

  1. 创建模块目录

    mkdir -p Modules/new_module/inc
    mkdir -p Modules/new_module/src
    
  2. 创建模块头文件new_module.h

    #ifndef NEW_MODULE_H
    #define NEW_MODULE_H
    
    #include <stdint.h>
    
    /**
     * @brief New module configuration structure
     */
    typedef struct {
        // 配置参数
    } new_module_config_t;
    
    /**
     * @brief New module instance structure
     */
    typedef struct {
        new_module_config_t config;
        uint8_t initialized;
    } new_module_t;
    
    /**
     * @brief Initialize new module
     * @param instance: Pointer to module instance
     * @param config: Pointer to module configuration
     */
    void new_module_init(new_module_t *instance, const new_module_config_t *config);
    
    // 其他模块API...
    
    #endif /* NEW_MODULE_H */
    
  3. 创建模块源文件new_module.c

    #include "new_module.h"
    
    void new_module_init(new_module_t *instance, const new_module_config_t *config) {
        if (instance == NULL || config == NULL) {
            return;
        }
    
        // 初始化实现
        instance->config = *config;
        instance->initialized = 1;
    }
    
    // 实现其他模块API...
    
  4. 更新模块的CMakeLists.txt

    # Add new_module library
    add_library(new_module STATIC)
    
    # Add new_module sources
    target_sources(new_module PRIVATE
        src/new_module.c
    )
    
    # Add new_module include directories
    target_include_directories(new_module PUBLIC
        inc
    )
    
    # Link new_module dependencies
    target_link_libraries(new_module PRIVATE
        hal
    )
    

5. 编译配置

5.1 选择目标架构

HAL/Inc/hal.h中定义HAL_TARGET_ARCH宏来选择目标架构:

#ifndef HAL_TARGET_ARCH
#define HAL_TARGET_ARCH HAL_ARCH_STM32F4
#endif

或者在编译命令中定义:

cmake -DHAL_TARGET_ARCH=HAL_ARCH_STM32F4 ..

5.2 选择目标板子

通过修改bsp_board_manager.c中的current_board_index来选择目标板子:

/**
 * @brief Current board configuration index
 */
static uint8_t current_board_index = 0;  // 0表示第一个板子配置

或者调用bsp_board_set_by_name()bsp_board_set_by_index()函数来动态选择:

bsp_board_set_by_name("NEW_BOARD");

6. 常见问题与解决方案

6.1 编译错误undefined reference to `hal_new_mcu_gpio_init'

原因未实现新架构的GPIO初始化函数。

解决方案按照第2节的步骤实现新架构的GPIO初始化函数。

6.2 运行时错误:串口无输出

原因可能是UART初始化失败或GPIO配置错误。

解决方案

  1. 检查UART的GPIO配置是否正确
  2. 检查UART的时钟是否使能
  3. 检查UART的波特率设置是否正确

6.3 移植后LED不亮

原因可能是GPIO配置错误或初始化顺序问题。

解决方案

  1. 检查LED的GPIO配置是否正确
  2. 检查LED的初始化函数是否被调用
  3. 检查GPIO的时钟是否使能

7. 示例移植流程

7.1 STM32F1移植示例

  1. 添加STM32F1架构支持

    • hal.h中添加HAL_ARCH_STM32F1定义
    • 创建hal_stm32f1.hhal_stm32f1.c文件
    • 实现STM32F1特定的GPIO、UART等驱动
  2. 添加STM32F1板子配置

    • 创建stm32f103c8t6_board.c文件
    • 定义stm32f103c8t6_board_config结构体
    • bsp_board_manager.c中添加该配置
  3. 配置编译选项

    • 设置HAL_TARGET_ARCH=HAL_ARCH_STM32F1
    • 更新Linker脚本为STM32F1的链接脚本
  4. 编译和测试

    • 编译项目
    • 烧录到STM32F1开发板
    • 测试LED和UART功能

8. 最佳实践

  1. 遵循分层设计原则:保持各层之间的独立性,避免跨层调用
  2. 使用统一的接口尽量使用HAL层提供的统一接口避免直接操作硬件
  3. 实现完整的初始化:确保所有硬件资源都正确初始化
  4. 添加必要的错误检查:在关键函数中添加参数检查和错误处理
  5. 编写清晰的文档:为新添加的代码编写清晰的注释和文档
  6. 测试所有功能:移植后测试所有关键功能,确保正常工作

9. 资源

10. 联系方式

如果您在移植过程中遇到问题,请联系项目维护者获取帮助。


文档版本v1.0 更新日期2026-01-23 适用项目stm32f407vet6_cmake