-
Notifications
You must be signed in to change notification settings - Fork 465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use external Flash chip for storage #1547
Comments
Lack of a persistent filesystem has always been a limitation of Epsilon. Fixing this limitation has always been a good idea... and in the wake of TI removing access to native code on the TI-eZ80 series by an OS upgrade on 2020/05/20, with users fuming over the move, a persistent filesystem for Epsilon has become an even better idea of even higher desirability for users of NumWorks calculators :) The low free Flash space of the N0100 is indeed an issue, we can't expect users to solder an additional Flash chip on N0100 calculators, though it's not too hard to do it. The memory layout of the N0100 OS could be shuffled to be able to use that 64 KB sector for filesystem storage purposes... but then the Flash memory would become unable to store improved OS versions even sooner, which is bad for users. For over two decades, users of TI-Z80, TI-68k and TI-eZ80 calculators have put up with variables whose maximum size is 64 KB minus several control bytes. On the TI-68k series: in Flash memory, AMS 2.xx and 3.xx use variable headers of 2 bytes for a bit field containing the status of the logical block in Flash memory (active, to be garbage collected later, etc.) + 8 bytes for the folder name + 8 bytes for the variable name. For multiple reasons, USB DFU isn't the best protocol for dealing with Flash-based filesystems. |
At this point, the N0100 only has 150 KiB of Flash unused and its structure is really heterogeneous (4x16 KiB, 1x64 KiB and 7x128 KiB sectors). I'm not going to bother migrating its storage to Flash because quite frankly it's not worth the headache. I do not think NumWorks will support another USB mechanism to exchange data because DFU is doing the job just fine for their needs. There are no compelling reasons for them to change it. While the community could add Media Transfer Protocol to epsilon, that's a lot of work and I doubt it will happen anytime soon. Right now I'm assessing the state of storage in epsilon and there are several things to clean up before attempting this. Among other things, Python script edition is done directly inside the storage buffer and that will obviously not work with Flash. |
Hi @boricj ! Thanks for starting this discussion! First of all, this is something we've been wanting to do for a while. It's a great feature and it would be a nice addition to Epsilon. That being said, it's a feature targeted at power users that very few people have actually asked us to add — you might be the first, actually. As a result, we've kept pushing it further down our roadmap, and to be very honest it's still not one of our top priorities at the moment. That being said, we'd love to add this at some point, and there are definitely a few decisions to be made. Off the top of my head:
Last but not least, as you've noticed, we're indeed very often using the fact that "files" (well, records) are in RAM, and we edit them in place. Changing this behavior would probably require a non-trivial amount of work. Nothing impossible of course, but that assumption is made virtually everywhere records are used. |
@Ecco I'm concerned about using an off-the-shelf file system that does not fill the requirements I've laid out:
It's too early to decide just yet, but unless someone can find an existing file system with the requirements I've identified, I believe that writing an ad-hoc record system to be the least risky option. I'm not going to redesign the entire record subsystem of epsilon from scratch and deal with the snowballing consequences just to reuse a file system off the shelf.
I disagree with reducing the use cases to only power users. It's like saying 32K is more memory than anyone will ever need on a calculator. I've listed a bunch of stuff that will be possible when storage is measured in megabytes and not two dozen of kilobytes:
I specifically recall analyzing a video of a thrown ball during a high-school assignment. I used software on a computer to get the coordinates of the ball across time, then performed regression in Excel to find a linear model on the x axis and a quadratic model on the y axis. All of that could conceivably be done on a NumWorks calculator without the need to book a computer room, if it had the storage for a dozen of video frames or even just a single chronophotograph (I assume the data is on the calculator, but it's nothing a smartphone, tablet or portable computer can't handle). It's not about having a bigger storage just to store more Python scripts. It's about having a bigger storage to enable new possibilities for users that they wouldn't even think of otherwise, because the current limitations of the calculator inhibit that kind of thinking outside the box. In any case, I believe that the |
+1 for USB MTP for its ability to decouple the underlying storage mechanism from the communicated filenames. I heard about a working implementation of MTP for the TI-eZ80 series, which has its own flat filesystem (no folders) based on contiguous files stored in sections of either RAM or Flash memory (the section of Flash memory which can store user variables is officially known as "archive memory"). |
So I've given it some more thoughts: Storage-wise, we should use something like a log-structured sequence of records: struct RecordHeader {
char name[60];
uint32_t dataSize;
char data[dataSize]; // Padded to 4 byte alignment.
}; Given Flash constraints, deleting a record would be done by writing a null character at Since scanning this structure linearly could take a long time when near capacity, a statically-sized and sorted array of record headers pointers (effectively their names) would be required for fast access and iteration. This proposal is mainly because such a structure is easily manipulated with C standard library An interesting new use-case I've found would be to store the snapshots of inactive apps in Flash. This should substantially decrease RAM usage since it would allow for extending the current system of run-time overlays for apps to their snapshots as well. To prevent out-of-memory allocation problems, part of the "maximum" capacity margin would be used for app snapshots. It does not need to be implemented in the short-term, but it'll be done at some point when RAM shortage or expansion of the MicroPython heap will become an issue. If anything, this highlights the fact that the N0100 should not be a concern for the design (and that non-compatible work, if any, should probably be postponed until the N0100 is filled to the brim and cannot support new major releases anymore). While I've made some minor cleanups so far, retro-fitting the existing epsilon record code with read-only direct buffer access is proving to be a lot more harder than I've expected since I did not know how pervasive read-write direct buffer access was across the code-base. I expect that a community-led effort would yield a rather big diff in this area and often bitrot against internal NumWorks developments... |
Problem you'd like to fix
Currently, epsilon uses a 32 KiB buffer in RAM as a storage area for Python scripts and Poincare objects (variables, sequences, functions...) with an simple ad-hoc file-system. Its structure is a sequence of (size, filename.extension, data) records with two magic
uint32_t
values delimiting the beginning and the end of the buffer. Of particular note, the workshop will directly read and write this buffer for transferring Python scripts and as such needs to understand the file-system format to work.This file-system as it currently exists has several shortcomings:
uint16_t
).memmove()
things around without issues.Describe the solution you'd like
The N0110 model incorporates an external 8 MiB Flash chip that is currently used for storing the firmware and the exam mode status. It is not used to its fullest potential as nearly 7 MiB of it is unused. Since it is unlikely that the firmware will expand to consume all that space anytime soon, it is proposed to move storage into it.
A new file system is required to make use of it, of which these are the requirements:
Having a new file system with a capacity of several megabytes instead of 32 KiB allows storing things that are currently impossible, such as images, screenshots, rich text documents, large datasets and so on. This in turn allows new usages for end-users (background images for graphs, document viewer, blitting sprites and tilesets in Python...) and also for third-party forks.
Describe alternatives you've considered
The N0100 model has only 1 MiB of Flash available with less than 120 KiB free at the moment. Furthermore, most sectors are 128 KiB long, with only four 16 KiB (the first one containing the reset vector and thus has to be erased with caution, the second one containing the exam mode status) and one 64 KiB sectors. It is doubtful storage can be successfully migrated to Flash in this model, so a decision is required for it (keep old file system, use new file system in existing RAM buffer, wait until N0100 support is discontinued due to stuffed Flash...).
Additional context
This is an improvement request originating from third-party forks. The external apps community support currently uses a tar file located at 0x90200000 to store data files and programs. This is an ad-hoc solution unsatisfactory on multiple levels and it'd be really nice if this could be integrated to share the native epsilon file system altogether. However, this cannot be done without cooperation with upstream as the workshop needs to understand the file system format to transfer scripts. Therefore, it is preferable that a solution satisfying all involved parties be reached.
Tasks identified
Ion::Storage
API and usageskandinsky
module for blitting/saving picturesfile
object for I/Oos
Python module for directory manipulationkandinsky
functionsThe text was updated successfully, but these errors were encountered: