秦皇岛市网站建设_网站建设公司_HTTPS_seo优化
2025/12/22 8:45:12 网站建设 项目流程

通过mplab添加harmony框架提供的sam9x60的usb驱动,总比自己适配tinyUSB之类的要快嘛

然后就发现遇到第一个坑。仅添加usb host layer 驱动后编译就报错了

volatile uint32_t * interruptList = hDriver->hcHCCA->hccaInterruptTable; 

说它
drv_usb_ohci.c:142:41: error: taking address of packed member of 'struct USB_OHCI_HCCA' may result in an unaligned pointer value
以及后面凡是对这个hcHCCA->hccaInterruptTable 进行32位指针化都会报这个错。

原因是它的结构体定义USB_OHCI_HCCA ,是添加了__attribute__((packed)) 修饰符的。
导致结构体成员可能没有按照自然对齐要求排列,直接获取 hccaInterruptTable 成员的地址会产生未对齐指针。

typedef struct __attribute__((packed)) USB_OHCI_HCCA
{volatile uint32_t hccaInterruptTable[32];volatile uint16_t hccaFrameNumber;volatile uint16_t hccaPad1;volatile uint32_t hccaDoneHead;volatile uint8_t  reserved[116];} USB_OHCI_HCCA;

这是因为大多数CPU要求特定类型的数据必须存储在特定地址上(例如32位数据必须存储在4字节对齐的地址上),而USB OHCI控制器的硬件通信区域定义,它们的内存布局必须与硬件规范完全一致。
这些结构体是硬件寄存器的直接映射,任何内存布局的变化都可能导致与硬件通信失败。使用 attribute((packed)) 修饰的结构体,编译器会压缩存储,不考虑自然对齐要求。
于是进行32位指针化时错误就发生了。

解决方案有多种,反正都是ai给的,我只说说能编译的。
第一个,获取的时候计算成员地址。
volatile uint32_t * interruptList = (volatile uint32_t *)((uint32_t)hDriver->hcHCCA + offsetof(USB_OHCI_HCCA, hccaInterruptTable));
方案特点:

  • 保持了结构体的 packed 布局(与硬件兼容)
  • 使用 offsetof 宏安全计算成员地址,避免未对齐访问
  • 不改变硬件通信区域的内存布局,确保系统稳定性
  • 是处理packed结构体成员访问的标准做法

第二种修改结构体成员 hccaInterruptTable 的对齐属性,给它单独添加修饰符

typedef struct __attribute__((packed)) USB_OHCI_HCCA
{volatile uint32_t hccaInterruptTable[32] __attribute__((aligned(4)));volatile uint16_t hccaFrameNumber;volatile uint16_t hccaPad1;volatile uint32_t hccaDoneHead;volatile uint8_t  reserved[116];} USB_OHCI_HCCA;

既能保留结构体其他成员的紧凑排列(packed 作用),又能强制该成员 4 字节对齐,彻底消除警告。

此外还有些需要特定编译器(gcc等,但我这是microchip的xc32编译器,我就不试了)
目前我选择第二个方案,单独给数组成员hccaInterruptTable添加修饰符使其对齐4k。能编译就行。

吐槽,这个是芯片官方框架提供的usb驱动的最新版本,当然我看了下前几个版本也是这个样子的。也不知道他们是怎么编译通过然后上传的。
如果是因为他们内部开发人员用的付费版编译器,那我真是无语了。
还有这个驱动能编译了也不代表能用,目前压根初始化不了,调试发现就是卡死在这个host layer 的初始化阶段。慢慢再继续给阿三擦屁股吧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询