打印
[其他产品]

硬件问题的问题经验分享

[复制链接]
265|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
meiyaolei|  楼主 | 2025-7-14 15:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在做MCU项目,跨芯片移植是家常便饭,硬件抽象层(HAL)要是搭不稳,代码分分钟炸窝。
今天就跟大伙唠唠,怎么利用厂家资源的同时,把HAL层做扎实,技术要求是啥,再吐槽几个踩过的坑。

厂家库是基础,但别完全依赖。现在MCU厂家确实给力,STM32、NXP这些大厂的库文件、设计案例一大堆,技术支持也到位。但直接用厂家库有个大问题依赖也会太多。比如STM32的HAL库,初始化函数里可能默认开了某些时钟,换到GD32上,时钟树结构不一样,直接用就可能出问题。所以咱们得把厂家库当原料,而不是成品,得自己再加工一层。

技术要求上,接口必须宽进严出。啥意思?就是HAL层的接口得能覆盖所有硬件功能,参数得全。比如PWM初始化,不能只写个PWM_Init(duty),得把频率、占空比、死区时间电机控制必备都塞进去。
这样上层想调死区时间,直接改结构体就行,不用改函数调用。厂家库可能没这些参数,咱就得在HAL层补上。
然后是资源管理的全局视角。厂家库可能只管自己模块的资源,比如定时器、DMA通道,但项目里多个模块可能抢资源。比如电机控制用定时器1,通信用定时器2,换芯片后定时器编号可能变了,这时候HAL层得有个全局资源表,记录哪个定时器被哪个模块占用了。

可以看一下这个代码,相信好多人都用过。
typedef struct {
    uint8_t timer_id;    // 定时器编号
    uint8_t used_by;     // 被哪个模块占用(电机、UART等)
} Resource_Table;

static Resource_Table resource_table[MAX_RESOURCES];

HAL_Status Resource_Alloc(uint8_t *resource_id, uint8_t used_by) {
    for (int i = 0; i < MAX_RESOURCES; i++) {
        if (resource_table[i].used_by == 0) { // 未占用
            resource_table[i].used_by = used_by;
            *resource_id = resource_table[i].timer_id;
            return HAL_OK;
        }
    }
    return HAL_ERROR;
}
要是忘了这个,换芯片后两个模块抢同一个定时器,直接死机。

错误处理必须认真的去检查 ,厂家库可能假设硬件操作肯定成功,但实际可能翻车。比如SPI传输可能因为总线冲突失败,这时候HAL层得返回错误码,比如HAL_TIMEOUT、HAL_ERROR,让上层能处理。参数校验更关键,比如PWM频率不能超过芯片最大值,要是上层传个1MHz,而芯片只支持500kHz,HAL层得拦住,返回HAL_PARAM_ERROR,而不是让硬件瞎跑,所以还是需要针对性的进行。
再说说算法与HAL的配合。比如电机控制的PID算法,核心是计算占空比,但具体怎么输出到PWM,得靠HAL层屏蔽硬件差异。假设算法层算出占空比是80%,HAL层得把80%转换成对应芯片的寄存器值(比如16位定时器是65535*0.8=52428),同时处理死区时间、通道互补输出这些细节。这样算法层不用管是STM32还是GD32,调HAL_PWM_SetDuty(80)就行,分享的都是以前在进行时的一些经验,相信也有人会遇到过。
厂家库可能测试过,但咱的HAL层改过,得自己测。用Unity或CMake搭测试框架,模拟硬件操作,比如测SPI_Transmit(),模拟传输成功、超时、参数错误的情况,确保HAL层能正确处理。特别是资源冲突、参数越界这些边界条件,必须测到。有次用STM32的库直接移植到GD32,SPI的时钟分频计算方式不同,STM32是APB2CLK / (divider+1),GD32是APB2CLK / divider,结果SPI不通信,排查两天才发现是分频系数没改。还有次PWM初始化没传死区时间,电机换相时短路,烧了功率管。更惨的是资源表没写全,换芯片后定时器编号变了,两个模块抢同一个定时器,直接死机。
HAL层要稳,得做到:接口覆盖全、资源管理严、错误处理真、测试覆盖广。厂家库是好帮手,但得自己再“加工”一层,把隐式依赖、资源冲突这些坑填平。这样跨芯片移植才能少掉坑,代码也能更干净。

使用特权

评论回复
沙发
xinpian101| | 2025-7-16 09:00 | 只看该作者
这个方法很好啊,可以让一个模块被多个任务调用又不会争抢。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:工程师
简介:超越自我,为设计激发灵感和想象。

248

主题

811

帖子

6

粉丝