嵌入式跨芯片通用项目框架设计方案

一、框架核心设计思想

上层业务逻辑与底层硬件完全隔离:

  • 应用层:不关心芯片型号,换芯片完全不动
  • 硬件抽象层:统一接口封装,换芯片只改这一层
  • 中间件层:承上启下,屏蔽芯片差异

二、项目框架目录结构

Project/
├── 01_App/                 # 应用层(核心业务,100%复用)
│   ├── main.c              # 主程序入口
│   ├── app_task.c          # 业务任务
│   └── app_cfg.h           # 项目配置
│
├── 02_Middleware/          # 中间件层(通用组件)
│   ├── protocol/           # 通信协议
│   ├── utils/              # 工具函数
│   └── sys_ctrl/           # 系统控制
│
├── 03_HAL/                 # 硬件抽象层(换芯片只改这里)
│   ├── chip_port/          # 芯片适配层
│   │   ├── stm32/          # STM32适配
│   │   ├── gd32/           # GD32适配
│   │   └── chip_port.h     # 统一抽象接口
│   └── board/              # 板级驱动
│
├── 04_ChipLib/             # 芯片原厂库(不修改)
└── 05_Output/              # 编译输出

三、统一硬件接口标准(chip_port.h)

// 03_HAL/chip_port/chip_port.h
#ifndef __CHIP_PORT_H
#define __CHIP_PORT_H

#include <stdint.h>
#include <stdbool.h>

/*************** GPIO 统一接口 ***************/
void gpio_init(void);
void gpio_set(uint8_t pin, uint8_t level);
uint8_t gpio_read(uint8_t pin);
void gpio_toggle(uint8_t pin);

/*************** UART 统一接口 ***************/
void uart_init(uint32_t baudrate);
void uart_send(uint8_t *data, uint16_t len);
uint16_t uart_recv(uint8_t *data, uint16_t max_len);
void uart_irq_handler(void);  // 中断统一入口

/*************** 定时器统一接口 ***************/
void timer_init(uint32_t period_ms);
void timer_start(void);
void timer_stop(void);

#endif

四、芯片适配层实现(以USART为例)

STM32 适配实现

// 03_HAL/chip_port/stm32/chip_port_uart.c

// 哪个串口
uint32_t usartx = USART1;
uint32_t usartx_rcu = RCC_APB2Periph_USART1;
uint32_t usartx_irq = USART1_IRQn;

// 波特率
uint32_t usartx_p_baudrate = 115200;

// TX引脚配置
uint32_t usartx_tx_port_rcu = RCC_APB2Periph_GPIOA;
uint32_t usartx_tx_port = GPIOA;
uint32_t usartx_tx_pin = GPIO_Pin_9;
uint32_t usartx_tx_af = GPIO_AF_USART1;

// RX引脚配置
uint32_t usartx_rx_port_rcu = RCC_APB2Periph_GPIOA;
uint32_t usartx_rx_port = GPIOA;
uint32_t usartx_rx_pin = GPIO_Pin_10;
uint32_t usartx_rx_af = GPIO_AF_USART1;

/*************** GPIO 初始化 ***************/
// TX
rcu_periph_clock_enable(usartx_tx_port_rcu);
gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);

// RX
rcu_periph_clock_enable(usartx_rx_port_rcu);
gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);

/*************** USART 初始化 ***************/
rcu_periph_clock_enable(usartx_rcu);
usart_deinit(usartx);

usart_baudrate_set(usartx, usartx_p_baudrate);
usart_parity_config(usartx, USART_PM_NONE);
usart_word_length_set(usartx, USART_WL_8BIT);
usart_stop_bit_set(usartx, USART_STB_1BIT);
usart_data_first_config(usartx, USART_MSBF_LSB);

usart_transmit_config(usartx, USART_TRANSMIT_ENABLE);
usart_receive_config(usartx, USART_RECEIVE_ENABLE);

nvic_irq_enable(usartx_irq, 2, 2);
usart_interrupt_enable(usartx, USART_INT_RBNE);
usart_interrupt_enable(usartx, USART_INT_IDLE);

usart_enable(usartx);

GD32 适配实现(换芯片只改这部分)

// 03_HAL/chip_port/gd32/chip_port_uart.c

// 哪个串口
uint32_t usartx = USART0;
uint32_t usartx_rcu = RCU_USART0;
uint32_t usartx_irq = USART0_IRQn;

// 波特率
uint32_t usartx_p_baudrate = 115200;

// TX引脚配置
uint32_t usartx_tx_port_rcu = RCU_GPIOA;
uint32_t usartx_tx_port = GPIOA;
uint32_t usartx_tx_pin = GPIO_PIN_9;
uint32_t usartx_tx_af = GPIO_AF_7;

// RX引脚配置
uint32_t usartx_rx_port_rcu = RCU_GPIOA;
uint32_t usartx_rx_port = GPIOA;
uint32_t usartx_rx_pin = GPIO_PIN_10;
uint32_t usartx_rx_af = GPIO_AF_7;

/*************** GPIO 初始化 ***************/
// TX
rcu_periph_clock_enable(usartx_tx_port_rcu);
gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);

// RX
rcu_periph_clock_enable(usartx_rx_port_rcu);
gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);

/*************** USART 初始化 ***************/
rcu_periph_clock_enable(usartx_rcu);
usart_deinit(usartx);

usart_baudrate_set(usartx, usartx_p_baudrate);
usart_parity_config(usartx, USART_PM_NONE);
usart_word_length_set(usartx, USART_WL_8BIT);
usart_stop_bit_set(usartx, USART_STB_1BIT);
usart_data_first_config(usartx, USART_MSBF_LSB);

usart_transmit_config(usartx, USART_TRANSMIT_ENABLE);
usart_receive_config(usartx, USART_RECEIVE_ENABLE);

nvic_irq_enable(usartx_irq, 2, 2);
usart_interrupt_enable(usartx, USART_INT_RBNE);
usart_interrupt_enable(usartx, USART_INT_IDLE);

usart_enable(usartx);

五、统一接口封装(上层调用)

// 03_HAL/chip_port/chip_port_uart.c(统一对外接口)
#include "chip_port.h"

static uint8_t uart_rx_buffer[256];
static uint16_t uart_rx_index = 0;

void uart_init(uint32_t baudrate)
{
    // 调用具体芯片的初始化代码(上面实现的)
    // 这里直接复用上面的USART配置代码
}

void uart_send(uint8_t *data, uint16_t len)
{
    for(uint16_t i = 0; i < len; i++)
    {
        while(usart_flag_get(usartx, USART_FLAG_TBE) == RESET);
        usart_data_transmit(usartx, data[i]);
    }
}

uint16_t uart_recv(uint8_t *data, uint16_t max_len)
{
    // 从环形缓冲区读取数据
    // 具体实现略
}

void uart_irq_handler(void)
{
    if(usart_interrupt_flag_get(usartx, USART_INT_FLAG_RBNE) != RESET)
    {
        uint8_t rx_data = usart_data_receive(usartx);
        // 存入环形缓冲区
    }
}

六、应用层代码(完全芯片无关)

// 01_App/app_task.c
#include "chip_port.h"

void led_task(void)
{
    gpio_set(LED_PIN, 1);      // 不管STM32/GD32,代码一模一样
    delay_ms(500);
    gpio_set(LED_PIN, 0);
    delay_ms(500);
}

void uart_task(void)
{
    uint8_t tx_buf[] = "Hello World\r\n";
    uart_send(tx_buf, sizeof(tx_buf) - 1);
}

七、换芯片操作流程

  1. 复制整个项目框架文件夹
  2. 替换 04_ChipLib 原厂库
  3. 在 03_HAL/chip_port 新增芯片适配文件
  4. 实现统一抽象接口(GPIO/UART/SPI等)
  5. 上层 01_App + 02_Middleware 一行不改
  6. 编译下载,直接运行

八、核心优势

场景传统方式本框架方式
换芯片1周1天(只改HAL层)
换项目从头搭建复制框架 + 改配置
换人开发需理解全部代码按分层定位,快速上手
代码复用率< 30%≥ 80%
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐