You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何便捷访问STM32系列芯片USB外设的PMA存储器

STM32 USB PMA 访问的优雅实现方案

下面是兼顾可维护性、可读性和兼容性的三种实现方案,可根据实际使用场景选择:


方案1:封装PMA专用访问宏/内联函数(最通用)

根据PMA的固定映射规则:16位PMA逻辑地址n对应的CPU物理地址 = PMA基地址 + (n << 1),直接封装底层读写接口,完全屏蔽硬件对齐细节:

// 定义PMA外设基地址
#define PMA_BASE 0x40006000UL

// 读取指定PMA逻辑地址的16位数据
#define PMA_READ16(n) (*(volatile uint16_t *)(PMA_BASE + ((n) << 1)))
// 向指定PMA逻辑地址写入16位数据
#define PMA_WRITE16(n, val) (*(volatile uint16_t *)(PMA_BASE + ((n) << 1)) = (val))

使用时直接传入PMA逻辑地址即可,不需要处理对齐、填充:

// 示例:写PMA地址0x006
PMA_WRITE16(0x006, 0x1234);
// 示例:读PMA地址0x001
uint16_t val = PMA_READ16(0x001);

方案2:封装PMA专用类型,保留结构体访问习惯

如果需要保持结构体的访问方式,可以定义强制32位对齐的PMA专用16位类型,编译器会自动处理填充,不需要手动加保留位:

// PMA专用16位类型,自动占4字节空间,低16位有效
typedef union {
    volatile uint16_t val;
    volatile uint32_t _reserved; // 强制32位对齐
} pma_uint16_t;

// 缓冲区描述符结构体,无需手动加填充、无需packed属性
struct buf_desc_entry {
    pma_uint16_t addr;
    pma_uint16_t count;
};

使用时直接访问val成员即可:

struct buf_desc_entry *desc = (struct buf_desc_entry *)PMA_BASE;
desc->addr.val = 0x008;
desc->count.val = 64;

方案3:封装批量读写函数,适配8位数据访问

如果需要在PMA和普通SRAM之间批量传输8位数据(比如USB数据包读写),可以封装专用拷贝函数,内部自动处理地址转换和拼接:

// 将普通SRAM的8位数据批量写入PMA
void pma_write_buf(uint16_t pma_start, const uint8_t *src, uint16_t len)
{
    for (uint16_t i = 0; i < len; i += 2) {
        uint16_t tmp = src[i];
        if (i + 1 < len) tmp |= (uint16_t)src[i + 1] << 8;
        PMA_WRITE16(pma_start + (i >> 1), tmp);
    }
}

// 将PMA数据批量读到普通SRAM的8位缓冲区
void pma_read_buf(uint8_t *dst, uint16_t pma_start, uint16_t len)
{
    for (uint16_t i = 0; i < len; i += 2) {
        uint16_t tmp = PMA_READ16(pma_start + (i >> 1));
        dst[i] = tmp & 0xFF;
        if (i + 1 < len) dst[i + 1] = (tmp >> 8) & 0xFF;
    }
}

方案优势

  • 无需手动为结构体添加填充位,避免人为错误
  • 不需要强制全局变量32位对齐,不影响普通8位/16位变量的使用
  • 硬件细节完全抽象,上层代码不需要记忆PMA映射规则,可读性更高
  • 可移植性强,更换不同PMA映射的STM32型号时,仅需修改底层宏和函数实现即可

内容的提问来源于stack exchange,提问作者Sam Bazley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 19:03:03