SimpleIDE and Propware -- I'm missing something.
greybeard
Posts: 65
I am running Win10. I am trying to use PropWare with SimpleIDE. I have downloaded the latest version of both. I got as far as attempting to run the cogc example. I set up the project the same way as I did for the getting started project. Didn't work. It failed because the '_load_start_blinky_cog' was missing. I know SIMPLEIDE will create this from a COGC file. So....
I included the blinky.cogcpp file in the project and received the message that the file format was wrong. I deleted it from the project file, changed he extension to .cogc and added it to the project. Failed again, this time because it couldn't fine the pin.h include file.
So...what am I missing.
I included the blinky.cogcpp file in the project and received the message that the file format was wrong. I deleted it from the project file, changed he extension to .cogc and added it to the project. Failed again, this time because it couldn't fine the pin.h include file.
So...what am I missing.
Comments
You can try adding "-xc++" to your compile options... whether or not this works is quite dependent on the specific implementation of SimpleIDE. Since the file is named "cogc", PropGCC can't auto-determine the language, so SimpleIDE must pass in "-xc" to force it to compile as a C file. However, if you also pass in "-xc++", that might override the "-xc" that SimpleIDE tries to pass. But it depends on a few things:
1) Will SimpleIDE use the compile flags that you type into the project Window even for a cogc file? Or maybe they're ignored since it's a special kind of file anyway?
2) Does PropGCC allow multiple instance of the "-x" argument?
3) If multiple instances of "-x" are passed, does it use the first or the last?
4) Does SimpleIDE add your special compile flags before or after its own "-xc"?
Other suggestiions??
Oh, right. Sorry - that error is not related to C/C++. Did you follow step 4 of the instructions for using PropWare with SimpleIDE?
This is the project file I have been using as created by SimpleIDE:
Cogc_Demo.cpp
-I ./../../include
-L ./../../lib
blinky.cogc
>compiler=C
>memtype=cmm main ram compact
>optimize=-Os
>-m32bit-doubles
>-fno-exceptions
>-Dprintf=__simple_printf
>-enable_pruning
>defs::-std=gnu+ -xc++ +0x -fno-rtti -fno-threadsafe-statics
>linker::-lPropWare -lLibpropeller -lSimple
>BOARD::PROPSTICK1
The result is:
blinky.cogc:26:26: fatal error: PropWare/pin.h: No such file or directory
compilation terminated.
I get the same results when running using the LMM compiler option.
You prefer the alternative - Arduino - where third-party libraries must go in a specific directory and use a specific folder structure? Or you prefer to just remove the ability to use third-party libraries? Or are you simply pipe-dreaming, waiting for a C/C++ artifact repository like Maven, NPM, and PIP?
I think using parallel processing (i.e. multiple cogs) instead of interrupts to get things done just a bit more complexity to keeping tasks working together smoothly. While I'm nfar from ann expert, I have gotten SimpleIDE to produce workable code despite clear documentation. Right now I'm investigating the use of PropWare with SimpleIDE mainly because I don't want do things on the command line. Been there, done that. There are other options but those are for a different post.
I have looked briefly into PropWare with Eclipse but that looks a bit more complicated. I would really like to see a C/C++ debugger of the Prop. Maybe in Eclipse.
Personally, I love CLion. Works absolutely wonderfully with PropWare (CLion is actually the reason I switched from Make to CMake) and I use it as my primary (only) development environment. I've also used its built-in debugger with GDB on the Prop just a bit. It had a couple problems (I don't remember what they were) but at a very basic level, it actually worked! I'm sure you can do the same with Eclipse.... I just don't like it :P
CLion is free for students, educational use, and Open Source projects and has a 30-day free trial.
https://www.jetbrains.com/clion/
You only have to pay yearly if you want yearly updates. And it gets cheaper the second and third consecutive years.
No idea, never used the Arduino IDE.
Not sure what I want. Building C/C++ projects has always been a pain in the butt whether it's make files, VS project files, Qt project files, X, Y, Z project files.
Especially if you want to be able to build the project on many different platforms and with different IDE's.
Hey, an NPM for C++ would be a great idea. We could call it CP/M
How come there isn't one after all these years?
@greybeard I have always though that not having interrupts and having totally separated processes to do what one normally does with interrupts made propeller Programming much easier. Especially when it comes to mixing and matching modules (objects) that other people have written into your project. There is no hooking into interrupt handlers. No issues of timing. No worries about priories etc. Just throw that object you found into your project confident that it cannot mess up any code you already have working. All very deterministic and dependable.
Hi greybeard, I somehow missed this post entirely. This level of detail should help me debug your issue much better - I will take a look this weekend and see if I can reproduce and fix it.
For anyone else using SimpleIDE with PropWare, this means you will not be able to use any PropWare objects in cogc/cogcpp files. Sorry for any inconvenience. I will, as always, be happy to answer any questions related to command-line compilation or integration with your favorite IDE.
History. I needed a Cog routine that had multiple sub routines (each only a few lines of code, no passed variables, but used in several different places) to limit cog memory usage. I can do this with SimpleIDE using a COGC file. I was trying to do this with PropWare.
It was (and still isn't) apparent that this could be achieved without using COGC file ... but being wrong is clearly a high possibility.
It may be possible to do it with SimpleIDE using C++ and class definitions but code space could be a problem again plus I wasn't sure how public/private routines are accessed by the COG.
Anyway. I would appreciate the feedback and and I am open to suggestions on other ways implement subroutines without a plethora of GOTO's.
Yes, I know that PASM supports call and return e.g. basic subroutine calls with no passed variables.
If you want help on how to fit into the boundaries set forth by SimpleIDE, it would be very helpful to be able to see exactly what it is you're trying to do.
As for public/private: those keywords do not affect anything at runtime or change the compiled code in any way. theyre just there to aid the programmer by showing what should and should not be used by members outside the class.
The original purpose was to get a have a Cog routine that utilized multiple short routines to handle some processing. For example.....a float library uses a cog to do floating point arithmetic. Anyway. I simply wanted to use C code with SimpleIDE to do something similar. Per the previous post, I created a simple example that I hoped would get the idea across. Unfortunately, it was not a simple as I thought. I discovered a number of things that greatly challenge my understanding of SimpleIDE, C, and Cog architecture. Telling me I don't know what I'm doing would be a fair comment.
Anyway the zip file attached is the project I put together. There is a number of comments in the code that point out where things that don't work like I would like them to work. Consider it fair game.
At this point I think I'll stay with SPIN and PASM for a while.
Thanks.
https://github.com/parallaxinc/Flight-Controller/tree/master/Firmware-C
I have a "stream processor" function in the FPU so I can send it a batch of work while I'm off doing something else, but it will also work in "single instruction" mode. I converted FDiv() and FFloat() to work that way.
The code for the flight controller has a number of PASM drivers that live in Spin files and all the interfaces are written in both Spin and C so you can see the parallels.
If I get some time this week I'll try to look at your example too.
1) You have a cogC routine and your main routine both sharing the variables pData and pMbx. That might or might not be an issue. I made the cogC function create them as locals inside the main() routine and gave them different names to be sure they wouldn't conflict.
2) Taking non-volatile pointers to objects that are volatile casts away the volatile nature of the original object. I saw this warning in both source files when compiling your code:
CogC Test.c:41:19: warning: initialization discards 'volatile' qualifier from pointer target type [enabled by default]
That means the compiler is assuming that nothing external is changing your values, which is obviously not the case, and is probably why nothing changes. I've attached my version of your code.
Also I used the '#define EXTERNAL' separate the variables used in the cogc routine from those used in the main routine. Note that both use the same variable name and there is no confusion by the compiler or during execution.
Somewhere in my rewrite I changed the COGTEST_STACK in 'Cogc_Test1.h' from 120 to 0 and the program still loads and executes.
Does anyone have an explanation why it works without a stack?? I am guessing that:
The compiler places the stack after code and data but not sure. If it places the stack prior to code space or data, this program should not work.
Does the compiler automatically place a stack at the end code and data and lets it expand as necessary -- There is plenty of room for a large stack in this example.
...OR Does the compiler simply reserve space after code and data and let the stack expand as necessary
In this case the compiler would reserve 0 stack space but the program would still work -- which it does.
The stack lives in hub memory even for COGC (-mcog) programs.
and the more that I am missing....
Just to prove my lack of understanding about SimpleIde 'c' and cogc programming.
My original objective was to launch a cog task, written in 'C" using SimpleIDE and a cogc module, that utilized subroutines that were resident in the cog. Thought a cogc module would do that, and it appears that it does.
Calling a subroutine in 'C' usually involves ;pushing information on the stack then jumping to the execution location. Returning from the routine involves popping things from the stack and continuing execution of the module calling the subroutine. If the stack is maintained in the HUB, then subroutine execution time will be impacted ... at least if my understanding of cog and hub interaction is correct.
Someone please correct me...Communication between the hub and cog is through the 6 PASM functions (RDLONG, WRLONG, etc) that require hub-cog synchronization for each i.e only one item can be exchanged for each transfer. If the stack is in the hub then each use of a passed parameter and local subroutine variable will require a hub-cog sync for the routine to execute, up to 23 clock cycles for each. Here I am assuming that the C compiler must generate a low-level instruction that uses these 6 PASM instructions.
I revised my experimental code to capture the clock counts before the inner FOR loop and the counts after the inner for LOOP. There are a total of 11 hub reads to execute the 5 iterations of the loop. The clock count varied between 740 and 960 clocks cycles. These counts are well within the clock count for max hub cog sync counts for 11 hub reads (23*11= 253).
Another interesting note, if someone runs the program, is that the clock count increases by a fixed amount for each iteration of the loop, 80 clock cycles is what I observer.
I'm afraid I have not had time to look at your code (and won't until end of May... my life is full this Month). However, for maximum speed in a short loop, I would encourage you to familiarize yourself with fcache. This will cache a snippet of your program in the cog (maximum of 64 instructions) to execute at native speed. This "fcache" is great because it lets you run all of your code in CMM (or LMM if you prefer) and then only when you need it, the necessary instructions will be copied in one large chunk into a reserved section of cog RAM, and then executed. For instance, this is how PropWare achieves 4.4 Mbps UART transfer speed even when using CMM. Fcache incurs extra overhead for calling the function, so it's probably slower overall if your function has no loops in it. But you mentioned a loop in your code, so perhaps the one-time overhead required to load the instructions from HUB to COG is acceptable.
Of course, fcache doesn't magically let a single Propeller cog do two things at once. So if you need asynchronous and fast, then you need to start a new thread and have that thread call an fcache'd function. I find that to be much easier to program than a cogc module.
Data of all sorts (including the stack) is always placed in HUB memory, even for programs compiled with -mcogc. The only exception is variables declared as _COGMEM, but there are restrictions on what you can do with those (they have to be long, not byte or word, and you cannot take the address of them).
However, I would recommend always providing a stack, because if something changes in your program (you add some more variables, or another level of function calls) then the compiler may start using the stack. If no stack was allocated, then it will start writing data below your mailbox, overwriting whatever happened to be in memory there (in PropGCC the stack grows down).
I have lost track of all the things I am missing and going back to the Propeller Tool and PASM.
Bye.