Proper Queue usage

Discussion to talk about software related topics only.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Proper Queue usage

Post 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.
vsabino
Posts: 32
Joined: Wed May 14, 2008 8:45 am

Re: Proper Queue usage

Post 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
User avatar
pbreed
Posts: 1087
Joined: Thu Apr 24, 2008 3:58 pm

Re: Proper Queue usage

Post 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....
}
vsabino
Posts: 32
Joined: Wed May 14, 2008 8:45 am

Re: Proper Queue usage

Post 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
User avatar
pbreed
Posts: 1087
Joined: Thu Apr 24, 2008 3:58 pm

Re: Proper Queue usage

Post 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?
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Proper Queue usage

Post 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
vsabino
Posts: 32
Joined: Wed May 14, 2008 8:45 am

Re: Proper Queue usage

Post 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
User avatar
pbreed
Posts: 1087
Joined: Thu Apr 24, 2008 3:58 pm

Re: Proper Queue usage

Post 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;
}


}



}
Post Reply