working in esp8266, i found some situations installing some libs (lua interpreter, for "dofile()" function) in which the application is unable to read internal flash littlefs because LittleFS.h (or FS.h) doesnt follow expected ISO/ANSI/GNU interface (stdio.h, dirent.h, FILE, DIR, etc)
how can we circumvent this difficulty? .. how could LittleFS.h (or FS.h) be rewritten or wrapped to use all filesystem standard C[++] facilities offer us? .. or does exists some other LittleFS "standard" lib for arduino/esp?
LittleFS is written for Arduino to have the same API as the Arduino SD library. the File class implements the Arduino base Stream class for familiar print, write, read functions.
yes i though that... do you know some bridge, wrapper or someway to make filesystem interaction "standard" again, so can be used with other "standard" libraries? ... not only for Lua loadfile()
i found esp8266-arduino uses redhat newlib, that uses standard filesystem headers objects and functions like stdio.h, dirent.h, FILE, DIR, fopen(), readdir(), etc ... but for some reason they were stripped down from esp8266-arduino .. maybe some way to reactivate them?
i don't think so necessarily, with just a filesystem should be enough ... however other functions surely require an OS like getpid(), fork(), get/setenv(), mkfifo(), uptime(), times(), signal(), etc
i don't know/understand why arduino FS/SD library didn't follow standard C headers .. even though basic similar functions are documented in avr libc (like FILE, fopen(), fread(), fget(), fwrite(), fput() flush(), fclose()) = AVR-LibC: <stdio.h>: Standard IO facilities
.. i think the correct way would have been to complement FS library with standard compatible structures instead, like DIR, struct dirent, etc , that would make arduino ecosystem more portable and compatible with other platforms/projects
i dont know how to motivate somebody to do this and take as a personal project/challenge to fix it because i dont have that so advanced knowledge ... anyone up for it?
i am trying to write a library to make LittleFS expose an api compatible with stdio.h and other C standard libraries ...
i started by examining actual esp8266 LittleFS library source code and reading some C documentation in cppreference.com, gnu.org and other sources.. and also asking some question to AI since i am not a developer and is hard to me
i managed to implement a basic minimal library with begin() function (includes mount), and littlefs_fopen(), littlefs_fread() and littlefs_fclose() for start ... later i will need help in replacing standard i/o functions with these
what keeps me stucked right now is how to manage standard streams (stdio, stdout, stderr)... i want to make a multiuser remote console application and redirect stantard streams to corresponding client stream in a round-robin fashion
my idea is to make custom read_byte() and write_byte() low level functions and replace them from current ones in stdin/stdout/stderr according connected client ... but i couldn't find a way on how AND WHERE to do it .. i will appreciate if you help me please
So presumably it's called littleFS for a reason; it's designed to work with small amounts of space, in flash memory, on microcontrollers with low performance and small amounts of program memory and RAM. Supporting a full POSIX-compatible filesystem is probably too expensive (or SEEN as too expensive, anyway. I guess an ESP8266 with 4MB of flash ought to out-perform an PDP11 with 128k RAM and a 5MB RM05 or similar.)
Even the newlib-based printf() implementations are depressingly bloated, largely because they thing the serial port has to be a "file."
Which particular APIs are you looking for?
Did you look at those at all? They're not very similar to the POSIX API at all; in particular they have "streams" at the bottom layer.
I don't see what that has to do with "filesystems." Trying to implement a standard file-based infrastructure over microcontroller-class hardware, only to have to implement weird ioctl(), tcsetattr(), select() and etc just so you can get to "raw, single-character non-blocking IO" that the Arduino "Serial" object gives you by default seems like an incredibly bad idea.
(I guess you want to start with some existing linux application, rather than from scratch. I can sympathize, but ... I think you'd be a lot better off trying to modify the app rather than modify the Arduino "environment" to look more like linux.)
A trivial multi-com port Arduino program looks like:
void loop() {
Serial.println("This is Serial");
Serial.println("1");
Serial1.println("This is Serial 1"); // Check Transmit
while (Serial1.available()) { // Check receive
Serial1.print("Serial 1 read ");
Serial1.println(Serial1.read());
}
Serial.println("2");
Serial2.println("This is Serial 2");
while (Serial2.available()) {
Serial2.print("Serial 2 read ");
Serial2.println(Serial2.read());
}
Serial.println("3");
Serial3.println("This is Serial 3");
while (Serial3.available()) {
Serial3.print("Serial 3 read ");
Serial3.println(Serial3.read());
}
delay(1000); // wait a bit for more data.
}
but instead of make littlefs lib implement this api (FS.h), they could made implement that api (stdio) (at least partially)... is the same thing
... anyway i never talked about supporting a FULL COMPILANT posix interface, that will be very big.. i know avr-libc was stripped down from some standards to make fit in avr uc, and is fine
i want to make an esp8266 microcomputer like atari 8-bit, apple 1/2, cp/m or a retro pc with msdos+basic, but with lua+littlefs instead, accessible through NETCAT...
lua makes extensive calls to standard i/o functions to work with files and streams, that is why i am trying to write a littlefs wrapper with a standard stdio api first (i don't want to modify lua source code for portability and maintainability)
so, the idea i have at this point so far is just to write custom low level i/o functions with same prototype and just replace them in stdin/out/err FILE i/o function pointers, relying on global pointers to Stream according current client in turn
... how to do this?, something like this?
Stream* globalStream = &Serial; // "default" stream
// prototype taken from sys/reent.h:struct __sFILE but i'm not sure
// just guessing the arguments and returns
_READ_WRITE_RETURN_TYPE custom_write(struct _reent* r, void* ctx, const char* data, _READ_WRITE_BUFSIZE_TYPE len);
(void*) r;
(void*) ctx;
return globalStream->write(data, len);
}
// replacing the (_write*) function pointer in stdout FILE*
stdout->_write = custom_write;
// serving one client at a time in round-robin
{
globalStream = &client;
run_repl(client); // this way, if client uses stdout will print to corresponding client, theoretically
globalStream = &Serial; // restore "default" stream
}
but this led me some questions, like: which is the INTERNAL MECHANISM so when some sketch/library/app accesses stdout it will end printing to Serial??, whatever baud rate or config it has
I was under the impression that Lua had already been ported to ESP8266 (in fact, it predated the Arduino port.) Doesn't that version support files? Um... : NodeMCU Documentation (I don't know if it supports access via WiFi, though. IIRC, it's aimed at writing WiFi apps via the UART port...)
Arduino originally had no filesystem at all, so it developed it's stream/print APIs without any idea that there would ever be "files."
AFAIK, ESP Arduino cores do not prevent the use of the more native ESP-sdk functions, so there is probably the newlib file functions are available.
"stdio" for printf/etc can be easily redirected to Serial for AVR and SAMD, and samd is also newlib based. Try:
elua project = https://eluaproject.net/ : lightweight lua language fork, but less known than original lua
maybe others i don't know
there are also other projects to bring lua language to arduino ide, but that just to replace IDE compiler from C++ to Lua, sketch is still compiled and flashed to ESP as always, it doesn't bring "Lua interactive console" capablities to modules nor any Lua magic
yes arduino had no filesystem support originally (until somebody start to manufacture SD card shields *)... but esp8266/32 does have natively from start!
(* why the heck didn't they make SD.h library use standard C library interfaces from beginning !!??)
where is the official documentation?, i was always searching for that
sounds very interesting!... but how this serves me to modify already existing standard streams FILE* i/o functions? (to reuse already allocated ram and avoid chance to broke things)
but the question i still open: which is the INTERNAL MECHANISM so when some a program accesses stdout it will end printing to Serial?? ... so we can examine functions, and emulate them, and replace them