Closed jlecoeur closed 9 years ago
Sounds good! Some suggestions from what we've been doing for our AUV where we have plenty of different boards with different purposes (all AVR32 though):
static inline usart_config_t backplaneboard_debug_uart1_conf(void) {
usart_config_t usart_conf =
{ .mode=UART_IN_OUT,
.uart_device.uart=(avr32_usart_t*)&AVR32_USART1,
.uart_device.IRQ=AVR32_USART1_IRQ,
[...]
};
return usart_conf;
};
Init functions expect a pointer to the "data" object that will be passed in every call, and a pass-by-value of the "xxx_config" returned by the conf method, which it then copies into its data object or uses for initialisation. The only dependency is now to central_data which is board specific - but it's also project specific so it's not a big issue. Maybe all board-related parts of central_data could be packed into a sub_struct.
Thanks for the input, indeed moving boardsupports to the Library is the next step. I hope the field tests are going well!
Similar to the first solution, what do you guys think of this? https://gist.github.com/jlecoeur/e32fa5e47e464a26239f#file-test_uart-c-L123 This is basically polymorphism in C, and it enforces the initialization of function pointers
One big milestone for MAVRIC will be the moment the hal will be truly platform independent (ie able to run on avr32, linux and stm32).
Proposed folder organization
First I think we should separate the chip drivers, which are not platform specific, from the peripheral drivers, which is the real hal.
Then I see two possibilities to link the low-level and high level peripheral files
First solution
Using function pointers. A high level interface is created in boardsupport.h, and initialized using a low-level function in boardsupport.c
High level
hal/common/uart.h:
Low level
hal/avr32/avr32_uart.c:
Second solution
Depending on the files which are compiled, a low level implementation is chosen
High level
hal/common/uart.c:
Low level
hal/avr32/lld_uart.c:
The first one seems easier to handle. The good point is that you do not need to add code in the LIbrary to add a new uart, just instantiate and initialize a new object in the project folder. However, we have to ensure that all pointers are initialized by the low level drivers. The compiler cannot help here, if a feature is not implemented on a specific hardware, then it is possible to have a NULL pointer for the corresponding function.
The second solution is safer in the sense that it will not compile if the low level driver does not implement one of the functions. However by looking at the code, it is impossible to tell which function is called: there will be several implementations with the same function name. Also, it needs a way to choose the uart: either separate function (uart1_read(), uart2_read(), ...), or a parameter uart_read(uint8_t uart_id, uint8_t byte), in both case more code is needed for more peripheral.
Peripheral initialization
In both cases, it is not clear where to put the initialization.
@lis-epfl/mavric-lis What do you think?