The queue examples that I've seen send strings as messages. Can I send integers or enums instead?
I have an enum called 'commands', I'd like to have several tasks send 'commands' to UserMain(). I've tried this:
enum commands{ SETUP_FOV_CMD, SETUP_FOCUS_CMD, SETUP_MIRROR_CMD, SETUP_PADDLE_CMD, ...
A task:
void TouchScreenServer(void*){
iprintf( "Starting TouchScreenServer.\r\n" );
commands TSCommand = NOTHING_CMD;
while (true){
char key = TS.Key();
if (WFOVButton.Hit(key)){
TSCommand = WIDE_CMD;
...
OSQPost(&CommandQueue, (void *)TSCommand);
}
} // end of TouchScreenServer
in UserMain :
...
commands Command = NARROW_CMD;
iprintf("Ready...\n");
while(true){
commands* pc = (commands *)OSQPend(&CommandQueue, 0, &QueueError);
Command = *pc;
iprintf("Working...");
switch (Command) {
// FOV commands follow
case WIDE_CMD :
...
This will compile, but hangs when the OSQPend unblocks (never prints "Working ..."). The hardware needs a hard reset to respond to the ID after this. I suspect I've gotten my pointers tangled up.
I think I'm missing something fundamental here, does anyone have an example of passing a non-char* message in a uCos OSQue?
Netburner MFC5234. Eclipse
Thanks,
Sam
Sending enums as messages in a uCos OSQue
Re: Sending enums as messages in a uCos OSQue
The error is mixing enum with pointer to enum.
The sent value is enum:
enum commands{ SETUP_FOV_CMD, SETUP_FOCUS_CMD, SETUP_MIRROR_CMD, SETUP_PADDLE_CMD, ...
...
commands TSCommand = NOTHING_CMD;
...
OSQPost(&CommandQueue, (void *)TSCommand);
but the received value is pointer to enum:
commands* pc = (commands *)OSQPend(&CommandQueue, 0, &QueueError);
Try to replace above line with
commands pc = (commands)OSQPend(&CommandQueue, 0, &QueueError);
________________
The sent value is enum:
enum commands{ SETUP_FOV_CMD, SETUP_FOCUS_CMD, SETUP_MIRROR_CMD, SETUP_PADDLE_CMD, ...
...
commands TSCommand = NOTHING_CMD;
...
OSQPost(&CommandQueue, (void *)TSCommand);
but the received value is pointer to enum:
commands* pc = (commands *)OSQPend(&CommandQueue, 0, &QueueError);
Try to replace above line with
commands pc = (commands)OSQPend(&CommandQueue, 0, &QueueError);
________________
barttech wrote:The queue examples that I've seen send strings as messages. Can I send integers or enums instead?
I have an enum called 'commands', I'd like to have several tasks send 'commands' to UserMain(). I've tried this:
enum commands{ SETUP_FOV_CMD, SETUP_FOCUS_CMD, SETUP_MIRROR_CMD, SETUP_PADDLE_CMD, ...
A task:
void TouchScreenServer(void*){
iprintf( "Starting TouchScreenServer.\r\n" );
commands TSCommand = NOTHING_CMD;
while (true){
char key = TS.Key();
if (WFOVButton.Hit(key)){
TSCommand = WIDE_CMD;
...
OSQPost(&CommandQueue, (void *)TSCommand);
}
} // end of TouchScreenServer
in UserMain :
...
commands Command = NARROW_CMD;
iprintf("Ready...\n");
while(true){
commands* pc = (commands *)OSQPend(&CommandQueue, 0, &QueueError);
Command = *pc;
iprintf("Working...");
switch (Command) {
// FOV commands follow
case WIDE_CMD :
...
This will compile, but hangs when the OSQPend unblocks (never prints "Working ..."). The hardware needs a hard reset to respond to the ID after this. I suspect I've gotten my pointers tangled up.
I think I'm missing something fundamental here, does anyone have an example of passing a non-char* message in a uCos OSQue?
Netburner MFC5234. Eclipse
Thanks,
Sam
Yevgeni Tunik
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
Re: Sending enums as messages in a uCos OSQue
Thanks yevgenit,
The uCos OS_Q is a queue of void pointers, so OSQPend returns a void pointer,
void * OSQPend( OS_Q * pq, WORD timeout, BYTE * err );
so when I tried your suggestion I get:
error: invalid cast from type 'void*' to type 'commands'
I think where I'm confused is what it is that the queue holds. It holds pointers to "messages", but do these messages always have to be strings? When I "post an enum to the queue", I am really posting it's pointer, I post (void *)TSCommand to the queue. If I try to just put the TSCommand in, I get a compile error, "can't convert type 'commands' to type 'void*'".
So are the queue elements pointers to TSCommand, (or whatever other 'commands' type variable I have placed in the queue)?
How do I get the value of TSCommands that was placed in the queue back out?
The Post/Pend aspect of the queue is working nicely for me, the main task blocks until I post to the queue. If I just make TSCommands global I can access it from any task, but then I only get the current value, there is no queueing of the values.
Thanks?
Sam
The uCos OS_Q is a queue of void pointers, so OSQPend returns a void pointer,
void * OSQPend( OS_Q * pq, WORD timeout, BYTE * err );
so when I tried your suggestion I get:
error: invalid cast from type 'void*' to type 'commands'
I think where I'm confused is what it is that the queue holds. It holds pointers to "messages", but do these messages always have to be strings? When I "post an enum to the queue", I am really posting it's pointer, I post (void *)TSCommand to the queue. If I try to just put the TSCommand in, I get a compile error, "can't convert type 'commands' to type 'void*'".
So are the queue elements pointers to TSCommand, (or whatever other 'commands' type variable I have placed in the queue)?
How do I get the value of TSCommands that was placed in the queue back out?
The Post/Pend aspect of the queue is working nicely for me, the main task blocks until I post to the queue. If I just make TSCommands global I can access it from any task, but then I only get the current value, there is no queueing of the values.
Thanks?
Sam
Re: Sending enums as messages in a uCos OSQue
The following tested example shows using message with integer value.
The identical integer representation of both integer and any pointer is assumed.
Such assumption is true for most(?) 32-bit architectures.
______ Start of example____
// Modified example of "NetBurner's uC/OS RTOS Library - 2.18 OSQInit".
#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <smarttrap.h>
#include <taskmon.h>
#include <NetworkDebug.h>
extern "C" {
void UserMain(void * pd);
}
const char * AppName="post_integer";
OS_Q MyQueue;
void task_dst(void*)
{
BYTE err;
iprintf("Ready to receive messages...\n");
while(true)
{
void * pData = OSQPend( &MyQueue, 0, &err );
iprintf("Received message: %d\n", (int)pData );
}
}
const int NUM_ELEMENTS = 3;
void * MyQueueStorage[NUM_ELEMENTS];
void UserMain(void * pd)
{
InitializeStack();
OSChangePrio(MAIN_PRIO);
EnableAutoUpdate();
EnableTaskMonitor();
#ifndef _DEBUG
EnableSmartTraps();
#endif
#ifdef _DEBUG
InitializeNetworkGDB_and_Wait();
#endif
iprintf("Application started\n");
OSQInit( &MyQueue, MyQueueStorage, NUM_ELEMENTS );
static int count;
OSSimpleTaskCreate( task_dst, MAIN_PRIO+10 );
OSTimeDly(1*TICKS_PER_SECOND);
iprintf( "Starting to send messages.\n" );
while (1)
{
OSTimeDly(2*TICKS_PER_SECOND);
for( int i=0; i<NUM_ELEMENTS; i++)
{
iprintf("Sent message: %d\n", count );
OSQPost( &MyQueue, (void *)count );
count++;
}
}
}
______ End of example____
The identical integer representation of both integer and any pointer is assumed.
Such assumption is true for most(?) 32-bit architectures.
______ Start of example____
// Modified example of "NetBurner's uC/OS RTOS Library - 2.18 OSQInit".
#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <smarttrap.h>
#include <taskmon.h>
#include <NetworkDebug.h>
extern "C" {
void UserMain(void * pd);
}
const char * AppName="post_integer";
OS_Q MyQueue;
void task_dst(void*)
{
BYTE err;
iprintf("Ready to receive messages...\n");
while(true)
{
void * pData = OSQPend( &MyQueue, 0, &err );
iprintf("Received message: %d\n", (int)pData );
}
}
const int NUM_ELEMENTS = 3;
void * MyQueueStorage[NUM_ELEMENTS];
void UserMain(void * pd)
{
InitializeStack();
OSChangePrio(MAIN_PRIO);
EnableAutoUpdate();
EnableTaskMonitor();
#ifndef _DEBUG
EnableSmartTraps();
#endif
#ifdef _DEBUG
InitializeNetworkGDB_and_Wait();
#endif
iprintf("Application started\n");
OSQInit( &MyQueue, MyQueueStorage, NUM_ELEMENTS );
static int count;
OSSimpleTaskCreate( task_dst, MAIN_PRIO+10 );
OSTimeDly(1*TICKS_PER_SECOND);
iprintf( "Starting to send messages.\n" );
while (1)
{
OSTimeDly(2*TICKS_PER_SECOND);
for( int i=0; i<NUM_ELEMENTS; i++)
{
iprintf("Sent message: %d\n", count );
OSQPost( &MyQueue, (void *)count );
count++;
}
}
}
______ End of example____
barttech wrote:Thanks yevgenit,
The uCos OS_Q is a queue of void pointers, so OSQPend returns a void pointer,
void * OSQPend( OS_Q * pq, WORD timeout, BYTE * err );
so when I tried your suggestion I get:
error: invalid cast from type 'void*' to type 'commands'
I think where I'm confused is what it is that the queue holds. It holds pointers to "messages", but do these messages always have to be strings? When I "post an enum to the queue", I am really posting it's pointer, I post (void *)TSCommand to the queue. If I try to just put the TSCommand in, I get a compile error, "can't convert type 'commands' to type 'void*'".
So are the queue elements pointers to TSCommand, (or whatever other 'commands' type variable I have placed in the queue)?
How do I get the value of TSCommands that was placed in the queue back out?
The Post/Pend aspect of the queue is working nicely for me, the main task blocks until I post to the queue. If I just make TSCommands global I can access it from any task, but then I only get the current value, there is no queueing of the values.
Thanks?
Sam
Yevgeni Tunik
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
Re: Sending enums as messages in a uCos OSQue
void * is the compiler way of saying I'm reserving a 32 bit block of stuff, I have no idea what you are going to put in there.
So with proper casting any int or enum can be conveted to/from a void *.
enum an_enum {A,B,C};
void * pV;
an_enum x;
x=A;
//Cast to void *
pV=(void *)x;
//Cast back to enum.
x=(an_enum)pV;
So with proper casting any int or enum can be conveted to/from a void *.
enum an_enum {A,B,C};
void * pV;
an_enum x;
x=A;
//Cast to void *
pV=(void *)x;
//Cast back to enum.
x=(an_enum)pV;
Re: Sending enums as messages in a uCos OSQue
Thanks pbreed,
Maybe this a compiler issue. When I try your suggestion, which was what yevgenit said also, I get:
error: invalid cast from type 'void*' to type 'commands'
If I first cast to int, then cast to my enum 'commands', it works (ie compiles AND behaves) fine:
int *pc = (int*)OSQPend(&CommandQueue, 0, &QueueError);
Command = (commands)(int)pc;
The error messages I've been getting make it look like the compiler treats enums as pointers, not like the ints I expected.
I think of enums as a subset of ints, so this compiler behavior seems odd to me.
I think this is as clean as I'm going to get it w/o making a Queue for enums myself.
Sam
Maybe this a compiler issue. When I try your suggestion, which was what yevgenit said also, I get:
error: invalid cast from type 'void*' to type 'commands'
If I first cast to int, then cast to my enum 'commands', it works (ie compiles AND behaves) fine:
int *pc = (int*)OSQPend(&CommandQueue, 0, &QueueError);
Command = (commands)(int)pc;
The error messages I've been getting make it look like the compiler treats enums as pointers, not like the ints I expected.
I think of enums as a subset of ints, so this compiler behavior seems odd to me.
I think this is as clean as I'm going to get it w/o making a Queue for enums myself.
Sam
Re: Sending enums as messages in a uCos OSQue
Thanks yevgenit,
Your example got me over the hump. I'm not sure why, but if I cast to int first, then cast to my enum 'commnds', I get the desired operation from the OSQueue:
int *pc = (int*)OSQPend(&CommandQueue, 0, &QueueError);
Command = (commands)(int)pc;
Thanks for your comprehensive example!
Sam
Your example got me over the hump. I'm not sure why, but if I cast to int first, then cast to my enum 'commnds', I get the desired operation from the OSQueue:
int *pc = (int*)OSQPend(&CommandQueue, 0, &QueueError);
Command = (commands)(int)pc;
Thanks for your comprehensive example!
Sam