Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » gint programming questions
Druzyek Hors ligne Membre Points: 34 Défis: 0 Message

gint programming questions

Posté le 03/12/2024 22:32

Hello! I'm planning on making a new program with fxSDK and gint, and I have a few questions. I have an fx-9750GIII and I hope to get an fx-CG50 soon, so I'm curious about a few things for both calculators:

- How can I allocate as much RAM as possible for the program to use? I read a few years ago that malloc is a little buggy, but can I get a big chunk of heap that way? I imagine if the heap is mostly empty but has a small allocation in the middle that will limit the largest piece I can allocate. Also, I read about the extra RAM in the SPU and understand the 24-bit accesses in case I need to do that.

- Does anything persist in RAM when an add-in exits?

- If the add-in allocates memory with malloc but doesn't free it, does the OS recover it or is it just lost?

- Does the add-in execute directly from flash or do I lose RAM as the program gets bigger?

- How can I read and write files in flash like Python scripts?

Thanks in advance!


Lephenixnoir Hors ligne Administrateur Points: 24700 Défis: 170 Message

Citer : Posté le 03/12/2024 22:41 | #


Welcome back! I recognize your avatar but haven't seen it in a while. :o

- How can I allocate as much RAM as possible for the program to use?

About 90-100 kB is available on the G-III, up to 600-700 kB for the CG-50. On the CG-50 there are also large swaths of unused RAM of which we commonly grab 2-3 MB but that technically total 6 MB.

The OS malloc is known to be a bit unreliable with fragmentation on the fx-CG, but most of the default heap memory is managed by gint anyway. On the G-III I don't have clean reports of fragmentation issues, however almost all the heap you can get is from the OS, so you don't have as much control over it and no statistics.

Also, I read about the extra RAM in the SPU and understand the 24-bit accesses in case I need to do that.

This is a great resource on the G-III, the largest one you have access to, although hard to use efficiently at the same time. You can read this documentation page about SPU memory.

The easiest piece of SPU memory to use is called PRAM0 and it's quite normal except that you can only use 32-bit accesses. So you can't use it to store, e.g., strings for strlen() and co., which frequently use 8-bit accesses. In practice, this means you are limited to using this memory with code that you write yourself.

The rest is XRAM0, YRAM0 and YRAM1, and they work the same except that when you write 32 bits of data only 24 bits are retained.

volatile uint32_t *YRAM0 = (void *)0xfe280000;
*YRAM0 = 0x11223344;
*YRAM0; // 0x11223300

I have yet to see these used in an add-in. It's feasible, but a pain.

- Does anything persist in RAM when an add-in exits?

As per the runtime contract, nothing. The OS doesn't spend time needlessly clearing out memory so you're likely to find scraps of previous executions' data. But that's not a behavior you should rely upon. You can store data safely using the filesystem, or if you want more speed, the main memory (but gint has no wrappers for MCS syscalls, you'll need to world switch and call them manually).

- If the add-in allocates memory with malloc but doesn't free it, does the OS recover it or is it just lost?

It remains unavailable until the add-in exits, then it is recovered by the OS. "Recovery" is however a misleading term here. The heap just ceases to exist when the add-in quits, and then it is recreated anew on top of whatever there is in memory when another add-in starts.

- Does the add-in execute directly from flash or do I lose RAM as the program gets bigger?

The add-in is mapped by the MMU directly from Flash at no cost in RAM usage. The add-in file is limited to 512 kB (G-III) / 2 MB (CG-50) after which it does not show up in the main menu anymore, and if you need more room you need to start using external files and loading them to RAM yourself, at which point there is a cost in RAM usage.

- How can I read and write files in flash like Python scripts?

You can use the standard POSIX file API (open() and co) or the standard libc API (fopen() and co) on both the G-III and CG-50. Do remember however to world switch during file operations, otherwise the add-in can crash.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Fcalva Hors ligne Membre Points: 604 Défis: 10 Message

Citer : Posté le 03/12/2024 22:43 | #


Hey, welcome here
- You can't have more than the standard heap on G-III (and the SPU only is for the G-III/ fx-CGs), though you can have an extra ~2MB on the CG50 (and on it the heap is already 512KiB)
- It's complicated, but it's not the case anywhere you should use (Basically it only persists if you corrupt important stuff )
- The OS recovers all memory from leaks because it's not the OS that handles it (and with the old SDK i think it just resets malloc()s anyways)
- The addin is loaded into RAM but in a reserved area so you can't lose/gain heap/stack (See Lephe's message)
- For Python file I/O, you would have to look at Slyvtt's experimental branch of PythonExtra (community python). It works though, just don't forget to .close() your files because the garbage collection seems a bit flaky
In general, i would recommend not searching too hard for more RAM, but rather just optimizing your program
Edit : i misunderstood the last question, you have standard C I/O with gint/fxlibc (see stdio.h)
Pc master race - Apréciateur de Noctua moyen
Caltos : G35+EII, G90+E (briquée )
Calamari Hors ligne Membre Points: 404 Défis: 0 Message

Citer : Posté le 03/12/2024 22:54 | #


How can I allocate as much RAM as possible for the program to use?

I've been using malloc and it seems good. There might be a better method, but what I do to get the largest contiguous block of RAM is start from 64KB on FX (can test GINT_HW_FX) otherwise 512KB (CG). Then I try to malloc in a loop, decrementing by 1KB each time malloc fails. Then once it succeeds, I free it, add 1024 and then loop from there, this time decrementing with the alignment I actually wanted (4 bytes, 8 bytes, etc). This seems to be quite fast. Example: https://git.planet-casio.com/calamari/Duvet/src/branch/main/src/sheet.c#L168

Of course if you're allocating a linked list or such then you can just malloc each element individually. Although, I ended up not doing that in Duvet in order to minimize overhead, hence the single large allocation.

Does anything persist in RAM when an add-in exits?

I'd recommend to avoid exiting at all, unless you really need to exit due to a fatal error or such. If you exit, then they have to run something else before they can run your add-in again. Instead, allow them to go back to the main menu, for example by pressing MENU. Check out getkey_opt and gint_osmenu. When they're at the main menu, if they choose run something else, your memory is "freed" automatically. Otherwise, they can come back to your add-in and your memory is intact. There are some display details you'll have to deal with when they come back, but it's manageable. Here's how I did it in a recent add-in: https://git.planet-casio.com/calamari/Duvet/src/branch/main/src/kbd.c#L85
“Remember to have fun doing this, or it ain't worth it.” — Robert Alan Koeneke
“They call me the king of the spreadsheets, got 'em all printed out on my bedsheets.” — “Weird Al” Yankovic
Druzyek Hors ligne Membre Points: 34 Défis: 0 Message

Citer : Posté le 05/12/2024 22:06 | #


Lephenixnoir a écrit :
Welcome back! I recognize your avatar but haven't seen it in a while. :o
That's right! You were a great help figuring out how to install fxSDK a few years ago. I've gotten a lot better at Linux since then! Thanks for your information this time too.

The OS malloc is known to be a bit unreliable with fragmentation on the fx-CG, but most of the default heap memory is managed by gint anyway. On the G-III I don't have clean reports of fragmentation issues, however almost all the heap you can get is from the OS, so you don't have as much control over it and no statistics.
So if I understand correctly, the OS will use a variable amount of RAM for itself but doesn't seem to have fragmentation issues, so I can use Calamari's strategy or similar if I want the biggest chunk of RAM possible? Does gint make any calls to malloc that I need to account for before I gobble up all the RAM?

You mentioned that you haven't seen any add-ins use the 24-bit SPU memory. What about the OS? I was wondering if I could leave data there after my add-in ends and expect it to stay there unchanged until it starts again (assuming a second add-in doesn't overwrite it).

Can you explain or link me to a little more about world switching?
Lephenixnoir Hors ligne Administrateur Points: 24700 Défis: 170 Message

Citer : Posté le 05/12/2024 22:22 | #


The OS uses a fixed amount of RAM and what you can get from the OS malloc() is also a fixed amount. That much is not a variable. Fragmentation is this issue where if you fill the heap then over the next cycles of freeing and allocating you end up with swiss cheese with no large blocks and you might be unable to get large allocations. This is a concern you might have on the G-III where gint's heap (which is the default) is small and you quickly end up using the OS heap. By contrast, this is less of a problem on the CG-50 because gint's heap and other extra memory is much larger than the OS heap.

(...) so I can use Calamari's strategy or similar if I want the biggest chunk of RAM possible? Does gint make any calls to malloc that I need to account for before I gobble up all the RAM?

If you want small bits of RAM, use malloc(). It will handle things for you. If you need a large chunk or RAM early on and hold on to it to make sure you keep access to large blocks, then :

- On the G-III, do a single malloc() of the largest size you can, which I'm expecting will be ~90 kB. No point in allocating multiple times as the buffers won't be contiguous. If that's not enough, address directly in PRAM0, but you'll need to stick to 32-bit accesses.
- On the CG, use gint's kmalloc_max() function to get the largest block available in the _uram arena if ~400 kB is enough for you. Otherwise, address directly at 0x8c200000 where you have a few MB.

You mentioned that you haven't seen any add-ins use the 24-bit SPU memory. What about the OS? I was wondering if I could leave data there after my add-in ends and expect it to stay there unchanged until it starts again (assuming a second add-in doesn't overwrite it).

I don't think the OS uses it, but other add-ins might. And it disappears the moment you press OFF. I advise against relying on long-term storage in RAM in general.

Can you explain or link me to a little more about world switching?

Basically gint is its own mini-OS and you can't use arbitrary official-OS functions while using gint. Usually this comes up when using the filesystem or when using specific syscalls for which gint has no equivalent. To use such functions, you need to leave gint temporarily, run them, then come back into gint, a maneuver known as a world switch. The world switch mechanism, which is hidden from users, ensures that gint and the official OS won't try to use the same piece of hardware at the same time.

In practice, you just have to isolate your file-manipulation code in dedicated functions and call these functions through gint_world_switch() instead of directly.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Druzyek Hors ligne Membre Points: 34 Défis: 0 Message

Citer : Posté le 06/12/2024 01:53 | #


Ok, great. That's just about everything I was wondering about. On the G-III, do I need a world switch to malloc the ~90K from the OS heap instead of gint's heap? Where is gint's heap? Thanks!
Lephenixnoir Hors ligne Administrateur Points: 24700 Défis: 170 Message

Citer : Posté le 06/12/2024 08:27 | #


You don't need to world switch to use malloc(). By default, malloc() will take memory from gint's heap and go to the OS heap when that is full. You can control which heap ("arena") to allocate from by using gint's slightly-lower-level kmalloc() function directly.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 65 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd