Closed martinwork closed 8 years ago
Thanks @martinwork
The function call to save the key-value pair should only prompt a physical write to memory if the value is different to that already stored... but i'm not seeing code to do that. Looks like a missing validation case in MicroBitStorage:put(). Good catch!
Looking at this, there's a fair bit of overlap with the low level read/write calls used in MicroBitFileSystem. Aligning this would reduce necessary code and solve the problem in one go... James is going to pick this up.
Will fix when #139 is merged.
thanks
Thanks @finneyj and @jamesadevine ... I noticed it because I had added some serial trace to flashPageErase. I didn't realise this was supposed to depend on the behaviour of MicroBitStorage. I was thinking of maybe replacing the lines in init featuring storedSample with memcpy( &average, calibrationData->value, sizeof(CompassSample)); status |= MICROBIT_COMPASS_STATUS_CALIBRATED;
BTW, am I right in thinking that saving the calibration can't be done while BLE is connected? It seems that if I try to calibrate with BLE connected I end up with a triangle of LEDs lit, apparently in flashPageErase.
@martinwork yep - that'll do as a workaround.
yes, we had also occasionally noticed that feature with BLE connected - pretty sure it's when SoftDevice's high priority interrupt fires during an erase cycle. It's on the list... :-)
If you have a repro case though, perhaps you could try disabling interrupts during flashPageErase(), and report back if that solves the behaviour?
Tried adding disable/enable_irq - no luck. The following seems to be about this situation: https://devzone.nordicsemi.com/question/1183/nrf51822-flash-erase-error/
Many thanks - that does seem to reinforce our thoughts about this being the cause...
Surprising that disabling IRQs doesn't prevent this issue at the expense of introducing latency in the BLE stack. I'm guessing the BLE radio must be running at really high priority, and is getting masked by _disable_irq(), or the delay introduces an unresolvable fault in SoftDevice...
Thanks also for the link - this sounds like an approach we should explore...
p.s. can you confirm that the fault only arises when BLE is actually connected?
I was getting lockups when doing neopixel - which was only 1-2ms with interrupts disabled. Disabling BLE fixes the problem. They lockup would only happen after a few seconds, randomly.
Thanks @mmoskal - yet more evidence of this.
I haven't had a problem without BLE connected. I tried lots of variations on how and when to call calibration before I remembered that saving to flash and BLE didn't go together ( maybe should be mentioned in the docs?).
The link's idea of using a slow connection seems likely to fail occasionally.
I suppose maybe saving could be delayed until disconnection.
I have arranged to close the connection to calibrate. If saving were moved out of the calibration routine, I could message the central to call me back in a few seconds before I disconnected to save.
we could do a delayed save, but this actually brings its own problems... e.g. it's necessary to persistently save some connection state to be BLE compliant (the CCCD state) - which in itself requires a flash erase/write. Hence we could actually wait pretty much forever for a disconnection... which may result in us never saving crucial state.
although... I guess the calibration data isn't critical. :-)
I was getting lockups when no BLE device was connected. Just enabling BLE in compilation was causing trouble.
@mmoskal I assume this was before the recent changes to the storage class...
When using locally scoped variables allocated on the stack, memcpying 48bytes, a lock up would occur consistently.
@martinwork what about you? Are you tagging against master or a specific version?
Sorry, on my phone.
memcpying when the data size was less than 48bytes, and declared on the stack.
I'm working with a local copy of "microbit-samples-master" with my own main(). The yotta_modules folder is identical to the current microbit-samples-master ( after a yotta build), except...
Thanks @martinwork. We did put a new ticker implementation in there - perhaps we don't tear down the interrupt handler properly before reset...
@jamesadevine sorry, I should have been more explicit: I was getting lockups with neopixel (no compass) with no BLE connection.
Thanks @martinwork for raising this, I've temporarily added a patch and it is in the latest tagged release, v2.0.0-rc3
.
@martinwork I'm going to close this issue, as this is resolved as of v2.0.0-rc3
Also, if you are interested in a DFU fix, pull the latest microbit-dal
master, and update mbed-classic
:
https://github.com/lancaster-university/mbed-classic/commit/1fb8ab4c1942d7eaa265e032e203c01a3bd71019
P.S. it was actually a combination of this line and the underlying timer implementation that was causing the DFU bug, good find @martinwork !
@jamesadevine thanks and well done
:smile: along with @finneyj
MicroBitCompass::init calls storage->get to retrieve the compassCal data then calls setCalibration.
setCalibration calls storage->put, which writes the same compassCal data back to flash.