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.).
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.
@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.
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.
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.
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 …
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.
@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:
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.
@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.
@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.
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?
@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?
@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.
@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.
@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)
...
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.
@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.
@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.
@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.
Comments
I will check again -- this didn't seem to be the case with a test I ran yesterday.
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.).
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.
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.
@cgracey That would be great. Nice to have something that one can just copy to flash and work.
Yes. Please.
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.
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.
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 …
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.
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:
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:
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.
@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:
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.
@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.
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.
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
I hope you can fix that.
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?
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.
@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:
Thank you for reporting this.
Both the OBEX and the P2_PNut_Public repository have been updated.
This is fabulous news for the new year. Cheers Chip!
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:
memobj.spin2:
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.
Indeed, that is great news!
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.
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.
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.