Abstracting graphics display (different size, colors?). Menu system? PPM? It feels some abstraction layers are strongly part of application type (such as "transmitter fw") and hence perhaps belong to the application, should it choose to be portable.
No these don't need abstractions. The scope of libk is to provide abstraction for framebuffer only. Then any graphics library can use the "canvas" to draw stuff on any supported display. And yes, graphics library is part of the application code - as well as things like flight control algorithms etc.
PPM however would be an platform layer function, just like PWM (because it is greatly dependent on the hardware - in this case timers). It would be reasonable to have configurable ppm as part of arch/soc layer that the board code can use to set ppm signal. The board code is part of libk however, but it's job is to expose a simple interface to the board that the application code runs on. For instance on fs-t6 radio it could be a call that looks like: fst6_write_ppm(chan1, chan2, chan3, chan4, chan5, chan6). That would be the only call that application would need to instruct fst6 board to send channel values to the rc model. The rest of the code of actually generating the ppm signal would be part of the library with parts of it being very architecture specific.
Update: i have working eeprom driver here: https://github.com/mkschreder/martink/b ... ock/at24.c
(the eeprom on flysky t6 board). fst6_write_config and fst6_read_config now use eeprom to save the config. https://github.com/mkschreder/martink/b ... ky-t6-tx.c
State of I2C: on avr i2c is all done and interrupt based. On stm32, i2c is currently very simple procedural approach that works, but is far from ideal. Ideally one would implement i2c using dma and with the same 3 calls: i2c_start_write, i2c_start_read and i2c_stop. I will add it into https://github.com/mkschreder/martink/b ... tm32/twi.c
once I get dma i2c working.
I can see some potential problems: code bloat (abstractions), performance (least common denominator, layers), polluting generic libk with application specific services ("read sticks").
The abstractions are all very thin. I could even have chosen to wrap them all into macros - in fact a lot of the lowest level stuff on avr is all macros. But I have moved away from macros for things like timestamp_expired() calls because macros made the overall size of executable too large (-Os flags have no effect on macros). The main abstraction is the layer that provides interfaces. I have come to conclusion that this layer is absolutely necessary if one wants to have things like external devices working seamlessly regardless of which number i2c interface they are connected to and regardless of how the connection is made. For example, it is possible to use gpio abstraction to treat an i2c gpio expander as though it was a normal on chip gpio. This allows to use many devices that may be controllable through normal gpio over i2c gpio (for instance LCD displays that connect over pcf i2c gpio expander). So I use some abstractions - but very few.
The layers of abstraction are similar to what desktop os uses such as linux, but we remove A LOT of the stuff that is completely unnecessary on small processors like the ones in many of the boards we are working on. The idea is that instead of following the "OS" model which uses threads and other multitasking concepts, we remove all of the uncertainties associated with multitasking and instead focus on reusable abstractions. OS model is really not perfect and even frameworks that run on desktops, like nodejs, are moving away from the threaded model completely. Without threads, abstractions are thinner, code more simple and concurrency issues gone completely. Without threads and without multi-user environment one does not need to have all that extra code that handles these things. Libk uses instead a very tight main loop, interrupt based data transfers and systicks counter for running tasks at intervals. But everything is all single thread and no application code is ever interrupted by other application code.
Performance: here is how it works: if speed is absolutely necessary one can use arch specific calls such as "gpio_set() or gpio_clear()" directly. All these calls are present for the application to use (on avr these calls are macro based so speed is maximal). However, if one needs to use a device that is usable on both arm, avr, or any other board - then one would naturally implement an abstraction anyway. So sacrificing a little of performance for possibility of writing a more portable firmware is something one is usually willing to do. Also, code bloat is greatly reduced when code is factored into smaller parts that are responsible for specific tasks.
Perhaps Richard can contribute a thought as he put nice solid foundation into art6.
Well, thanks to Richard I got ks0713 display working in no time.
So Richard has already contributed some. I have made Richard's display code work with vt100 emulator driver, made it compatible with serial port interface, and made it use my built-in font for drawing text. Updated code here: https://github.com/mkschreder/martink/b ... p/ks0713.c
LibK - Cross platform bare metal firmware development library: https://github.com/mkschreder/martink