本帖最后由 xcvista 于 2021-4-27 16:03 编辑
这是我有史以来见过最令人作呕的一座屎山。
Cortex-M23 核心
// gd32e23x.h
#include "gd32e23x_libopt.h"
RISC-V 核心
// gd32vf103.h
#if !defined USE_STDPERIPH_DRIVER
#define USE_STDPERIPH_DRIVER
#endif
#ifdef USE_STDPERIPH_DRIVER
#include "gd32vf103_libopt.h"
#endif /* USE_STDPERIPH_DRIVER */
这种强制绑定所谓标准库是什么迷之操作?我是看着就火大。为什么 GD 就不能像全世界所有其他芯片厂商一样,设备头文件和标准库分离开来,让开发人员可以各取所需?
然后设备寄存器定义……
// gd32e23x_gpio.h
/* GPIOx(x=A,B,C,F) definitions */
#define GPIOA (GPIO_BASE + 0x00000000U)
#define GPIOB (GPIO_BASE + 0x00000400U)
#define GPIOC (GPIO_BASE + 0x00000800U)
#define GPIOF (GPIO_BASE + 0x00001400U)
/* registers definitions */
#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */
#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */
#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */
#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/pull-down register */
#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */
#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */
#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */
#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */
#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */
#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */
#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */
#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle register */
这是什么奇葩代码结构?1202 年了都不知道结构体为何物?还是说是是为了照顾汇编语言?哪怕是为了照顾汇编语言我也没看到下面有 #ifndef ASSEMBLER 之类的代码啊?
至于那个所谓的标准库么……
// gd32f23x_gpio.c
void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
{
GPIO_BOP(gpio_periph) = (uint32_t)pin;
}
这种一行代码的函数还要单独放在 C 文件里面,而不是放到头文件里面去 inline?就算编译器知道不要为这种函数单独开帧框,一个调用一个返回都是代码量、分支预测失败风险和闪存预取队列清空的开销啊。何况在这个极端例子里面,原本无等待一条指令可以解决的事情硬生生变成了至少三条指令和好几个等待周期啊。再说了,所有这些非内连函数都要占用标识符命名空间,我之前遇到的奇葩冲突看来就是这地方出问题了。
你们要方便客户我能理解,但是这种强制绑定是什么迷之操作?然后绑定的还是一座屎山?然后好不容易提高频率挤出来的处理性能,全都被恶臭的代码给吞了。
补充:GD32 的 SVD 写的也是屎,要不然我看不惯这个头文件还有 SVDConv 重新转一个出来这条路。现在就直接变成想要用这颗芯片我要从重写/重构 SVD 开始。
|
@雨水 :我的比较标准是 SVDConv 的输出文件……
确实不行,感觉我去摸一摸估计都写得好点