Shop OBEX P1 Docs P2 Docs Learn Events
Looking for a way to save AUDS/AUGD/SETQ state - Page 2 — Parallax Forums

Looking for a way to save AUDS/AUGD/SETQ state

2»

Comments

  • evanhevanh Posts: 17,064
    edited 2026-02-14 09:38

    Use plain -g rather than -gbrk to allow printf() to coexist. Although that might not suit your situation either since I think then the debug() statements simply get converted to printf()'s.

  • roglohrogloh Posts: 6,243
    edited 2026-02-15 05:09

    @evanh said:
    Use plain -g rather than -gbrk to allow printf() to coexist. Although that might not suit your situation either since I think then the debug() statements simply get converted to printf()'s.

    When I do that I don't see any debug output, but the normal printfs in my application are printed...that's as if no debug is happening at all.

    ❯ loadp2 -t -b 230400 bigdemo.binary
    ( Entering terminal mode.  Press Ctrl-] or Ctrl-Z to exit. )
    Demo starting
    Main() is calling intfunc1 with value 1
        ----------
        intfunt1 called, with argument 1
        Adding 200
        Calling external function extfunc1(201)
        Function returned 96652, now returning this value
        ----------
    Value returned to main is 96652
    Main() is calling intfunc1 with value 96652
        ----------
        intfunt1 called, with argument 96652
        Adding 200
        Calling external function extfunc1(96852)
        Function returned 96652, now returning this value
        ----------
    

    Going back to -gbrk usage, I did another experiment and tried patching the intermediate p2asm COG code before final assembly with a DEBUG statement and that seemed to actually work.

     skip_clock_set_
        mov pa, ##@lutentry
        setq2   #255
        rdlong  16, pa
        DEBUG("hello")
        call    #_main
    cogexit
        waitx   ##160000
    

    This resulted in correct startup output with the DEBUG output also included. It's as if DEBUG doesn't work when inserted into LUTRAM for some reason but does in COGRAM. Am still investigating....

    ❯ loadp2 -b 230400 -t bigdemo.binary
    ( Entering terminal mode.  Press Ctrl-] or Ctrl-Z to exit. )
    Cog0  INIT $0000_0000 $0000_0000 load
    Cog0  INIT $0000_0404 $0000_0000 load
    Cog0  hello
    Demo starting
    Main() is calling intfunc1 with value 1
        ----------
        intfunt1 called, with argument 1
        Adding 200
        Calling external function extfunc1(201)
            ***********
    

    Update:
    Okay I have discovered more by isolating the code piece by piece:
    I can manually add a DEBUG instruction in the patched p2asm in COGRAM and get it to output. I can also jump to some fake LUT code which has a DEBUG statement inside it and get that to output strings also. For some reason in the full version of what I want to do I must have some sort of startup bug that messes with the serial port when debug is enabled (or perhaps is crashing/resetting the P2 resulting in trash being output). So with that method proven I think I can iteratively introduce more of what I do to the code to find which exact part is failing and why. Then I can move on to actually debug what I wanted to in the first place. LOL. Part of what I do is mess with the final binary image and that step could well be upsetting the debugger if some addresses or file lengths it uses are changing.

  • ersmithersmith Posts: 6,252

    @rogloh I wouldn't automatically assume it's a serial bug. It also could be debug data corrupted or missing. If you're compiling code with DEBUG statements and then later re-compiling it (or moving it around) then it's quite possible that the debugger is very confused. I think there are a number of assumptions about memory layout embedded in the -gbrk code, and if these are changed or not satisfied then it may be reading the debug strings from the wrong place in memory.

  • roglohrogloh Posts: 6,243
    edited 2026-02-16 01:05

    @ersmith said:
    @rogloh I wouldn't automatically assume it's a serial bug. It also could be debug data corrupted or missing. If you're compiling code with DEBUG statements and then later re-compiling it (or moving it around) then it's quite possible that the debugger is very confused. I think there are a number of assumptions about memory layout embedded in the -gbrk code, and if these are changed or not satisfied then it may be reading the debug strings from the wrong place in memory.

    Yes I am starting to think something like that might be the case. With -grk debug enabled I found if I ORGH a section at $100000 (1MB) then trim the downloaded binary image file off at (say) the 256kB point (the app size is only something around 100kB), it crashes/locks up immediately after the first DEBUG LOAD statement ges printed, but if instead I put my high memory ORGH code down at 400kB and do the same trim at 256kB it's fine. Very strange. Now in theory that may have something to do with my own external memory code trying to bring in and execute this code (as I'm simulating reading external high memory code from HUBRAM right now to simplify things) but it doesn't even seem to reach my cache handler stuff in the first place when it fails. No DEBUG seemed to work in the COG startup code before #_main or my extensions are even called. Although I'm still checking that out today trying to pinpoint the lockup. I did try to flip an IO pin LED at startup and think I saw it light before it went out, which may indicate a reboot, but really need to reconfirm that.

    When I trimmed the binary file before downloading, I did confirm it has all zeroes above the trim point so no debug strings should be placed there. They seemed to be somewhere down at $b99 offset in the file.

  • Wuerfel_21Wuerfel_21 Posts: 5,790
    edited 2026-02-16 01:16

    Debugger works roughly like this:

    • Program is assembled as normal, but DEBUG statements are converted into BRK #N (with N increasing each time). Associated debugger bytecode is generated and stowed away
    • Debugger program and bytecodes are combined and pre-pended to the program
    • When running, the debugger's init code is loaded into cog 0. This will
      • Setup clock mode and serial pins
      • Clear high hub RAM at $FC000..$FFFFF
      • Copy the debugger stuff into there
      • Enable debugger memory protection
      • Copy down the normal code to start at address 0
      • Clear any remaining RAM
      • Re-launch cog 0 (as the ROM bootloader would've)

    The address boundary for the copy/clear operations are defined by patching (by way of hardcoded offset >.> ) the _appsize_ variable in the debugger code.

    (EDIT: For completeness, note that executable compression works very similarly - if you have both debugging + compression enabled, compression is applied after the debugger is added. This double serving of init stubs somehow works.)

  • roglohrogloh Posts: 6,243
    edited 2026-02-16 04:38

    @Wuerfel_21 said:
    Debugger works roughly like this:

    • Program is assembled as normal, but DEBUG statements are converted into BRK #N (with N increasing each time). Associated debugger bytecode is generated and stowed away
    • Debugger program and bytecodes are combined and pre-pended to the program

    Yes that would explain why I don't see anything debug related at the end of the program.

    • When running, the debugger's init code is loaded into cog 0. This will
      • Setup clock mode and serial pins
      • Clear high hub RAM at $FC000..$FFFFF
      • Copy the debugger stuff into there
      • Enable debugger memory protection
      • Copy down the normal code to start at address 0
      • Clear any remaining RAM
      • Re-launch cog 0 (as the ROM bootloader would've)

    All makes logical sense.

    The address boundary for the copy/clear operations are defined by patching (by way of hardcoded offset >.> ) the _appsize_ variable in the debugger code.

    I'll need to examine this, it might be related to my problem if the copy amount is somehow messed up by my ORGH $100000. Hopefully I can overcome it if this is the issue.
    EDIT: Ok looks like I might have to patch this value at $e4. I do see it being setup as over 1MB when I do my ORGH. I may have to patch it with something under 512kB where the last non-zero long occurs and also accounting for the debug prepend amount of $C70. Gonna give it a try to see if the lockup disappears.
    UPDATE: YES! that was it and after patching the value the debugger hang is fixed. I can make some progress now. Thanks @Wuerfel_21 for this information! :)

    (EDIT: For completeness, note that executable compression works very similarly - if you have both debugging + compression enabled, compression is applied after the debugger is added. This double serving of init stubs somehow works.)

    Yeah didn't look into compression issues, that would probably affect things also but have other things to worry about first.

    As a last step I split the final binary generated by flexspin which is over 1MB when my external memory code segment is created at $100000. Ultimately I will split the file at an offset of 512kB (or the last non-zero long in the file below this), and anything over 1MB is extracted to a secondary image file although I've noticed the presence of debugger code will push this up a bit higher than 1MB offset in the binary image and I'll probably need to somehow compensate for that too. This secondary upper memory image file will ultimately need to be written to the 1MB boundary in Flash to be read in by my external memory initialization code to PSRAM for example. Then the cache handling code will dynamically bring the external memory code blocks into cache rows on demand.

  • roglohrogloh Posts: 6,243

    Tell you what. Running relocated C code from flexspin in hubexec at different cache addresses to the listing file is a real mind-bender to try to debug. Without using P2 DEBUG there'd really be no chance to solve the issues without going insane. So far I found a couple of addressing bugs in my code and fixed them, so some major program hangs I encountered are now fixed and the test code runs a lot further now. But there are still remaining issue(s) to resolve before this is 100% right. Once an AUGD is missed prior to my callpa ##ADDR, farcall_ext2int far calls all hell breaks loose and lockups typically prevail as is expected. All address calculations need to be spot on dealing with the AUGD/AUGS instructions at the wrap boundaries. Am slowly getting there but it's the type of work that needs a fresh brain to work through.

Sign In or Register to comment.