PDA

View Full Version : Coginit in C -- guess I've forgotten how to use pointers...



WNed
04-01-2009, 03:57 PM
I'm trying to get the hang of some of the more Prop specific stuff in ICC. This has not started out well. I wanted to start a function in a specific cog, but can't seem to get the pointer right for Coginit.
bare bones code:


#include <stdio.h>
#include <propeller.h>

void SomeFunc(void);
void (*fnc_ptr)(void);
long stack[20*7];

void main()
{
fnc_ptr = SomeFunc;
coginit(1, (*fnc_ptr)(), &stack[19 + 20]);
}

void SomeFunc(void)
{
printf("Hi."); // Just to have something in the function
}




compiler output:


iccprop -c -e -D__ICC_VERSION="7.04C" -DP8X32A -l -g ..\..\..\..\..\PROGRA~1\iccv7prop\Play\CogScan\poi nty.c
!E D:\PROGRA~1\iccv7prop\Play\CogScan\pointy.c(15): type error in argument 2 to `coginit'; found `void' expected `pointer to void function(void)'
D:\PROGRA~1\ICCV7P~1\bin\imakew.exe: Error code 1
Done: there are error(s). Exit code: 1. Wed Apr 01 03:46:48 2009




What have I gotten wrong?

Thanks,
Ned

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno

MagIO2
04-01-2009, 04:32 PM
Shouldn't it be "func_ptr" inside of the coginit? func_ptr is a pointer variable, so the content of it is the pointer you need in the coginit-call.

Not sure either ... C programming is so far in the past ;o)

ImageCraft
04-01-2009, 04:53 PM
coginit(1, fnc_ptr, &stack[19 + 20]);

or just
coginit(1, someFunc, &stack[19 + 20]);

In your syntax, you are *calling* the function, which is not what you want.

WNed
04-02-2009, 01:08 AM
I would have sworn I tried "coginit(1, someFunc, &stack[19 + 20]);"
I tried so many permutations. I finally dug out one of my old C books and copied the syntax directly from an example program in it... maybe the book being wrong is why I always hated pointers...
Now, if I add an argument to the function, I'm literally back to square one.




#include <stdio.h>
#include <propeller.h>

void SomeFunc(int i);
long stack[20];
int num;

void main()
{
coginit(1, SomeFunc(num), &stack[0]);
}

void SomeFunc(int i)
{
printf("%d", i); //Just to have something in the function
}




Brings me right back to:



iccprop -c -e -D__ICC_VERSION="7.04C" -DP8X32A -l -g ..\..\..\..\..\PROGRA~1\iccv7prop\Play\CogScan\poi nty.c
!E D:\PROGRA~1\iccv7prop\Play\CogScan\pointy.c(14): type error in argument 2 to `coginit'; found `void' expected `pointer to void function(void)'
D:\PROGRA~1\ICCV7P~1\bin\imakew.exe: Error code 1
Done: there are error(s). Exit code: 1. Wed Apr 01 12:40:51 2009




I really hate feeling stupid, yet here I am...
Thanks for your assistance.
Ned

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno

MagIO2
04-02-2009, 01:36 AM
You can't do that! With the () you have a function call. So SomeFunc(num) is called and returns void and this void is used as parameter for coginit. That's what the error-message tries to explain to you.

I would guess that you have to put the parameters on the stack, but I can't help you with that because I don't have a Propeller C compiler.

CounterRotatingProps
04-02-2009, 03:43 AM
//Standard C:

// Def a pointer to a function pointer and set it to null:
int (*pntr2Func)(int, char) = NULL; // or void (funPtr)(int, char), if you wish

// Def the call convention:
void __cdecl MyFunc(int MyNum, char MyChar); // The Microsoft Way
void MyFunc(int MyNum, char MyChar) __attribute__((cdecl)); // GNU gcc

// Assign a function's address to the func ptr:

int MyFunc (int MyNum, char MyChar){ printf("In MyFunc()\n"); return MyNum + 99; }

pntr2Func = MyFunc; // short version

//I don't know this compiler, but here's some hacks to try...

// *** Actually, this may be it: ***
pntr2Func = &MyFunc; // explicit reference to an address - this is really the correct *and portable* way to do the assignment.

//or, even (bad parser, bad, if so !)
pntr2Func = &MyFunc();

//If none of that works, hack hack ... try passing the pointer by reference, e.g.

coginit(1, &fnc_ptr, &stack[19 + 20]);

//since it looks like you intend to do something like a dispatch table, i.e., the pointer variable will hold the addresses of different functions before you init the cog?

//The other thing to examine is stepping and breaking at each point where the pointers
//are used and compair the actual addresses to make sure they are where you expect them to be.
//In

fnc_ptr = SomeFunc;
//*break here*

//is fnc_ptr really the same as SomeFunc?

//Also, some compilers aren't smart enough, you might have to type cast it back to void pointer in the call - if it's parser allows this.

coginit(1, (void *)fnc_ptr, &stack[19 + 20]);


//Another suggestion: mock this up in a (sorry) real compiler like VC or gcc and step-debug and see if it does it as you expect.
//As MagIO2 mentions, you might have to put that functions parms elsewhere ...
//all this really depends on how the the compiler implements the underlying address blocks (stack, heap, data, code, etc.)

//- HTH

// Howard in Florida
// (void*) (programmer)(void) ;

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Buzz Whirr Click Repeat

WNed
04-02-2009, 04:13 AM
Well thank you very much, Howard, for your informative reply. I'm concurrently learning both ICC and MinGW under Eclipse, so I can go ahead and see what things look with a *different* compiler. http://forums.parallax.com/images/smilies/blush.gif
You wouldn't happen to know where I could get an async comms IO library for MinGW, would you?

By the way, Way Cool photo. It's fun when things go boom*.

*under legal, controlled and safe circumstances... your results may vary... void where prohibited.

Ned

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno

jazzed
04-02-2009, 04:36 AM
Howard says:
//Another suggestion: mock this up in a (sorry) real compiler like VC or gcc and step-debug and see if it does it as you expect.

Yup, that's what I do if I'm not sure of something :)


Normally you would start a function in a new cog like this:

long gstack[10]; // ICCPROP doesn't like local arrays ... they should be global.
void foo(void)
{
· int n = 0
· while(1) // do something forever
··· n++;
}

void main(void)
{
· cognew(foo, gstack);
· while(1);
}

If you want to share data between your cog function and the main thread, use globals.

Looking at the cognew source though, you might be able to pass a parameter to the cog function
by setting the value in stack location 3+ i.e. gstack = parm value. I have not tested this.
I was quite annoyed that a simple parameter passing mechanism is not available, but got over it.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve


Propalyzer: Propeller PC Logic Analyzer (http://www.brouhaha.com/~sdenson/Propalyzer)
http://forums.parallax.com/showthread.php?p=788230 (http://forums.parallax.com/showthread.php?p=788230)

WNed
04-02-2009, 05:21 AM
@Steve,
It seems I was trying too hard to duplicate Spin functionality. In addition, waaaay back when I first learned C, "they" were really pushing locally defined data as a means to managing memory. I remember this because I rather liked the convenience of globally accessible data for exactly the reasons I faced today. Even with memory being tight in the Prop, it seems as though ICC prefers global over local data as well. Sheesh, if I'd had any idea that my answer is just to do what I'd do naturally anyway, this would have been a much shorter thread!

Thanks,
Ned

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno

jazzed
04-02-2009, 06:29 AM
Using local data is important for multitasking drivers and applications for reentrancy. The "good news" is we can just start another COG (a core) instead of launching 100 tasks ... oops we don't have 100 cores but we can start cores that can run proceedures serially. Unfortunately, for some reason we have limits on local data with ICCPROP. I've seen using large function scoped local arrays and structures work at some times and fail others. I've promised Richard some repeat-by scenarios the next time I hit them. Perhaps someone else will see this first.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve


Propalyzer: Propeller PC Logic Analyzer (http://www.brouhaha.com/~sdenson/Propalyzer)
http://forums.parallax.com/showthread.php?p=788230 (http://forums.parallax.com/showthread.php?p=788230)

WNed
04-02-2009, 07:09 AM
Give Cluso99 another year and we'll be up to or very near 100! I guess it would be 96 adding 8 Cogs per Blade...
Thanks for the heads up on the large local array intermittent failure. Gives me something to look forward too... http://forums.parallax.com/images/smilies/wink.gif

Thanks in general to you and the others who put so much effort into this community.
Ned

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno

ImageCraft
04-02-2009, 11:23 AM
Why local array may not work:

I don't know if this is your case, but if you have something like


main()
{
...
somefunc();
// somefunc's local space is reclaimed!!!
otherfunc();
...
}

void somefunc()
{
int stack[10];

cognew(... stack); // once somefunc returns, "stack" is gone....
...
}


re: passing params
Yes it can be done. The params can be passed on the stack, and the receiving COG can copy out the data to the LMM VM registers, to obey the calling conventions. It's not hard to do per se, but just needs time.

ImageCraft
04-02-2009, 11:30 AM
BTW, if you look at the change log for ICCPROP http://www.imagecraft.com/pub/readmeProp.txt, you will notice that since first release just less than a year ago, we did not have any compiler problem except a couple bugs with FCACHE. There were bugs with not handling large/fp printf in the IDE, not packaging the high level math functions, typos in the propeller.h, and enhancements.

That's actually pretty darn remarkable for a new compiler.

So Steve, if you find a bug with local variable, that may be the first compiler bug, but show me the code http://forums.parallax.com/images/smilies/smile.gif

// richard

jazzed
04-02-2009, 02:11 PM
Yup. In the case of stack a global array is very necessary since local variables are designed to go away once they are out of frame. I've had legitimate problems with local arrays like string buffers "char buff[256]" for example from one release to another that were solved by going global .... Not trying to cause trouble, it's just a heads up observation. I'll create a test when I have time. Kind of busy with XMM now.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve


Propalyzer: Propeller PC Logic Analyzer (http://www.brouhaha.com/~sdenson/Propalyzer)
http://forums.parallax.com/showthread.php?p=788230 (http://forums.parallax.com/showthread.php?p=788230)

WNed
04-02-2009, 11:46 PM
Guys....
Nobody's saying your new sports car is ugly, just one driver telling another to be gentle on the clutch shifting into second gear. http://forums.parallax.com/images/smilies/smile.gif

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno

CounterRotatingProps
04-03-2009, 08:54 AM
WNed said...
Guys....
Nobody's saying your new sports car is ugly, just one driver telling another to be gentle on the clutch shifting into second gear. http://forums.parallax.com/images/smilies/smile.gif


Agreed --- instead of saying use a "real" compiler http://forums.parallax.com/images/smilies/nono.gif,· maybe I should have said use a "bigger brother" compiler· http://forums.parallax.com/images/smilies/scool.gif --- especially as the only compiler I've ever written was for an 8080 http://forums.parallax.com/images/smilies/freaked.gif

This is a bit of a thread drift here, but Ned's question made me curious:

@compiler folks:· are you emulating a 'stack' in a heap-like space. Stacks (in the sense of function calls,·func. parameters,·and code-block local variables) seem like they would be problematic in a small memory footprint. What's the recursion call limit, for example?

@Ned: you're most welcome - hope that helped out. And thanks for the avatar compliment --- it's an old Star Trek scene --- where Spock and Kirk go back in time through a big dougnut looking thing to c.a. 1930 --- and Spock builds a vacuum tube kludge to interface the tricorder. It turned into the first toaster ... like a lot of my electronics projects !·http://forums.parallax.com/images/smilies/jumpin.gif

cheers
- Howard
~~~~~~

·

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Buzz Whirr Click Repeat

Post Edited (CounterRotatingProps) : 4/3/2009 1:03:10 AM GMT