Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    machine.Pin('P15') crash debugging

    Scheduled Pinned Locked Moved LoPy
    11 Posts 3 Posters 2.4k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L Offline
      LoneTech
      last edited by

      I noticed that machine.Pin('P15') causes a crash on LoPy firmware <=0.9.4.b1:

      >>> p=machine.Pin('P15')
      Guru Meditation Error of type IllegalInstruction occurred on core   0. Exception was unhandled.
      Register dump:
      PC      :  400d68b8  PS      :  00060930  A0      :  800d6e81  A1      :  3ffdd370
      A2      :  3ffd5cd0  A3      :  00000000  A4      :  00000001  A5      :  00000000
      A6      :  ffffffff  A7      :  3ffdd530  A8      :  800d6e3b  A9      :  3ffdd340
      A10     :  00000026  A11     :  00000028  A12     :  00000027  A13     :  00000040
      A14     :  00000000  A15     :  00000020  SAR     :  00000007  EXCCAUSE:  00000000
      EXCVADDR:  00000000  LBEG    :  4000c46c  LEND    :  4000c477  LCOUNT  :  ffffffff
      CPU halted.
      

      Significantly, machine.Pin.module.P15 exists and doesn't crash to access. So the bug is isolated to some pins when the Pin class is called (which normally would involve creating a new instance). I expect the pin instances are singletons, since id(machine.Pin.module.P19) == id(machine.Pin('P19')). P15 and P16 crash in this manner.

      The particular pin I'm debugging, P15, is also known as G0 and GPI38 (P16=GPI39=G3 is similar, but has the Vbat connection on the expansion board). That places it in two unusual groups: above 32 and input only. It's input only because it's one of the dedicated analog inputs, which also means it's an RTC pin.

      Calling init() on the pin causes an identically reported crash, suggesting the issue is within pin_obj_init_helper, which is called by both pin_make_new and pin_obj_init.

      A quick objdump -d build/LOPY/release/application.elf indicates that the crash address is in machpin_disable_pull_up. The odd thing about it is that it gives the precise start of that function, which should be a fully general instruction, hardly invalid. A0 would point at a return instruction in pin_config, except for the part where it starts with 8 not 4. Not sure if that's at all relevant. d6e3b, found in A8, looks like a jump target in pin_obj_configure. Those are reasonable places to have visited, though the disassembly seems to have failed to realign after a realigning set of jumps. The compiler generated assembly does not show such confusion.

      I'm tired for now. I will probably resume looking at this tomorrow.

      1 Reply Last reply Reply Quote 0
      • L Offline
        LoneTech
        last edited by LoneTech

        Department of pseudobugs: In pin_set_value, the expression 1 << pin_number is used for numbers larger than 32. This is undefined behaviour in C, but happens to work because the ssl instruction only reads 5 bits. GCC seems unaware of this, since adding a bitmask to make the behaviour defined adds an unnecessary extui instruction. Edit: Apparently only because it didn't optimize fully. Doing it in the same expression instead of to a new variable worked better.

        1 Reply Last reply Reply Quote 0
        • L Offline
          LoneTech
          last edited by LoneTech

          Minor hint for others who choose to inspect the assembly, since objdump doesn't realign properly (the reason it needs to is perhaps a linker weakness). If you run make with V=1, it prints the exact commands run. You can then pick a particular object file and replace -c -o filename.o with -S -fverbose-asm -o filename.S to generate somewhat more readable assembly.

          1 Reply Last reply Reply Quote 0
          • S Offline
            sakis
            last edited by sakis

            Hi,

            Thanks for the detailed report. I confirm that this is a bug and I'll create a GitHub issue.

            L 1 Reply Last reply Reply Quote 0
            • L Offline
              LoneTech @sakis
              last edited by

              This post is deleted!
              S 1 Reply Last reply Reply Quote 0
              • S Offline
                sakis @LoneTech
                last edited by

                @LoneTech Then no need to create a new issue right? Thanks

                L 1 Reply Last reply Reply Quote 0
                • L Offline
                  LoneTech @sakis
                  last edited by

                  @sakis Sorry, I'm confusing myself. It's the non-issue of the bit shifts that I did a pull request for, I haven't tracked down the crash. Still learning to get around the code, I'm aiming at the oddity where interrupts seem to map wrong for GPIO>=32 at the moment.

                  S 1 Reply Last reply Reply Quote 0
                  • S Offline
                    sakis @LoneTech
                    last edited by

                    @LoneTech No problem. I'll create the GitHub issue anyway and if it's fixed by the pull request we can close it. Thanks for your contributions

                    1 Reply Last reply Reply Quote 0
                    • L Offline
                      LoneTech
                      last edited by LoneTech

                      The bug I'm trying to hunt down right now is a little more distinct. The irq method on pins numbered higher than 32 produces irq objects that link to their lower numbered counterparts; so for instance trying to set an interrupt handler for P19=GPIO32 instead affects P2=GPIO0. They produce separate irq objects but both affect the registers for GPIO 0.

                      1 Reply Last reply Reply Quote 0
                      • R Offline
                        Ralph
                        last edited by

                        Hi @LoneTech. Thanks for helping out here, the embedded team merged your pull request yesterday.
                        I hear from @daniel that they are planning to completely re-write the interrupt code from scratch. You might want to consider that before you dive in too deep :)

                        L 1 Reply Last reply Reply Quote 0
                        • L Offline
                          LoneTech @Ralph
                          last edited by

                          @Ralph No worries. It turned out those two were the same subtle bug, and my 3 letter fix was applied not only where I found it but a handful more places. Commit fc4dd58 contains that fix, and reenables a bit of pin initialization which I'm guessing was commented out because it hit the same bug.

                          1 Reply Last reply Reply Quote 0

                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                          With your input, this post could be even better 💗

                          Register Login
                          • 1 / 1
                          • First post
                            Last post

                          Pycom on Twitter

                          Pycom