Page 2 of 2

Re: Proper Queue usage

Posted: Thu Jul 29, 2010 7:22 pm
by tod
I don't know what the structure of your code is, depending on that your options are at least:
1. A regular class member variable (requires an instance of the class)
2. A class static member variable (doesn't require an instance of the class)
3. A file static variable. (Global to the file but not the whole program i.e. "file scope")
3. A "global" variable that resides in a namespace (the pig with lipstick solution)
4. A global variable (the pig without lipstick).

If you're a C programmer (not C++) you need to realize that the static keyword takes on an additional function in C++.

If you put in your .h file

Code: Select all

class YourClass
{
   private:
      static float someFloatVar_;
}
In your.cpp file (by convention up at the top before any methods) you have to have

Code: Select all

float YourClass::someFloatVar_;  //you should probably initialize it here as well =0.0 or whatever.

Re: Proper Queue usage

Posted: Fri Jul 30, 2010 7:33 am
by vsabino
Tod, thanks for the reply. I'm not a C++ programmer, but I was reading a little about static variables, and knew what they mean inside a class. I don't have that section of code implemented with classes, so I think the simplest way (without resorting to "pigs") would be to declare a static float variable and pass a pointer to it.

Although, I saw a post from Pbreed: "float is 32 bits, ok to stuff into a queue, double is 64 bits, not ok." Paul, how can I stuff a float into a queue, elegantly? Any suggestions aside from what tod and Larry mentioned?

Thanks,
Victor

Re: Proper Queue usage

Posted: Fri Jul 30, 2010 11:44 am
by pbreed
Do it just like I described in my first post example with an int, only now its a float.

So to put it into a Queue

float fin;
OSQPost(&myQ, (void * )fin);

then get it back

BYTE err_result;
float fout =(float) OSQPend( &myQ, timeout, &err_result );

if(err_result==OS_NO_ERR )
{
fout has the value posted....
}

Re: Proper Queue usage

Posted: Fri Jul 30, 2010 12:27 pm
by vsabino
Paul,

That's how I started the float discussion. Please see my post from "Fri Jul 23, 2010 6:42 am"

".......I got it to work, except for one case where I want to queue a float:

float float_speed;
OSQPost( &QueueIRQ3, (void *)float_speed);

I get this error: invalid cast from type 'float' to type 'void*'.................."


Victor

Re: Proper Queue usage

Posted: Fri Jul 30, 2010 1:42 pm
by pbreed
If the same exact code works in other places, what
is different in that file?

Is it possible that someplace has redefined the float to be double?

What does sizeof(your_float_varuiable); report in that case?

Re: Proper Queue usage

Posted: Fri Jul 30, 2010 5:41 pm
by tod
Paul,

I think the point was that casting a float as a void* doesn't work anywhere. Previous posts showed a couple of ways to "fool" the compiler, but it was pointed out that this general approach to sticking values in queues breaks down once a primitive data type size exceeds the size of a pointer.

Tod

Re: Proper Queue usage

Posted: Mon Aug 02, 2010 7:23 am
by vsabino
Paul,

float float_speed;
OSQPost( &QueueIRQ3, (void *)float_speed);

never worked for me. I was experimenting with ints. Then, when I tried the float, I got the compile error.
"invalid cast from type 'float' to type 'void*"

Tod and Larry pointed out that this would not work as is, that I had to make some changes to "fool" the compiler, or avoid doing this altogether, by passing a pointer to the float.

That is where I was, when you posted that the above snippet should work.

Thanks,
Victor

Re: Proper Queue usage

Posted: Mon Aug 02, 2010 10:00 am
by pbreed
My error, the compiler used to let you cast any 32 bit (ie 4 byte) chunk as a void *.
Every time we update the complier it gets pickier.

You can't pass the pointer to the float as the float is then on the stack and or if static there is only one float.
If you want pass floats where each float is unique then you will have to do a union.
Lets say we pass a pointer to a float, when we change the value of that float the value you passed will change.

Please note that the reality check printf to make sure the sizes are correct.

Take a look at example #2
It shows the problem with passing a pointer to a float rather than the actual float.
When it sleeps for 10 seconds it will wake up and show the same value 3 times

The following example works.




static void * QStorage[256];

OS_Q myQueue;

typedef union
{float f;
void * p;
}floatunion;


void AlternateTask(void * pd)
{

float f=0.1;
while(1)
{
floatunion f_p;

OSTimeDly(3*TICKS_PER_SECOND);
f_p.f=f;
OSQPost(&myQueue, f_p.p);
f+=0.001;
}

}

/*-------------------------------------------------------------------
* UserMain
* ----------------------------------------------------------------*/
void UserMain( void *pd )
{
InitializeStack();

if ( EthernetIP == 0 )
{
iprintf( "Trying DHCP\r\n" );
GetDHCPAddress();
iprintf( "DHCP assigned the IP address of :" );
ShowIP( EthernetIP );
iprintf( "\r\n" );
}
else
{
iprintf( "Static IP address set to :" );
ShowIP( EthernetIP );
iprintf( "\r\n" );
}

OSChangePrio( MAIN_PRIO );
EnableAutoUpdate();

OSQInit(&myQueue,QStorage,(BYTE)255);

OSSimpleTaskCreate(AlternateTask,MAIN_PRIO-1);

printf("Reality check sizeof(float)=%ld sizeof(void *)= %ld and sizeof(floatunion)= %ld\r\n",sizeof(float),sizeof(void *) , sizeof(floatunion));
int n=0;
while(1)
{
BYTE err;
floatunion f_p;
err=0;
f_p.p=OSQPend(&myQueue,TICKS_PER_SECOND,&err);
if(err==OS_NO_ERR)
printf("Value of f=%g\r\n",f_p.f);
else
printf("We did not get a valid value probably timed out\r\n");
if((n++)==10)
{
iprintf("Sleeping for 10 Seconds");
OSTimeDly(10*TICKS_PER_SECOND);
n=0;
}


}



}

*******************************************Broken Example # 2 *********************************


static void * QStorage[256];

OS_Q myQueue;


void AlternateTask(void * pd)
{

float f=0.1;
while(1)
{

OSTimeDly(3*TICKS_PER_SECOND);
OSQPost(&myQueue,(void *)&f);
f+=0.001;
}

}

/*-------------------------------------------------------------------
* UserMain
* ----------------------------------------------------------------*/
void UserMain( void *pd )
{
InitializeStack();

if ( EthernetIP == 0 )
{
iprintf( "Trying DHCP\r\n" );
GetDHCPAddress();
iprintf( "DHCP assigned the IP address of :" );
ShowIP( EthernetIP );
iprintf( "\r\n" );
}
else
{
iprintf( "Static IP address set to :" );
ShowIP( EthernetIP );
iprintf( "\r\n" );
}

OSChangePrio( MAIN_PRIO );
EnableAutoUpdate();

OSQInit(&myQueue,QStorage,(BYTE)255);

OSSimpleTaskCreate(AlternateTask,MAIN_PRIO-1);

int n=0;
while(1)
{
BYTE err;
float * pF;
err=0;
pF=(float *)OSQPend(&myQueue,0,&err);
if(err==OS_NO_ERR)
printf("Value of f=%g\r\n",*pF);
else
printf("We did not get a valid value probably timed out\r\n");
if((n++)==10)
{
iprintf("Sleeping for 10 Seconds\r\n");
OSTimeDly(10*TICKS_PER_SECOND);
n=0;
}


}



}