-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CircuitPython completely freezes upon button click #1908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Worth attaching the whole code and all the sound samples too if you're ok with that. Worth a mention of the specific version of CircuitPython and the library bundle you are using too. |
The entire codebase is here: https://pastebin.com/NT34K32T The versions of CircuitPython we tried are 3.1 and 4.0. |
I was able to replicate this. It is a hang rather than a crash. Unfortunately, it's a bit of a complicated example. It'd be great to whittle it down a bit. Anyone have a CircuitPlayground Express with an SWD attachment? |
I think this may be related to memory management. I added an "import gc" and made some calls to gc.mem_free to note that the memory was quite low just before the hang. I put in a call to gc.collect() after the 'cpx.pixels.show()' line in the while loop and ran successfully for several minutes ( as opposed to several seconds without the patch). It did, however, eventually hang. I do have a Jlink debugger which I will hook up to the CircuitPlayground Express and see what can be seen. |
Attached is a stack from the hang state. Apparently we hang while reading a WAV file. Single stepping thru, it looks like the issue is in shared_dma_transfer at the following lines: rx_active is true, so it looks like the dma_transfer_status & 0x3 is always staying at 0. I'll try looking at the relevant code to see if I can spot why that might be. |
I had a glance at your stack trace. I know nothing about this so bare in mind this is a very uninformed comment but one argument to
Is this the code in question https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/common-hal/busio/SPI.c#L325-L342 ? It looks like the [Added later] I was reading https://learn.adafruit.com/adafruit-circuit-playground-express/adapting-sketches-to-m0#storing-data-in-flash-7-18 and it talks about memory layout:
Perhaps when it says |
I think I may have spotted the issue, but would like some other HardFault_Handler Line: 294 The code at line 412 in common_hal_audiobusio_pdmin_record_to_buffer() seems to have started a DMA
So, we have an active DMA operation on channel 0 from the PDM code, and the background code
|
Sounds suspicious @DavePutz ! I think you are right about contention.
Perhaps @jepler and @deshipu have ideas of how to fix this too. |
I think @DavePutz is on the right track, if both devices ever try to use the same channel at the same time, something bad will happen. Why isn't the expected protection against this working? I started looking into this with debugging prints and the first thing I noticed is that Next, I started tracking how When this happens, it's possible for both AudioOut and PDMIn to simultaneously believe they have been allocated the same DMA channel, and to make conflicting uses of it. I did not find any other sites in circuitpython that look like they would reset ENABLE, and the datasheet at best fails to state clearly that this bit can be reset automatically at the end of a DMA operation, but one of these two things must be happening. My recommendation, and I can clean up and PR my local code that is doing this (there are also a lot of inappropriate print statements and so on), is to add a new array of bool that tracks whether CP believes the DMA channels are in use, and use that in find_free_audio_dma_channel. This involves creating new wrapper functions audio_dma_enable_channel and audio_dma_disable_channel that call the SDK functions but also manipulate the new variable: f9e4b99 However, I have to note that I did NOT reproduce the original problem of a freeze, I just found with debugging statements that both AudioOut and PDMIn were trying to use channel 0 at the same time. My testing python code was:
|
Here is some python code that reproduces reliably for me. Note that I think the use of the Neopixel code may be needed, as in my tests that generated a lot of gc_allocs and gc_frees - possibly related??
|
Unfortunately, I still get hard crashes with my earlier debugging and potential fix code. |
next guess, which it looks like has solved the problem, but not sure if it's cumulative with other local changes:
Theory: nothing is clearing out audio_dma_state for this channel (except reset); this leads to audio_dma_load_next_block being called when it shouldn't have been, which is exactly what has been described. |
I can confirm that your fix takes care of both the original code by c-k-dillard and my repro code above. My only question would be if we could still have a dma channel conflict should someone actually be playing a wav file asynchronously with using the microphone (or is that really not possible)? |
@DavePutz Yes, my analysis of how the channel->CHCTRLA.bit.ENABLE value work seem to indicate that there's a further risk of accidentally re-using a DMA channel too soon when the playback (or, hypothetically, the recording) are asynchronous. |
@jepler Care to make a PR for that audio_dma_state fix? |
Hi, I'm seeing the same hang reported in an earlier comment - I'm reading from the mic and then playing audio in a loop. I'm on v6.3. Is this a known issue still? Can I read from the mic and play audio in a different way to work around this? Also not sure if I should open a new ticket for this..
|
@geecrypt Please open a new issue with a reference to this one. New issues are easier to track than comments on closed ones. Thanks! |
While using the cpx, the two buttons crash the entire board after playing a sound. There is no error message and the REPL and serial monitor crash. The buttons are supposed to play a sound when they're pressed. Here is the video of the serial monitor crash: https://imgur.com/O1GLBwN. The board crash is also recorded: https://youtu.be/53wDuqXmbi8. The code that seems to be causing the crash is below
The text was updated successfully, but these errors were encountered: