I have some very simple file I/O code using the Bfile_ functions that's failing in a weird way, and I'm stumped as to what is going on. Opening and reading files works as expected, the issue is with writing. Whenever I call the save function, it's basically a 50/50 chance whether it writes or freezes the entire system and I have to take the battery out to reset it.
Here's the entire code:
Code:
void hscore_load(highscore_t *hscores) {
int file = hscore_open();
if (file < 0)
return;
Bfile_ReadFile_OS(file, hscores, sizeof(highscore_t) * HSCORE_COUNT, 0);
Bfile_CloseFile_OS(file);
}
void hscore_save(highscore_t *hscores) {
int file = hscore_open();
if (file < 0)
return;
Bfile_SeekFile_OS(file, 0);
Bfile_WriteFile_OS(file, hscores, sizeof(highscore_t) * HSCORE_COUNT);
Bfile_CloseFile_OS(file);
}
highscore_t is a simple 8 byte struct containing a short char array and an unsigned integer, both functions take an array of known size of these structs. The hscore_open() function just opens the file with a hardcoded path using Bfile_StrToName_ncpy, creating it if it doesn't exist and returning -1 if that fails for some reason. Whatever the issue is it's not there, since the read works just fine.
File size is the exact size of the struct array (40 bytes), but increasing it doesn't change anything either.
I can't see what about the write would cause this issue, it's about as simple as it gets. Any ideas? Am I doing something obviously wrong that I've missed?
Update: tried a couple things based on whatever I could find in old forum posts, but nothing seems to work: adding padding to write a larger number of bytes, deleting and creating the file again on each write.
Some more interesting things: sometimes it'll continue as if the write was successful, but doesn't actually modify the file. Deleting the file also causes the system to hang with no chance of recovery.
I'm properly stumped on this one, i'll keep posting if I find anything ig.
Hello!
This does indeed seem odd! According to SimLo's documentation,
"SysCall 0x1DAF: int Bfile_WriteFile_OS( int HANDLE, const void *buf, int size );
Writes to an open file in storage memory.
There has been observed some anomaly (http://casiopeia.net/forum/viewtopic.php?f=22&t=1577&p=13543#p13537 [dead link]). Writing with a source-buffer, which is located in the flash-memory rebooted the calculator. That reminds of the bank-read-write-collision of the fx-9860-flashs."
Is there a chance your hscores are in the flash memory?
Hi! Yeah, I've read about some of the oddities around the Bfile_ calls wrt writing from flash as well as running user timers (iirc both have to do with the OS potentially running the optimization which can change the address of the add-in on flash, right?). Neither should be an issue though, the function is only ever taking a static array declared in main so that's certainly in RAM (and I'm not installing any user timers).
I wrote a minimal add-in that just opens, writes and closes a file in a loop trying to repro, but couldn't get it to hang in the same way even writing hundreds of times. However if I do something similar in my game (just a very simple Tetris game, I got my fx-cg50 last week and figured it'd make for a nice weekend project to get started!) and bind a key to just save the highscores in the main menu, it hangs after pressing the key a couple times, also randomly. That hints toward there being something in my code that's breaking things rather than an issue with the syscall itself, but honestly there's so little going on I'm not sure what could cause issues.
Is there any way to debug the calculator, btw? That would probably help here, the fact it's a system wide hang and not an error makes me think the CPU is getting stuck in a loop somehow, either in the syscall routine itself or by jumping to an invalid address (though the latter seems unlikely, that would probably cause a system error most of the time). Looking at a disassembly of the syscall might give some hint as to what could go wrong too, but I wasn't able to find one.
Update: I kinda gave up and refactored the project to use the fxSDK/gint kernel, which I was planning on using for future projects anyway since it has nicer APIs and better performance than the native syscalls. The filesystem calls in gint work perfectly, so that solves my problem.
I'm still curious as to what is going on, but I strongly suspect skill issue on my part. Guess I'll revive this thread if I ever run into this issue again using the Prizm SDK and find anything about the cause.
bluescreen wrote:
Hi! Yeah, I've read about some of the oddities around the Bfile_ calls wrt writing from flash as well as running user timers (iirc both have to do with the OS potentially running the optimization which can change the address of the add-in on flash, right?). Neither should be an issue though, the function is only ever taking a static array declared in main so that's certainly in RAM (and I'm not installing any user timers).
I wrote a minimal add-in that just opens, writes and closes a file in a loop trying to repro, but couldn't get it to hang in the same way even writing hundreds of times. However if I do something similar in my game (just a very simple Tetris game, I got my fx-cg50 last week and figured it'd make for a nice weekend project to get started!) and bind a key to just save the highscores in the main menu, it hangs after pressing the key a couple times, also randomly. That hints toward there being something in my code that's breaking things rather than an issue with the syscall itself, but honestly there's so little going on I'm not sure what could cause issues.
Is there any way to debug the calculator, btw? That would probably help here, the fact it's a system wide hang and not an error makes me think the CPU is getting stuck in a loop somehow, either in the syscall routine itself or by jumping to an invalid address (though the latter seems unlikely, that would probably cause a system error most of the time). Looking at a disassembly of the syscall might give some hint as to what could go wrong too, but I wasn't able to find one.
If you would like someone else to look over your code, you're welcome to upload it to a git-something or pastebin and I can take a look!
It does seem very odd, but again there's not much I can say without seeing the whole program.
There are a few ways of debugging - personally I run everything in CASIO's fx-CG emulator in WINE, to my calculator isn't going to brick itself, before I test on real hardware. Apart from that, you could disassemble the addin to see what's going on, but there's little good debugging software for the PrizmSDK as CASIO don't make any. A few people started developing some projects in this space, but afaik none of them ever made anything really production-worthy.
You mentioned in your latest post that you're using gint - they have would you could class as a debugger: https://git.planet-casio.com/Lephenixnoir/gintctl
I'm not quite sure how to use it myself (so can't help much), but I don't really use gint, and Lephe's code is always great.
Also, if you'd like to disassemble the syscall (or your own addin), I'd recommend Lephe's fxos: https://git.planet-casio.com/Lephenixnoir/fxos
It's a great disassembler for the calculator.
Let me know if you have any other questions!
dr-carlos wrote:
If you would like someone else to look over your code, you're welcome to upload it to a git-something or pastebin and I can take a look!
I do have a github repo for it, but I never pushed the code with the Bfile_ calls since it was broken. I don't want to waste your time looking at my code since the problem is (sort of) fixed, but if you really want to you can imagine the functions I posted in place of the ones in the repo, rest of the code is pretty much the same.
dr-carlos wrote:
There are a few ways of debugging - personally I run everything in CASIO's fx-CG emulator in WINE, to my calculator isn't going to brick itself, before I test on real hardware. Apart from that, you could disassemble the addin to see what's going on, but there's little good debugging software for the PrizmSDK as CASIO don't make any. A few people started developing some projects in this space, but afaik none of them ever made anything really production-worthy.
I did get the emulator for mac, couldn't figure out how to load custom add-ins though. That would be nice to get running, if only because it allows for faster iteration than copying the add-in to my calculator every time.
dr-carlos wrote:
I'll look into those, thanks!
bluescreen wrote:
I did get the emulator for mac, couldn't figure out how to load custom add-ins though. That would be nice to get running, if only because it allows for faster iteration than copying the add-in to my calculator every time.
Presuming it is the same as the Windows emulator, open the Memory app, then press PC (F3) and Import files (F1). This should open a dialog where you can select your G3A to upload.
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.
»
Go to Registration page
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum