fsrw isn't flushing all data
Circuitsoft
Posts: 1,166
Hi,
I'm trying to write CSV to a log file on an SD card, and I'm finding that the file ends with several 512-byte blocks of nulls rather than the correct data.
I'm making a GPS data-logger based on the Skytraq Venus 6 chipset, configured to binary mode. My serial-handling cog calls proc_msg when it finds a complete navigation message from the GPS. 'Ser' is a FullDuplexSerial4port object with port 0 connected to the GPS and port 1 going to the upstream USB port.
I have a button attached to pin 22 with a simple hardware debounce circuit, and an LED on pin 23 that's handled by a 3rd cog.
So, I turn on the board, and my LED turns green. I wait until the GPS lock LED starts blinking and then I press the button such that my LED starts blinking green. After 10-15 seconds, I press the button for several seconds, and when I release, the LED turns off. I wait a few seconds in case the SD card needs to flush itself then depower the board, put the SD card into the computer, and get the attached file. The first 512 bytes of the file are correct, then it's nulls up until the proper length of the file, where it ends in $0d, $0a.
Am I doing something wrong that the file isn't getting flushed properly?
I'm trying to write CSV to a log file on an SD card, and I'm finding that the file ends with several 512-byte blocks of nulls rather than the correct data.
I'm making a GPS data-logger based on the Skytraq Venus 6 chipset, configured to binary mode. My serial-handling cog calls proc_msg when it finds a complete navigation message from the GPS. 'Ser' is a FullDuplexSerial4port object with port 0 connected to the GPS and port 1 going to the upstream USB port.
I have a button attached to pin 22 with a simple hardware debounce circuit, and an LED on pin 23 that's handled by a 3rd cog.
PUB run_button | evt, last_state, last_time, failed evt := \sdfat.mount_explicit(24, 25, 26, 27) ' SD card on pins 24-27 if evt led := LED_RED ser.str(1, string("Mount error ")) Dec(evt, 0) ser.Tx(1, $0d) else led := LED_GREEN ser.str(1, string("Mount succeeded", $0d)) repeat evt := 0 if last_state and not ina[22] ' Button pressed last_time := cnt evt := 1 if ina[22] and not last_state ' Button released last_time := cnt - last_time evt := 2 last_state := ina[22] if evt == 2 if last_time > (clkfreq << 1) ' Button held at least two seconds led := LED_GREEN_FAST_BLINK led := LED_OFF sdfat.unmount elseif last_time > (clkfreq >> 3) ' Button held at least an eigth of a second - real press if led =< LED_YELLOW ' Not in a state we can do anything about else if led == LED_GREEN failed := \sdfat.popen(string("log.csv"), "a") if failed led := LED_RED led := LED_GREEN_BLINK elseif led == LED_GREEN_BLINK led := LED_GREEN_FAST_BLINK sdfat.pclose led := LED_GREEN if good and (led == LED_GREEN_BLINK) Dec(week, 1) sdfat.pputc(",") Dec(centiseconds, 1) sdfat.pputc(",") Dec(lat, 1) sdfat.pputc(",") Dec(lon, 1) sdfat.pputc(",") Dec(alt, 1) sdfat.pputc($0d) sdfat.pputc($0a) good := 0 PRI proc_msg | i 'ser.str(1, string("Got GPS: la")) ' Week is a 16 bit value, so need to 0-fill it ' Other values are 32 bits, so any existing data gets shifted out. week := 0 repeat i from 7 to 8 week <<= 8 week |= gps_string[i] repeat i from 9 to 12 centiseconds <<= 8 centiseconds |= gps_string[i] repeat i from 13 to 16 lat <<= 8 lat |= gps_string[i] repeat i from 17 to 20 lon <<= 8 lon |= gps_string[i] repeat i from 25 to 28 alt <<= 8 alt |= gps_string[i] good := 1 Dec(week, 0) Ser.Tx(1, ",") Dec(centiseconds, 0) Ser.Tx(1, ",") Dec(lat, 0) Ser.Tx(1, ",") Dec(lon, 0) Ser.Tx(1, ",") Dec(alt, 0) Ser.Tx(1, $0d)
So, I turn on the board, and my LED turns green. I wait until the GPS lock LED starts blinking and then I press the button such that my LED starts blinking green. After 10-15 seconds, I press the button for several seconds, and when I release, the LED turns off. I wait a few seconds in case the SD card needs to flush itself then depower the board, put the SD card into the computer, and get the attached file. The first 512 bytes of the file are correct, then it's nulls up until the proper length of the file, where it ends in $0d, $0a.
Am I doing something wrong that the file isn't getting flushed properly?
Comments
* This also includes the case of violent motion disrupting the contacts on the card.
I've not read any of the code but I'd say that is a bit of an indication that you are feeding nulls into the file.
1. finish any writing of data so you have a complete data element
2. close file (includes flushing of data)
3. unmount card
I don't follow your logic in your code as to how this happens. But maybe it's just me... :-)
So, calling unmount closes the file anyway.
I see what you are saying about some of the methods being included in the others however I still flush and close the file before unmouting.