[RFC] [*]: add support for compile-time polymorphism#8
[RFC] [*]: add support for compile-time polymorphism#8rizlik wants to merge 1 commit intowolfSSL:mainfrom
Conversation
There was a problem hiding this comment.
I love the idea but I do think this could be simplified by doing the following.
First we can remove runtime polymorphism all together.
Second, keep the driver function declarations in the driver header.
Then we can do the following:
clock.h:
#define whal_Clock_Init(NAME) whal_##NAME##_Init((NAME))
...more defines here for each API function...
#define WHAL_CLOCK_DEVICE_DECLARE(NAME, DRIVER) \
extern whal_Clock ##NAME[1]; \
static inline whal_Error whal_##NAME##_Init(whal_Clock *clk) { \
return whal_##DRIVER##_Init(clk); \
} \
static inline whal_Error whal_##NAME##_Deinit(whal_Clock clk) { \
return whal_##DRIVER##_Deinit(clk); \
} \
static inline whal_Error whal_##NAME##_Enable(whal_Clock clk) { \
return whal_##DRIVER##_Enable(clk); \
} \
static inline whal_Error whal_##NAME##_Disable(whal_Clock clk) { \
return whal_##DRIVER##_Disable(clk); \
} \
static inline whal_Error whal_##NAME##_GetRate(whal_Clock clk) { \
return whal_##DRIVER##_GetRate(clk); \
}
#define WHAL_CLOCK_DEVICE_DEFINE(NAME, REGMAP, CFG) \
whal_Clock ##NAME##[1] = { \
.regmap = REGMAP, \
.cfg = CFG, \
}
pic32cz_curiosity_ultra.h:
WHAL_CLOCK_DEVICE_DECLARE(clock, Pic32czClockPll);
pic32cz_curiosity_ultra.c:
WHAL_CLOCK_DEVICE_DEFINE(clock, WHAL_PIC32CZ_CLOCK_REGMAP,
&(whal_Pic32czClock_Cfg) {
/* 300MHz clock */
.oscCtrlCfg = &(whal_Pic32czClockPll_OscCtrlCfg) {
.supplyCtrl = &g_whalSupply,
.supply = &(whal_Pic32czSupc_Supply){WHAL_PIC32CZ_SUPPLY_PLL},
.pllInst = WHAL_PIC32CZ_PLL0,
.refSel = WHAL_PIC32CZ_REFSEL_DFLL48M,
.bwSel = WHAL_PIC32CZ_BWSEL_10MHz_TO_20MHz,
.fbDiv = 225,
.refDiv = 12,
.outCfgCount = 1,
.outCfg = &(whal_Pic32czClockPll_OutCfg) {
.postDivMask = WHAL_PIC32CZ_POSTDIVMASK0,
.outEnMask = WHAL_PIC32CZ_OUTENMASK0,
.postDiv = 3,
},
},
.mclkCfg = &(whal_Pic32czClock_MclkCfg) {
.div = 2,
},
.gclkCfgCount = 1,
.gclkCfg = &(whal_Pic32czClock_GclkCfg) {
.gen = 0,
.genSrc = WHAL_PIC32CZ_GENSRC_PLL0_CLOCKOUT0,
.genDiv = 1,
},
}
);
main.c
#include <pic32cz_curiosity_ultra.h>
void main(void) {
whal_Clock_Init(clock);
...
}
This would also make the WHAL_DRV_FN unnecessary since the define macro would guarantee the correct naming
Thoughts?
| uint8_t tmp[sizeof(test)] = {0}; | ||
|
|
||
| err = whal_Clock_Init(&g_whalClock); | ||
| err = WHAL_CLOCK_INIT(clock); |
There was a problem hiding this comment.
Not sure I like having to use all caps to use this library
There was a problem hiding this comment.
I know it's ugly, but I also dislike having a macro lowercase. Not sure what's best here, this way it's clear that there is more macro trick behind
| */ | ||
|
|
||
| whal_Error whal_Pic32czClockPll_Init(whal_Clock *clkDev) | ||
| whal_Error WHAL_DRV_FN(Pic32czClockPll, init)(whal_Clock *clkDev) |
There was a problem hiding this comment.
I don't like this. This will make the every driver function essentially un-grepable
There was a problem hiding this comment.
interesting point, I want to avoid that there is some rule the driver maker must "known" about how to name function, I need to evaluate the general comment yet, so probably will not be needed
| whal_Error (*init)(whal_Clock *dev); | ||
| whal_Error (*deinit)(whal_Clock *dev); | ||
| whal_Error (*enable)(whal_Clock *dev, const void *clk); | ||
| whal_Error (*disable)(whal_Clock *dev, const void *clk); | ||
| whal_Error (*getrate)(whal_Clock *dev, size_t *rate); |
There was a problem hiding this comment.
Keep naming convention. First letter of functions should be capitalized. Also why remove comments?
There was a problem hiding this comment.
sorry I'll reput commnets it wasn't intentional.
| static inline whal_Error whal_dev_##NAME##_init(void) { \ | ||
| return WHAL_DRV_FN(DRIVER, init)(&whal_dev_##NAME); \ | ||
| } \ | ||
| static inline whal_Error whal_dev_##NAME##_deinit(void) { \ | ||
| return WHAL_DRV_FN(DRIVER, deinit)(&whal_dev_##NAME); \ | ||
| } \ | ||
| static inline whal_Error whal_dev_##NAME##_enable(const void *clk) { \ | ||
| return WHAL_DRV_FN(DRIVER, enable)(&whal_dev_##NAME, clk); \ | ||
| } \ | ||
| static inline whal_Error whal_dev_##NAME##_disable(const void *clk) { \ | ||
| return WHAL_DRV_FN(DRIVER, disable)(&whal_dev_##NAME, clk); \ | ||
| } \ | ||
| static inline whal_Error whal_dev_##NAME##_getrate(size_t *rate) { \ | ||
| return WHAL_DRV_FN(DRIVER, getrate)(&whal_dev_##NAME, rate); \ |
There was a problem hiding this comment.
Don't change the function naming scheme. It should be whal_Clock_Init. no need for whal_dev_
There was a problem hiding this comment.
this is not the "general" function though, it's just a wrapper for the specific device. The problem is that if you name a device gpio to end up with function named whal_gpio_init() that might clash with other functions.
I think namespacing this tiny wrapper function is useful. They should never be called directly btw as the other macro expands to that
There was a problem hiding this comment.
Ahh, agreed. Maybe rename whal_dev_ to whal_Internal_ just so it's a more clear it's not supposed to be used directly?
|
Hmmm, now that I think about it, compile time polymorphism may make it impossible to implement a driver that needs to use a multiplatform driver call in it's implementation. For example, say microchip releases a new SoC pic32cz2. Let's say our current pic32cz UART driver supports this new pic32cz2 SoC but our pic32cz clock driver doesn't. Right now our pic32cz uart driver is hard coded to use the pic32cz clock driver. Or maybe a better example is implementing a SPI flash driver. The driver implementation would need to be able to call SPI functions from any SPI driver we have. And runtime determination of which underlying spi driver to use would be unavoidable in the case where the SoC has two different SPI IPs on the same chip. It may be best to just handle this by just calling the driver function directly in cases where the user doesnt want to use runtime polymorphism. |
No description provided.