fsrw demo to read and display file contents
Rsadeika
Posts: 3,837
Below is my attempt to add some lines to a created file, then open the file to be read, and the contents displayed to the VGA screen. The part that is not working is the displaying of contents to the screen. What am I missing here?
Thanks
Ray
Thanks
Ray
''Open_sd_030.spin CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 '' Using the DEMO board with an SD card reader '' attched to P0 ... P4 DO = 0 CLK = 1 DI = 2 CS = 3 VAR BYTE dirbuff[12] BYTE filebuff[256] BYTE filesize OBJ sdfat : "fsrw" vga : "MikronautsVGA64" PUB demo | mount vga.start(16) '' Start the VGA driver vga.cls '' Clear the screen '' Mount the SD card mount:= \sdfat.mount_explicit(DO, CLK, DI, CS) if mount < 0 vga.str(string("Failed to MOUNT",$0D)) abort vga.str(string("SD card was found and MOUNTED.")) vga.out($0D) '' Add some txt to an exiting file sdfat.popen(string("test3.txt"),"a") sdfat.pputs(string("This is the xxxx line.",$0D)) sdfat.pputs(string("This is the yyyy line.",$0D)) sdfat.pclose vga.str(string("File has been wrtten to.",$0D)) '' Show files on the SD card sdfat.opendir sdfat.nextfile(@dirbuff) vga.str(@dirbuff) vga.out($0D) sdfat.nextfile(@dirbuff) vga.str(@dirbuff) '' Open the file for read and display contents sdfat.popen(string("text3.txt"),"r") filesize:=sdfat.get_filesize sdfat.pread(@filebuff,filesize) vga.str(@filebuff)) '' Unmount the SD card sdfat.unmount vga.out($0D) vga.str(string("SD card has been unmounted",$0D))
Comments
You open it for appending. So, if you already run the program several times it's bigger than 256 bytes and thus reading the whole file will destroy your RAM (propably including the program).
This is called a buffer overflow and is used to hack systems here and there. So, the best way to read any stream is by using a limit and rather read it in portions.
In your case you can use a loop to read/print the file counting down the variable filesize. If I remember right pread returns how many bytes actually have been read.
Also think about increasing the length of filebuffer by one byte and always store a 0 (zero-byte) after the last read character. Otherwise vga.str might print more than you want.
Ray
The attached demo will probably be helpful, and contains a bunch of string methods that may be handy, too.
thanks,
Jonathan
As far as I remember it reads 512 bytes. With the function getLine it simply searches for the lineend and replaces it with zero, so the buffer can simply be used as string.
With the next call you get back the address of the next line. If there is no lineend in the remaining buffer, the remaining part is copied to the beginning and the next bunch is loaded. That's the reason why the buffer has more than 512 bytes. It needs max. linelength more bytes.
The config reader is doing even more. It not only reads a file, it parses it's content. If you change the separator from " " to "," you can easily read CSV files with it and find the values in an array of longs.
You should use "c == 10" in your comparison instead of "c == 13" (the LF character is 10). Windows text files also contain a CR, but it is always before the LF. You may want to include the CR and LF characters in the string, some programs may want to know how the string was terminated, or you could have another version of the routine that strips them out. You could make it faster if you duplicate some of the code from pread in preadln.
Dave
Dave, good point about the 10 vs 13, it's my "yes, I'm using Windows" tell...sorry about that! And yes, there's plenty of room for speed-ups, again just not sure if the code-space/speed tradeoff is justified, especially for people using the Propeller IDE instead of BST (where the unused functions would get stripped). My personal leaning is to just add in the simple version of the function (maybe with a terminating character as a function parameter).
Thanks for the feedback, everybody!
Jonathan
Ray
remove the bold part.
should be or you could do something like
Also, should be something like
Ray
Jonathan
(going to edit that right now)
Any chance the udpate is going to include multi-file support? I don't care about folders for my projects, but I'd love to be pulling audio and animatronic control data from the same SD card.
Jonathan
EDIT:
if you make len your return variable, it is initialized to 0 for you, and is returned at the end of the routine, saving 2 lines of code.
So you can also read a string to the next comma or space or any other character:
Andy
So, basically you should type in 'help' to list the command list, please let me know if there are any major problems. Of course this works with the VGA monitor, in the 64x24 mode, and is using the standard 5MHz crystal.
Ray
Ray, there is an example similar to this which I think is in the FSRW 2.6 distribution zip, but I'm including it here as an attachment. It uses the serial terminal instead of VGA and keyboard.
Jonathan
Since everything is geared for TV, or serial terminal, I decided that I wanted to work in VGA. Now, everybody has some choices, and you are not funneled into TV, or serial terminal mode. Long live VGA LOL
Ray
You should change the logic at the beginning of get_keystring so that it returns "if kbd.gotkey <> true". Currently, if kbd.gotkey is not true the "if c == $0D" statement is executed using an uninitialized value for c. c is a stack variable, and it's initial value is unknown. Your code is working OK because vga.blink is probably changing the stack location that c uses to something other than $0D.
You should also include the keyboard_010.spin and MikronautsVGA64.spin objects that you are using in the ZIP file. keyboard_10.spin is not in the ZIP file, and the copy of MikronautsVGA64.spin that is in the ZIP file doesn't have the blink and gotoxy methods.
Ray