this is clearly the wrong category but i dont know how to fit it better.
Want to show you the DwarfOS, or short dOS :).
It has got some cool features with 1.1.0, automatically creating far pointer const string arrays with a getter-Function from a array of strings, including a index-information on which position the string was in the original array, and creating array with indiviual maximal String Sizes to avoid unnecessary space consumation. Other modules as circular dynamically resizeable Input Queue from 7 to 244 byte, to use it as stdin , a serial communication module, a clock are also very cool. It has a own small ISO-conform time.h with CET/CEST/UTC timestamp-strings. It dont uses arduino libs and just a minimum of avr-gcc libs where necessary.
The modules can be loaded modulary into the memory. You can unload all the helpers during runtime. The Functions of the helpers are function pointers, you can easily change it to own modded implementations.
It has targets in his CMakeLists to print size, create a hex file or print the complete content of the flash memory.
For me its very useful, it has everything i need for a project, for easy setup and debugging from the start. And it consumes just a few dozen byte ram because of modular loading and unloading. Has a lot of comfort for this small amount.
Have fun, and i invite everybody to give critizm or join the project, its unter MIT.
Look into colossal cave adventure repo for a example how to use this const progmem arrays and the automatically generated getters.
For debugging I need timestamps for example and ram usage. And see if setup is completed. With Sim AVR and a virtual serial port, I use simutron as GUI, you have this first line at the top where it shows setup, and can use it immediately as stdout with printf.
It does the same as a few arduino libs, but smaller and smarter imho.
You dont need minimal Ram, these Arrays costs only 2byte for every array, for the pointer.
For example see how i parsed the original strings from the game into my arrays
Here i did the parsing
Here is one file
This costs you 5 x 2 byte ram for the 5 arrays and 2 byte for the getter function (plus 2 x 2 byte for the pointer to the strings that didnt fit into the arrays with the borders i gave). And if you want to load a string from the progmem you need the free heap memory, otherwise malloc will fail. If you want to load a string with 1,5kB length you need this free memory, but you can free the memory immediatly after using the string.
The nice thing is, it automatically produces now these progmem arrays and the getter function. you dont need a pointer (2byte Ram) for every string in Progmem, just for one Array 2byte.
There is still work to be done, i work alone at it in my holidays. But for example these two lines belong to colossal cave adventure and the generator added it also in other projects atm, there you get the initialized flash helper that is used.
" #include "advent.h" #include "advdec.h"
"
EDIT:
Since last hour it also decide if your Arduino has more or less than 64kB Flash and uses far progmem pointer only for the devices with more and produces a other getter function for the smaller devices.
Also this naming for the generated define could be changed. I work on the os parallel to CCA, and so sometimes i mixed the concepts to much. But i think there are some smart ideas that solve problems that arent solved before with such less ram consumation. And its MIT, it has a CMakeLists and is ready for every IDE. I really invite everybody to join, even with critique or such questions.
EDIT3: Testing and writing Issues will also help, i cant test every modul atm, i enjoy my holidays with working on CCA.
EDIT4: Its possible to implement this modular loading from the helpers also to this getter function, it would spare 2byte or maybe 4. But if you have 10 of these text files this could be worth the effort.
If you have problem with ram management there is this lazyloading, it is now only adapted to Near Progmem strings, because i was a beginner when i wrote this, but its easily adapted to far strings if needed, and it has some comfort functions to cache strings in ram and free them randomly. If you have for example 6kB free Ram you can cache a lot of strings there that are often used, ask the heap helper for free ram, free some of the cached strings just randomly if you havent enough and if the strings you need arent cached anymore this repo will load them, or serve them from the cache if still there. You dont have to look for yourself if they are still in Ram after the random cleaning. And the placement is with hashing, so its O(1) for searching a string.
This is Ram consumption compiled for AtMega328p, so it uses only 72byte for this comfort. And some of these bytes are overhead included in every program.
There are still 6 or 8 bytes included for my adjustment to a second, the testOs function and the loaded heapHelper. So overhead is less than 40kB. You have all the memory free. Load helpers (they cost 2 bytes of heap for every function) and unload/free them immediatly after use.
Maximum length of a string of the Colossal Cave Adventure is around 1,5kb. So i need 1,6kb free Heap to load it from my arrays, and can unload it immediatly. So i have 4,4kB free where i could cache smaller strings. The game has a lot of strings around 50-100byte. I could cache for example 80 strings that are often used with 50byte length, or 200 with 20 byte, etc.
But the thing is, the game will work also just with 1,6kb free Mem, i could install several of these games parallel, if i have enough Space for their strings.
EDIT: 400byte free memory you can find also at a ATMega328P, this is enough for 5 console lines. Why you wouldn't recommend this, if this is the maximum i need?
EDIT2: And you see how small i can make a working program. You can do so much things with for example 500byte Ram, and can still load the longest strings from the game at a ATMega328p.
There is even the possibility to read these progmem strings per hand, every single character and put the character directly into stdout, into the register of USART TX, need a small additional function in the flashHelper and a connection to stdout, then you wouldnt need any memory at all and you can send 100kb Strings. Also with 28kBaud its just 4sek
Think i will implement this too if ELPM is not avaible for example, Users with a AtMega328P will love it.
On Devices with less ram, you often have also <64kB Flash, and then puts_p is working just fine and the code for a AtMega328P is really small. This dont load the flash string into the memory at all. It works with one or 2 byte free ram.
EDIT: I get used to give the strings one byte more space in progmem as the require, to ensure, that i find always a null termination. Had some strange behaviours before.
EDIT2: Think will try to make another getter for the progmem arrays that uses this approach and print them directly to stdout, if you dont need it in memory for manipulation.
I am not sure why there is no puts_pf but maybe I will find out when I try to implement it.
And standard conform dwarfOS will probably get it's own stdio.h with this function.
Now the example show the purpose of the modularity, I can easily produce different examples, complete different combinations of the modules, but it's just 4 lines copy paste in CMakeLists for every new Example, three dozen lines copy paste from one example, mostly the includes and setup, having a small as possible system, and adding one up to three dozen lines with the actual new example and can freely decide which amount of ressources I use. At first I made this for me. And most probably I won't do such tasks as documentation with same effort as a employee, also now I have holidays, don't have always so much ressources.
But I enjoy this toolset very much, therefore I hope I find people to work on it with me here.
Edit2: I have a nephew, 11y old, programming simple python, I made this also to ease these kids programming MCU with c, with this comfort functions of heap management etc, but there is a gap in the documention how to implement the library into Atmel Studio. Won't do this tbh in the near future.
No, User has to send a uint32_t farpointer, user has to use get_far_address before calling the function, but then its just changing some types here. You will get your puts_PF(uint32_t farPointerToString).
EDIT2: There is clearly a way, maybe somebody has time to test this if he urgently need it