FlexBASIC P2 uSD explore
I finally got my uSD to work on my P2 edge setup. Below is just a simple program to see if I am writing/reading anything to the uSD card.
I am using a 16GB uSD card, it seems to be reading and writing to the card without any problems, so far. With FlexBASIC, how large of a uSD card can it work with?
The next question, anybody have any FlexBASIC code to do things like DIR the card, delete files from the card, and so on.
Since, I think, it would not be practical to have some kind of mini editor, in FlexBASIC, is their a way to move files between _vfs_open_host() and _vfs_open_sdcardx(). I guess that way you could create a file on your host system, and then move the file to the uSD card, to be used with your program. This would be done without removing the uSD card.
' test1sd.bas OPTION EXPLICIT ' no implicitly dec'd vars CONST HEAPSIZE = 8192 ' lots of elbow room dim a$ as string dim i as ubyte dim msg$ as string msg$ = "Just some text." mount "/host", _vfs_open_host() mount ("/sd", _vfs_open_sdcardx(5,4,3,2)) ' mount the file system at /SD node ' write some stuff open "/sd/test.txt" for output as #2 'print #2, " " 'print #2, "This is another test line.";chr$(13) print #2, msg$;chr$(13) close #2 ' close the file 'read it all back print "Reading stuff from file..." open "/sd/test.txt" for input as #2 ' open for input do a$ = input$(1024, 2) ' get 1024 chars (or less if eof) print a$; ' print them loop until len(a$) = 0 ' keep going until eof close #2 ' close file for safety before exit print "Test done."
Now I asked the same question in another topic The Basic help file doesn't list any function, while there are functions we need in C. There can be 2 solutions:
Any size will work, but be aware that cards larger than 32GB will come preformatted as exFAT, you'll have to reformat to FAT32. Obnoxiously Windows' format dialog won't let you, you need a special tool.
A linux PC or a Raspberry Pi can do this job, there is also a GUI available (gparted) - I have 128 GB SD with fat32 on it. The main problem is how to access the basic directory access/manipulation functions from... Basic
Command shell for P2in the
SpecialMenu of FlexProp can do this.
You can also look at the C source code for it in samples/shell, maybe the used C functions work also in flexBasic.
I checked out using : "The Command shell for P2 in the Special Menu of FlexProp can do this.". If I were using the P2 eval board, then it probably would work. BUT, I am using the P2 Edge rev-b board with a uSD Add-on board.
The shell program uses the uSD pin locations that are on the P2 eval board. Using the P2 uSD Add-on board, you will have a numerous choice of pin locations. Their are problems when you use the shell.c program in the FlexBASIC program.
In my test program I used - dim shell as class using "shell.c", this compiled without any errors , but it did not work as expected. I think this has to be run as a stand alone in FlexBASIC, not sure how to do this. The other option is to rewrite shell. c so it would work as expected, in a FlexBASIC program.
Probably the best choice would be, use the shell in the special menu, but that means that shell program would have to have a rewrite to support the sdcardx() option.
shell.c isn't designed to be used as a class, it's a stand-alone program. To modify it to run on your P2 Edge, you'll just have to change the _vfs_open_sdcard() call (near line 206 of the main() function) to the appropriate _vfs_open_sdcardx()).
In general to copy a file from host to SD card, or vice-versa, you would mount both host and SD, then open the source file, create the destination file, and copy data from source to destination until end of file. Or, you run the shell program and type something like "copy /host/src.txt /sd/dest.txt"
Directory listings aren't supported from FlexBasic yet. I'll probably try to add the DIR function from FreeBasic to a future release, but for now you'll have to import a C module that uses opendir/readdir.
I just tried out ersmith suggestions, and the shell program worked as expected. I tried the 'exec' command, not sure what kind of file it is supposed to run.
In my flexprop GUI program I load in shell.c, and the test.bas program. From there I can compile and run the shell.c program, when I need access to the shell stuff.
Just curious, does anybody know what pins the uSD uses on the P2 Edge rev c board, hopefully it would be the same pins that are used on the P2 eval board.
Just normal P2 BIX binaries.
Yes, it's the same pins (as dictated by the bootloader)
Here's a simple test.bas program for showing a listing file (on the host, in this case). It uses a C class in "dir.c". The "DIR" function in that class acts very much like the FreeBasic DIR function, and I'll probably add it to the FlexBASIC language in a future release.
To make this complete, cd is needed, and then we can explore the file system using Basic. If I remember, a shell example has cd implemented, so it should be not a problem to impotr this too.
The chdir function is already implemented and is in fact used in the test.bas that I posted.
Now I can see it After a third look at the code... coffee needed...
I can't find chdir in Flexprop's Basic help. How many other gems are hidden in there?
Lots. If it is a standard C call, odds are really good you can get to it from FlexBASIC as long as it doesnt return a FILE pointer.
It seems this basic needs a new manual.
It doesn't understand "chdir" unless you use something else. For example "print". Then it magically understands chdir.
It also understands "fopen". This returns a FILE pointer, so... I have a lot to experiment with.
Edit: it returns 0 if the directory exists,, but the example dir function doesn't list anything from it. If the directory doesn't exist, it returns -1 and then the dir function lists the main directory on SD card.
So chdir works, but then something is wrong or I don't know how to use it
Edit 2: I added a "shell.c" as a class to the Basic program. When I called its 'main()' from Basic, it worked. It can cd, dir, etc (even doing printf using my video driver after Basic captured channel #0)
I can call getcwd directly from Basic and it works, showing the correct current directory after several chdir called from Basic.
However getcwd called from inside shell.c, called from Basic, (from do_dir) calls the current directory is "/" (while called from Basic directly tells "/sd/mod" which is correct.
Edit 3: I wrote a custom cwd2 function in C, which calls cwd and returns it result. It returned "/"(wrong), while cwd called from Basic returned /sd/mod(right). Why?
Yes, since this is my thread, please move to Basic category.
chdir can reach the directories, but dir$() only works on the root directory. This is a bug in dir$(); actually in the underlying file system code (dir$() worked fine on the P9 file system code, but the FAT file system code is a bit more rigid in what it will accept). To fix it, replace the file
flexprop\include\libc\unix\mount.cwith the one attached to this post.
I'd have to see the exact code, but it's possible that the class has gotten its own internal working directory that is different from the main BASIC one.
(Edit: I have to check something... )
OK, let's write again.
To test what is wrong with dir, I tried your shell.c example, which works without any problem, changing and listing directories on SD card.
Then I added the shell.c as a class to Basic and called its main()
It worked without any problems. Adding a video driver and attacung it to the channel #0 makes the shell output text on my screen instead of the serial port while stil working fine.
So I tried to call do_dir from Basic, which failed.
Basic -> main -> do_dir works, while Basic->do_dir does not
I found something is wrong with cwd, so I added this function to shell.c to check it:
Then from Basic I did this:
I replaced mount.c on my PC/Flexprop 5.9.6, cwd problem remained. To test, I have to prepare a new SD card with several dirs in it (I left it at the university) and build a 5.9.7 on my RPi as there is no 5.9.7 on PC, then test if 5.9.7+new mount.c works.
Edit: a lot of strange things happened while installing and using the flexprop 5.9.7 on the RPi 400 with a new 64-bit OS. A warning: if someone wants to connect the P2 Eval to RPi4/400, don't connect it to the USB3 port or strange things can happen (Flexprop cannot see a serial port, the RPi hangs up and cannot boot again from external SSD until P2 Eval is disconnected. A conflict somewhere on USB between SSD and FTDI, or something like this, not flexprop related. RPi 400 cannot boot with both SSD and P2 Eval are connected to USB3 port. Use USB2 port instead.
I still have problems compiling and uploading to P2 using 5.9.7/RPi400/64bit OS. It is too late now to check what may be wrong and I am now way too tired.
@pik33 : I haven't had a chance to dig into this yet, but I suspect that the cdir class and the BASIC main program have different current directories. The "shell.c" example was never really designed to be a re-usable class, so it's probably better not to rely on any of its behavior.
Here's the test program I used to get a listing from an SD card (using the modified mount.c I posted above):
It works, but not 100% correct. Some strange things happen.
If the directory is long, the program fails after several (something over 100) listed files.
So I tried to check if the number of listed files is not 128 and modified the code:
What I added is (1) var i, (2) waitms to see what is printed (3) print i.
If there is only
I was correct. The number of listed files is indeed 128.
What is strange, if I
print i, fname
the number of listed files is less (and = 114)
Edit: it is HEAPSIZE that limits the number of listed files. It seems every loop allocates the memory on the heap but does not return it so the heap becomes full. HEAPSIZE=8192 increased the count to ~256
string = _gc_alloc(strlen(ent->d_name)+1);
in basic_dir.c allocates the memory for the directory entry. Nothing frees it.
That's why the heap gets full.
I patched this, adding a static variable for this:
static char string;
and then commented out the allocation
After this ugly patch there is no more limits for the number of listed files (I have 1054 of them in this directory). The problem is now worked around.
@pik33 : Ah, that line should have called
_gc_alloc; then the string could have been garbage collected. Thanks for the bug report, I'll fix that.
A glitches discovered while trying to explore SD card:
Edit: I patched basic_dir.c, now fbNormal lists only files. The differences are: dir and system properties are checked at the end instead of beginning and then there is = instead of |= which ecludes directories from search results if fbDirectory is not specified.