This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
Hi Giovanni, I have external EEPROM IC on I2C bus and want to access to it in convenient way. ChibiOS has files abstraction level. Is it best way to deal with EEPROM? Are there any examples of using the file feature (code looks too weird for me)?
There are two things you can do with an interface: 1) Extend it adding new method signatures. 2) Implement it.
In your case, if BaseFileStream has all the methods you need then you just have to do an implementation of the interface. An example of interface implementation is the serial driver, SerialDriver is both an extension of the interface BaseAsynchronousChannel and an implementation. You may look into serial.c and do exactly the same but on the interface BaseFileStream.
Anyway, this will also give a chance to debug that interface, it has never been implemented and I just saw a couple of other errors (fixing now). Let me know if you find any problem.
Is there must be "BaseFilelStreamVMT" instead of "FileStreamVMT"
2) I can not imagine what to do with "_base_file_stream_data" 3) Functions in interface returns values, but it is not always obvious what that values means? For example:
1) Fixed on repository. 2) Nothing, the interface defines no data. Those macros are used to "inherit" the data fields defined into the super interfaces. 3) The documentation is on macro that "wraps" the method, in that case chSequentialStreamRead(), anyway good point, for the BaseFileStream the documentation is not that complete, I will work on it.
1) I propose to add "position" field to "_base_sequential_stream_data" and "errors" in "_base_file_stream_data" 2) looks like macro wrappers in chfiles.h are incomplete:
1) Disagree, sequential streams don't have a position, the concept of position is added by extending them to "files" that also have a "seek" feature. Adding fields to interfaces is generally a bad idea, you don't know if the implementer class need or can handle an "error" field. In general better use get/set methods, this allow to associate actions to the act of accessing a feature.
1) Understood. But where is correct to store position and errors values? Using static variables for that purpose looks ugly. Wrap BaseFileStream in my own File object (with that fields)? 2) There is no Open() function. I must create my own function that initialize instance of file stream, right?
1) Just like the serial driver, all its fields are fields added to the base interface, you create your EEPROMFileStream class implementing BaseFileStream and add all the fields you need.
2) The idea is that there is a FileSystem object with an "Open" method that returns a "File" object. The file system is a "factory" of "file" objects. In your case there is not factory, you would have a static object instance with an "ObjectInit()" function like HAL drivers for initialization.
Giovanni wrote:2) The idea is that there is a FileSystem object with an "Open" method that returns a "File" object. The file system is a "factory" of "file" objects. In your case there is not factory, you would have a static object instance with an "ObjectInit()" function like HAL drivers for initialization.
This bit interests me for my own C++ filesystem class. What is the best way of memory managing these file objects? my initial thoughts were either to statically allocate memory for N file objects and use a memory pool (good solution if you know in advance max number of open files. Timeouts could be used). or have each client statically allocate a file object and pass by reference.
I'll follow the development of this idea, if I implement ST's 'Internal Flash to EEPROM' wrapper, I can interface it with this code
The best approach is a pool IMO. The memory pools can feed from a "memory provider", so there is no need to know the number of objects in advance, let the pool get them using chCoreAllocI() as provider. There is risk of memory exhaustion but it still avoids memory fragmentation because the pool reuses the objects.
Edit: Of course the static approach has its advantages too.