Shop OBEX P1 Docs P2 Docs Learn Events
PNut/Spin2 Latest Version (v48.1 - preprocessor and flash-image saving) - Page 70 — Parallax Forums

PNut/Spin2 Latest Version (v48.1 - preprocessor and flash-image saving)

16667687072

Comments

  • JonnyMacJonnyMac Posts: 9,182
    edited 2024-12-10 15:49

    Understood. PNut is currently saving a raw binary image file if you just use "filename -c".

    I will check again -- this didn't seem to be the case with a test I ran yesterday.

    I didn't write the uSD loader that is in the P2 ROM, so I am not sure how it works, but my understanding is that if you put a binary file on a formatted SD card called "_BOOT_P2.BIX", it will boot from that.

    That only works when the SD card that is comingled with the Flash is attached; I cannot use that SD card in my apps because I am using the the Flash for program configuration values. It was a bad idea to comingle the SD and Flash data lines they way they are -- they made one of the other device useless over the savings of a single pin. Not at all ironic that the person who forced this issue is not long participating in the Propeller community....

    Ideally, it would be nice if we had a unified, dual-device driver that would allow us to access files on the Edge Flash and on the Edge uSD at the same time. Until that time, though, I'm using a separate uSD for my files (WAVs, etc.).

  • JonnyMacJonnyMac Posts: 9,182
    edited 2024-12-10 15:58

    @Rayman said:

    @ke4pjw said:
    I think what Jon wants is this:

    Is this true? Does the "Save Flash File" create a file that can be directly copied into the flash boot chip without modification?

    Not from Propeller Tool, no. I went down this road a long time ago. It does save a binary image, but not a clean, ready to boot image.

  • @JonnyMac said:

    @Rayman said:

    @ke4pjw said:
    I think what Jon wants is this:

    Is this true? Does the "Save Flash File" create a file that can be directly copied into the flash boot chip without modification?

    Not from Propeller Tool, no. I went down this road a long time ago. It does save a binary image, but not a clean, ready to boot image.

    Ah, OK. I was wrong. The only difference between the Binary and Flash is that the Flash file is zero filled the rest of the 512k.

  • JonnyMacJonnyMac Posts: 9,182
    edited 2024-12-10 20:36

    I downloaded a simple program to Flash from the latest version of PNut. I used the CLI to create a binary version of the downloaded code (used -c). I then ran a Flash reader in RAM to look at the contents and I found they do not match. I'm not sure why. For the moment I'm assuming I did something wrong -- will keep checking.

  • cgraceycgracey Posts: 14,232
    edited 2024-12-10 21:58

    @JonnyMac said:
    I downloaded a simple program to Flash from the latest version of PNut. I used the CLI to create a binary version of the downloaded code (used -c). I then ran a Flash reader in RAM to look at the contents and I found they do not match. I'm not sure why. For the moment I'm assuming I did something wrong -- will keep checking.

    What winds up in the flash is the application (the binary) prepended with the second-stage-flash loader which runs after the ROM's first-stage-flash loader. I will have to make a new command to output this version of the application. When you download with flash, the flash programmer is prepended with the second-stage-flash-loader+binary blob.

  • RaymanRayman Posts: 14,789

    @cgracey That would be great. Nice to have something that one can just copy to flash and work.

  • JonnyMacJonnyMac Posts: 9,182
    edited 2024-12-10 22:09

    I will have to make a new command to output this version of the application. When you download with flash, the flash programmer is prepended with the second-stage-flash-loader+binary blob.

    Yes. Please.

    @Rayman said:
    @cgracey That would be great. Nice to have something that one can just copy to flash and work.

    I have made it work as Ray suggests, but I had to do post-processing of the previous binary file before I could copy it from an SD into the Flash to run. In the past I suggested the extension be P2I so that we know it's a bootable P2 image file.

    Thanks, Chip.

  • evanhevanh Posts: 16,075
    edited 2024-12-10 22:28

    They're all bootable. Just that the EEPROM method, alone, also needs the staged loader. Chip could have chosen it to be a fixed length 512 kB, filling all of hubRAM, but went with the staged loader approach instead. Much faster iterating on updating the Flash chip this way.

    Cluso's SD boot method allows a direct binary, without staging, same as serial loading. This is due to the complexities of reading an actual file at boot time. If you can manage that then it's nothing to also handle variable file size as well.

  • RaymanRayman Posts: 14,789

    Was just wondering if multitasking could be used for debugging …. Maybe a second task could report variable values over serial and then wait for response to continue …

  • JonnyMacJonnyMac Posts: 9,182
    edited 2024-12-13 00:27

    I frequently use a secondary Spin cog to report values to a terminal for debugging. I don't know that the new multitasking features would be useful here, but I'm interested in your ideas. I really wish there were a P2 DEBUG window that was as easy to use as PST. I guess tasks could be used to update portions of an output instead of doing the whole thing in one go.

  • evanhevanh Posts: 16,075
    edited 2024-12-12 22:48

    @JonnyMac said:
    I really which there were a P2 DEBUG window that was as easy to use as PST. I guess tasks could be used to update portions of an output instead of doing the whole thing in one go.

    I use loadp2 after compiling with Pnut -cd from a shell. Same as I do with Flexspin. I've got a single line in the shell's history for each combination, eg:

    filename=test_setqrdlong;  wine ~/hoard/coding/bin/PNut_v39.exe ${filename}.spin2 -cd; loadp2 ${filename}.bin -p /dev/serial/by-id/usb-Parallax_Inc_Propeller_P2-ES_EVAL_P23YOO42-if00-port0 -t -b 2000000
    

    I suppose I should go one step further and save them as a script each, with "filename" as an argument.

  • Hi Chip,
    I found an error in the new v47 - Cooperative multitasking.
    Here a short Testprog:

    _clkfreq = 240_000_000
    DEBUG_LOG_SIZE = 1_000_000
    
    var Magic, stk[30]
    
    pub start() | i
      Magic := $DEADBEEF    'for testing
      LONGFILL(@stk, $12345678, 30)   'for testing
      taskspin(newtask, LED(), @stk)
      debug(uhex(Magic))
      repeat while Magic == $DEADBEEF    'test Magic for overwrite 
        'debug(UHEX_LONG_ARRAY(@stk,16))
        tasknext()
      'debug(UHEX_LONG_ARRAY(@stk,16))
      debug(uhex(Magic))
    
    pri LED()
      debug("Start: ",udec(taskid(), taskchk(thistask)))
      repeat 1_000
        pintoggle(16)
        tasknext()
      debug("End: ", udec(taskid()))
    

    After task LED() toggles 1000 times and the task ends the Var Magic is overwritten with values from stk[]

    Uwe

  • cgraceycgracey Posts: 14,232
    edited 2025-01-03 21:39

    @wummi said:
    Hi Chip,
    I found an error in the new v47 - Cooperative multitasking.
    Here a short Testprog:

    _clkfreq = 240_000_000
    DEBUG_LOG_SIZE = 1_000_000
    
    var Magic, stk[30]
    
    pub start() | i
      Magic := $DEADBEEF    'for testing
      LONGFILL(@stk, $12345678, 30)   'for testing
      taskspin(newtask, LED(), @stk)
      debug(uhex(Magic))
      repeat while Magic == $DEADBEEF    'test Magic for overwrite 
        'debug(UHEX_LONG_ARRAY(@stk,16))
        tasknext()
      'debug(UHEX_LONG_ARRAY(@stk,16))
      debug(uhex(Magic))
    
    pri LED()
      debug("Start: ",udec(taskid(), taskchk(thistask)))
      repeat 1_000
        pintoggle(16)
        tasknext()
      debug("End: ", udec(taskid()))
    

    After task LED() toggles 1000 times and the task ends the Var Magic is overwritten with values from stk[]

    Uwe

    I had discovered such a bug earlier and updated the initial v47 upload with a fixed version. I should add another digit to version numbers, going forward, to make sub-version updates obvious.

    Here is the latest:

    https://obex.parallax.com/obex/pnut-spin2-latest-version/

    I hope that solves the problem you are seeing. If not, please let me know here.

    I will investigate this, too, by running your program on the current version.

    I also wonder if this bug affects/affected anything below LONG[@stk][-1].

    Thanks for posting about this.

  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 01:41

    @wummi, I see the problem in the latest compiler, too.

    When the task ends and pops the stack all the way down, it winds up modifying the LONG below the stack base. It doesn't affect the LONG below that one, though.

    I will get this fixed now. Thanks a lot for pointing this out. For now, this will get around the problem:

    taskspin(newtask, LED(), @stk[1])   'point to one long into stk
    

    I modified your code a little bit. I had to put in {spin2_v47} to get the task instructions working and I made a check for the long before Magic.

    {spin2_v47}
    _clkfreq = 240_000_000
    DEBUG_LOG_SIZE = 1_000_000
    stksize = 20
    var MagicPre,Magic, stk[stksize]
    
    pub start() | i
      MagicPre := $DEADBEEF    'for testing
      Magic := $DEADBEEF    'for testing
      LONGFILL(@stk, $77777777, stksize)   'for testing
      taskspin(newtask, LED(), @stk)
      debug(uhex(@stk))
      debug(uhex(MagicPre, Magic))
      repeat while Magic == $DEADBEEF    'test Magic for overwrite 
        debug(UHEX_LONG_ARRAY(@stk,stksize))
        tasknext()
      debug(UHEX_LONG_ARRAY(@stk,stksize))
      debug(uhex(MagicPre, Magic))
    
    pri LED()
      debug("Start: ",udec(taskid(), taskchk(thistask)))
      repeat 1
        pintoggle(16)
        tasknext()
      debug("End: ", udec(taskid()))
    
  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 04:02

    @wummi, the problem was that I was using the TASKNEXT routine to switch away from a RETURNed task. The exact problem was that TASKNEXT was pushing the now-dead task context before loading the next one. Because the RETURNed task popped all the way out, then even popped a new top-of-stack value, its final stack pointer wound up one long below its initial stack pointer. So, letting TASKNEXT push the now-dead context was not a harmless operation, because the stack was one long below where it started. So, now I will jump midway into TASKNEXT, where it sets up the next task. This will be a little faster, anyway. It will take one extra instruction to fix this. Thanks a lot for reporting this.

  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 08:05

    This TASK-return bug is now fixed and the file has been updated on the OBEX:

    https://obex.parallax.com/obex/pnut-spin2-latest-version/

    When this version of PNut runs, you will see "PNut v47.1" at the top of the screen.

  • maccamacca Posts: 819

    @cgracey said:
    This TASK-return bug is now fixed and the file has been updated on the OBEX:

    https://obex.parallax.com/obex/pnut-spin2-latest-version/

    When this version of PNut runs, you will see "PNut v47.1" at the top of the screen.

    The interpreter source in the package seems the same as the previous version, can you please update it (and/or update the Github repository) ?
    Thanks.

  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 09:20

    @macca said:

    @cgracey said:
    This TASK-return bug is now fixed and the file has been updated on the OBEX:

    https://obex.parallax.com/obex/pnut-spin2-latest-version/

    When this version of PNut runs, you will see "PNut v47.1" at the top of the screen.

    The interpreter source in the package seems the same as the previous version, can you please update it (and/or update the Github repository) ?
    Thanks.

    Oh, sorry about that, Marco. I will get this done tonight, as well as update the P2_PNut_Public repository with everything.

    The OBEX file is now updated.
    The P2_PNut_Public repository is now updated.

  • cgraceycgracey Posts: 14,232

    In the latest v47, there is a preprocessor which will have command-line control in v48.

  • maccamacca Posts: 819

    @cgracey said:
    In the latest v47, there is a preprocessor which will have command-line control in v48.

    Awesome! Looks compatible with what I have already implemented in Spin Tools.

  • cgraceycgracey Posts: 14,232

    @macca said:

    @cgracey said:
    In the latest v47, there is a preprocessor which will have command-line control in v48.

    Awesome! Looks compatible with what I have already implemented in Spin Tools.

    One thing that might be different is that the scope of preprocessor symbols is outside the scope of CON symbols. They have totally separate lives.

  • Hi Chip,
    v47.1 is working now.
    One more thing: the behavior of ABORT ist changed.
    ABORT now executes TASKSTOP and not COGSTOP.
    Is the COG stoped when all 32 tasks are stoped?

    Thanks for the quick fix,
    Uwe

  • Hi Chip,
    next Problem with v47.1 - Cooperative multitasking.
    taskspin(newtask, ..., ....) returns nothing.
    It should return the TaskNo or -1

    {Spin2_v47}
    
    _clkfreq = 240_000_000
    DEBUG_LOG_SIZE = 100_000_000
    
    var stk[300]
    
    pub start() | i, task
      repeat i from 1 to 7
        taskspin(newtask, LED(i), @stk[i*30])             'works
        'task := taskspin(newtask, LED(i), @stk[i*30])    'crasch after 2 tasks statet
        'debug(sdec(task))
    
      repeat
        pintoggle(16)
        tasknext()
    
    pri LED(id)
      debug("Start: ",udec(taskid()))
      repeat 100_000 * id
        pintoggle(id + 16)
        tasknext()
      debug("End: ", udec(taskid()))
    

    I hope you can fix that.
    Uwe

  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 19:10

    @wummi said:
    Hi Chip,
    v47.1 is working now.
    One more thing: the behavior of ABORT ist changed.
    ABORT now executes TASKSTOP and not COGSTOP.
    Is the COG stoped when all 32 tasks are stoped?

    Thanks for the quick fix,
    Uwe

    That's right. ABORT now executes TASKSTOP if no \ is in the method-call chain. And then TASKSTOP will do a COGSTOP when no tasks are left. I thought that was the logical thing to do. What do you think?

  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 19:18

    @wummi said:
    Hi Chip,
    next Problem with v47.1 - Cooperative multitasking.
    taskspin(newtask, ..., ....) returns nothing.
    It should return the TaskNo or -1

    {Spin2_v47}
    
    _clkfreq = 240_000_000
    DEBUG_LOG_SIZE = 100_000_000
    
    var stk[300]
    
    pub start() | i, task
      repeat i from 1 to 7
        taskspin(newtask, LED(i), @stk[i*30])             'works
        'task := taskspin(newtask, LED(i), @stk[i*30])    'crasch after 2 tasks statet
        'debug(sdec(task))
    
      repeat
        pintoggle(16)
        tasknext()
    
    pri LED(id)
      debug("Start: ",udec(taskid()))
      repeat 100_000 * id
        pintoggle(id + 16)
        tasknext()
      debug("End: ", udec(taskid()))
    

    I hope you can fix that.
    Uwe

    SPINTASK should return 0..31 or -1, when used as an expression term. I will investigate this.

    EDIT: Yes, there is definitely a problem when using SPINTASK as an expression term.

  • cgraceycgracey Posts: 14,232
    edited 2025-01-04 20:28

    @wummi, I got this fixed and I updated the file in the OBEX.

    The problem was that I was doing a JNC in the x86 compiler code, when I should have been doing a JNS. This was causing a bit flag in a compiled Spin2 bytecode to not get set, which was to indicate when a return result was needed. I also found that the return result was not XOR'd with $1F in the intepreter, as it should have been, to give the user the proper task number. These problems are both fixed now.

    I added a new file to the .zip file called TASKSPIN_demo.spin2, which is a variation of what you posted above:

    'Use Ctrl-F10 to run
    
    {Spin2_v47}
    
    CON _clkfreq = 200_000_000
    
    VAR stk[30*32]
    
    PUB start() | i, task
    
      repeat 32 with i
        task := taskspin(newtask, LED(i), @stk[i*30])
        debug(sdec(task))
    
      debug("Ending: ", udec(taskid()), ", Other tasks are running")
    
    PRI LED(id)
      debug("Started: ", udec(taskid()))
      repeat 20_000 * id
        pintoggle(id)
        tasknext()
      debug("Ending: ", udec(taskid()))
    

    Thank you for reporting this.

    Both the OBEX and the P2_PNut_Public repository have been updated.

  • roglohrogloh Posts: 5,852
    edited 2025-01-05 02:09

    @cgracey said:
    In the latest v47, there is a preprocessor which will have command-line control in v48.

    This is fabulous news for the new year. Cheers Chip!

    @cgracey said:
    One thing that might be different is that the scope of preprocessor symbols is outside the scope of CON symbols. They have totally separate lives.

    Hmm. Is there any way that the overridden constants passed down from the caller's object instantiation line still somehow influence the pre-processor? Can the macro defined in an #ifdef refer to a CON constant at all?

    e.g. I'm thinking of something that would enable this type of usage where the parent can affect what is built in the child object but probably won't work out with the current approach:

    caller code:

    OBJ   
       mem : "memobj" | extmem_select=1  ' override to use external memory
    
    PUB init()
       mem.fillmem(BUFFER, 0, BUFFSIZE)
       ...
    

    memobj.spin2:

    #define EXTRAM extmem_select
    
    PUB fillmem(addr, val, len)
    #ifdef EXTRAM
       psram.fillbytes(addr, val, len)
    #else
       bytefill(addr, val, len)
    #endif
    

    I was sort of hoping if extmem_select is not defined by parent (remains undefined in CON section) this #define EXTRAM extmem_select line may not actually create the EXTRAM macro. You may possibly achieve this by allowing an optional parameter after the macro name which is then looked up in the CON section for existence?

    Also can some future variant allow the macro's value itself be checked for a selection, if extmem was a number that signified the type of memory for example? That's probably going to be more difficult as it needs an #if statement evaluation instead of simpler #ifdef.

  • ersmithersmith Posts: 6,088

    @rogloh said:

    @cgracey said:
    In the latest v47, there is a preprocessor which will have command-line control in v48.

    This is fabulous news for the new year. Cheers Chip!

    Indeed, that is great news!

    @cgracey said:
    One thing that might be different is that the scope of preprocessor symbols is outside the scope of CON symbols. They have totally separate lives.

    That's the way flexspin and openspin work too, similarly to C compilers. I think it makes things simpler and allows the preprocessor to be implemented in a separate pass or even an external program.

    Hmm. Is there any way that the overridden constants passed down from the caller's object instantiation line still somehow influence the pre-processor? Can the macro defined in an #ifdef refer to a CON constant at all?

    Please let's not be mixing in CON constants with the preprocessor, I really like what Chip has now. Having a way to define symbols in the child might be useful but perhaps some new syntax could be implemented for that.

    Another option would be CON with dead code removal for IF statements. That would be a nice optimization in general.

  • roglohrogloh Posts: 5,852
    edited 2025-01-05 04:16

    @ersmith said:
    Please let's not be mixing in CON constants with the preprocessor, I really like what Chip has now. Having a way to define symbols in the child might be useful but perhaps some new syntax could be implemented for that.

    Yeah we'd want a nice clean way to do it. Doesn't have to use the CON constants but would be handy to have some way for parent code to control what the child implements or exposes to the parent. That way you don't have to modify the child code at all.

    Although another solution might end up being some common included "config" file that gets modified for a customized solution. Just trying to avoid a situation where you'd need to hand edit multiple files to configure the same macro symbols in each file and keep this information consistent over these files. Thinking further, maybe if the tool always controls these shared macro symbols by being defined on the command line this becomes a non-issue.

  • cgraceycgracey Posts: 14,232

    @rogloh said:

    @ersmith said:
    Please let's not be mixing in CON constants with the preprocessor, I really like what Chip has now. Having a way to define symbols in the child might be useful but perhaps some new syntax could be implemented for that.

    Yeah we'd want a nice clean way to do it. Doesn't have to use the CON constants but would be handy to have some way for parent code to control what the child implements or exposes to the parent. That way you don't have to modify the child code at all.

    Although another solution might end up being some common included "config" file that gets modified for a customized solution. Just trying to avoid a situation where you'd need to hand edit multiple files to configure the same macro symbols in each file and keep this information consistent over these files. Thinking further, maybe if the tool always controls these shared macro symbols by being defined on the command line this becomes a non-issue.

    Command-line DEFINE/UNDEF of master pre-processor symbols is clean and hopefully sufficient. Getting preprocessor symbols tangled up with CON symbols could pose chicken-and-egg problems.

Sign In or Register to comment.