C++ Troubleshooting Challenge
DavidZemon
Posts: 2,973
I've attached two SimpleIDE projects with the relevant code.
I've created a class that should be able to safely print from multiple cogs. Sometimes, it even works! The problems is, I can't figure out why it doesn't work all of the time.
Technical details explained:
Hello_Demo works great! It's just a basic use of Printer and SimplexUART that I created to compare all the different "Hello, world!" programs. Pretty cool.... except that it doesn't work when compiled within PropWare! I was fully expecting to come here to the forums and say "Why don't either of these projects work!?"... but when I ran it outside of the PropWare build system, it works. I have no idea why.
The problem I have within the PropWare build system is Printer::_printf. It is defined as virtual currently (so that I can override it and use locks in SynchronousPrinter) and is the deepest root of the problem that I can find. If I remove virtual, Hello_Demo works again. If I change the call in Printer::printf from
I can't imagine why this works in the simple case of a standalone project but not PropWare.
Project 2: SynchronousPrinter_Demo
Much simpler problem to describe. It isn't thread safe. Not sure why
Any help is appreciated! I've tried to make it as easy as possible to help me debug, but even still I know it is quite complex with all of the files. Let me know if there's something else I can do to make it easier.
David
I've created a class that should be able to safely print from multiple cogs. Sometimes, it even works! The problems is, I can't figure out why it doesn't work all of the time.
Technical details explained:
- UART and its children are the hardware drivers.
- SimplexUART is the most basic UART concrete class capable of transmitting from a single cog. It is not thread safe and can not be used from multiple cogs.
- SharedSimplexUART is still not thread safe, but it can be used from multiple cogs so long as the user ensures two cogs do not print simultaneously.
- Printer is a class that contains formatting functionality such as put_int, put_hex, and printf. Just a clean way to keep those big functions out of the UART classes.
- A pointer to a PrintCapable class is required (UART implements PrintCapable) by the constructor and saved as a member variable. That member is then called on to do the printing
- SynchronousPrinter wraps all of its methods with locks so that it is thread-safe.
Hello_Demo works great! It's just a basic use of Printer and SimplexUART that I created to compare all the different "Hello, world!" programs. Pretty cool.... except that it doesn't work when compiled within PropWare! I was fully expecting to come here to the forums and say "Why don't either of these projects work!?"... but when I ran it outside of the PropWare build system, it works. I have no idea why.
The problem I have within the PropWare build system is Printer::_printf. It is defined as virtual currently (so that I can override it and use locks in SynchronousPrinter) and is the deepest root of the problem that I can find. If I remove virtual, Hello_Demo works again. If I change the call in Printer::printf from
this->_printf( /* args */ );to
Printer::_printf( /* args */);then it works (even with virtual still in the signature).
I can't imagine why this works in the simple case of a standalone project but not PropWare.
Project 2: SynchronousPrinter_Demo
Much simpler problem to describe. It isn't thread safe. Not sure why
Any help is appreciated! I've tried to make it as easy as possible to help me debug, but even still I know it is quite complex with all of the files. Let me know if there's something else I can do to make it easier.
David
Comments
Thanks. I was too zonked to even think about checking the zips before passing out. A PropWare folder has been added to each zip with only the relavent PropWare headers.
David
https://github.com/DavidZemon/PropWare/tree/printer
And I get gibberish output: Watching the output, it looks like the serial driver is adding on extra bits at the end: the output comes in 1 second bursts, with the A followed by some number of bad bits.
I haven't. That's very odd. I'll see if I can figure out why my scope wasn't working last night and give it another try this evening with just one cog.
As a side note... I'm feeling quite dumb. I'm scoping my board like so:
And nothing shows up. If I change the UART pin to P0 (and of course move the probe to the first pin), it works. Does the Quickstart somehow intercept P30 and keep me from reading it at the header?
Unfortunately, that didn't help at all with my synchronous issue. Three nights in a row now I've been banging my head against the wall trying to get this to work and I can't seem to figure it out where the issue lies. :frown:
A little more info:
Going to put_uint(cog) instead of printf("Hello from cog %u", cog) removes any issues. It seems to work fine when I do that. Using puts("Hello") works too (so long as "Hello" is a literal and not a local variable).
Fixed:
* printf was interruptable
* lock was not cleared upon instantiation
* lock can now be checked and refreshed
I've uploaded a binary distribution of the printer branch.
David
Also, IIRC the quickstart board doesn't have a pull-up on pin 30 so the shared UART class - when releasing its pin driver - will cause the pin to float, NG (evidently, even if I only use one cog to drive the pin I get ghost characters within the gaps). To test functionality I kept the dira setup and sent data from all cogs inverted (idle low) to an unrelated pin which is then routed through a feedback counter to pin 30.
Note, for some reason the sequences "\n\r" and "\r\n" show different behaviour in the SimpleIDE terminal. The latter works for me.
I noticed the "\n\r" and "\r\n thing too and, after looking at the Simple sources, figured out they use "\r\n" so I did changed it around. As for stack size, I'm using 128 longs so that's not a problem. Interesting that it still works when you comment out the `+ STACK_SIZE` lol.
I did just notice that isn't *quite* what I wanted. so i've changed it to but it didn't help any.
I've also applied a pull-up resistor to my board with no luck
And I never initialized wait_time. Though adding that initialization fixes the supposed deadlock problem that I thought I was having, it's still not 100% on my machine. I am repeatedly getting:
And I've seen this "2412" time and time again. Been getting that for a long time. No idea why. This copy of the demo code can be found here. And here for the entire commit.
__Edit__
If I disable some of the cogs (for instance, but wrapping the entire `run_cog` function in then cog 3 works and 1 and 2 print 2448. If I enable only cogs 1 and 2, then 2 works and 1 prints 2436. Enabling only cog 1 makes both 0 and 1 work perfectly.
_start_cog_thread asks for the top of the stack though, not the bottom. and I did try it both ways - it actually made no difference lol
But hey! Look at this! Those of us using PropGCC now have the ability to easily log as much information as we want, whenever we want, from any and all cogs we want! I wish I had this a year ago.