Pumpkin, Inc.

Pumpkin User Forums

Communication between Tasks

For issues specific to Atmel's AVR and MegaAVR microcontrollers, including Atmel AVRStudio and ImageCraft's ICCAVR C compiler.

Communication between Tasks

Postby Gerald » Wed Apr 16, 2008 2:51 am

hi,

i have 2 taks, on task is measuring some stuff and the other is doing some stuff depending on the state variable in task1!
could i just use a global variable between the 2 task? the first tasks sets the variable and the second task is reading the variable!?
or any other solution?
i dont want to use a message or stuff like that...because i dont want to block for a certain time in task2!!!!!!!

[This message has been edited by Gerald (edited April 16, 2008).]

Gerald
 
Posts: 24
Joined: Tue Mar 11, 2008 11:00 pm

Re: Communication between Tasks

Postby aek » Wed Apr 16, 2008 5:48 am

There's nothing fundamentally wrong with using global variables ... but if you do so, you should declare said variables as static within one module, and provide a function-based interface to them (E.g. read_gvars(), write_gvars(), etc.). This takes more code, but is considered cleaner and safer.

The trouble with such an approach in a multitasking system is that you cannot use changes in said (global) vars to trigger the running of the dependent task -- hence no real synchronicity.

Note that if you have bit-sized vars (flags, essentially) then you maybe can use an eFlag instead, and yu could block on the eFlag. You could have one eFlag bit be "hit" periodically by a timer to trigger a minimum "repeat rate" for the dependent task.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Communication between Tasks

Postby Gerald » Thu Apr 17, 2008 12:21 am

do you see any problems here?
i set a breakpoint to OSSetEFlag(VOLTAGE_EFLAG_P, VALID); but it never came to the breakpoint, then i stopped debugging and continued and it stops at the breakpoint...do you understand that?

code:
void TaskADC()
{
static OStypeErr err;
static unsigned int adc_value = 0;
static unsigned int channelindex = 0;
static unsigned int voltage = 0;

// enable adc measurement
bit_set(DDRC, PC1);
bit_set(PORTC, PC1);

init_adc();

for(; ;)
{
// start convertion
start_adc();
// wait for convertion finished
while(ADCSRA & (1<<ADSC));

adc_value += ((ADCH << 2) | (ADCL >> 6));

if (channelindex < (HISTORY_SIZE - 1))
{
channelindex++;
}
else
{
if(HISTORY_SIZE == 16)
{
voltage = (adc_value >> 4);

// 9V // 16V
if(voltage >= 512 && voltage <= 909)
OSSetEFlag(VOLTAGE_EFLAG_P, VALID);

adc_value = 0;
channelindex = 0;
}
}

OS_Delay(1);
}
}


void TaskFunctionLogic()
{
static OStypeErr err;
static OStypeMsgP msgP;

for(; ;)
{
OS_WaitEFlag(VOLTAGE_EFLAG_P, VALID, OSANY_BITS, OSNO_TIMEOUT);

// ... do some stuff if coltage is VALID

OSClrEFlag(VOLTAGE_EFLAG_P, INVALID);
}
}

main.c:
// start all tasks....
OSCreateEFlag(VOLTAGE_EFLAG_P, VOLTAGE_EFLAG_CB_P, INVALID);

my include files:
-----------------
-----------------
salvocfg.h:
#define OSEVENTS 5
#define OSEVENT_FLAGS 1
#define OSMESSAGE_QUEUES 0
#define OSTASKS 5

os.h:
#define MSG_... OSECBP(1)
#define MSG_... OSECBP(2)
#define MSG_... OSECBP(3)
#define MSG_... OSECBP(4)
#define VOLTAGE_EFLAG_P OSECBP(5)


#define VOLTAGE_EFLAG_CB_P OSEFCBP(1)

#define VALID 0x01
#define INVALID 0x02

#define TASK_FUNCTIONLOGIC_P OSTCBP(1) /* "" #1 */
#define TASK_... OSTCBP(2) /* "" #2 */
#define TASK_... OSTCBP(3) /* "" #3 */
#define TASK_... OSTCBP(4) /* "" #4 */
#define TASK_ADC_P OSTCBP(5) /* "" #4 */

#define PRIO_FUNCTIONLOGIC 10 /* "" */
#define PRIO_... 10 /* "" */
#define PRIO_... 10 /* "" */
#define PRIO_... 10 /* "" */
#define PRIO_ADC 10 /* "" */



You could have one eFlag bit be "hit" periodically by a timer to trigger a minimum "repeat rate" for the dependent task. ?????

[This message has been edited by Gerald (edited April 17, 2008).]

[This message has been edited by aek (edited April 17, 2008).]

Gerald
 
Posts: 24
Joined: Tue Mar 11, 2008 11:00 pm

Re: Communication between Tasks

Postby aek » Thu Apr 17, 2008 9:27 am

It's best to set a breakpoint on a NOP() or such -- some debuggers don't break well on Salvo API calls, some of which are macros.

To me, it looks like that code should work.

However, in general what I do is separate the ADC acquisition from any sampled voltage tests. I.e. I use one task to initialize the adc and average the outputs, and another periodic task to examine the results and act on them. But your approach should work as well.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Communication between Tasks

Postby Gerald » Sun Apr 20, 2008 10:41 am

// 9V // 16V
if(voltage >= 512 && voltage <= 909)
OSSetEFlag(VOLTAGE_EFLAG_P, VALID);
else
OSSetEFlag(VOLTAGE_EFLAG_P, INVALID);


void TaskFunctionLogic()
{
static OStypeErr err;
static OStypeMsgP msgP;

for(;
{
OS_WaitEFlag(VOLTAGE_EFLAG_P, VALID, OSANY_BITS, OSNO_TIMEOUT);

// ... do some stuff if coltage is VALID

OSClrEFlag(VOLTAGE_EFLAG_P, INVALID); // also did with: OSClrEFlag(VOLTAGE_EFLAG_P, INVALID);
}
}

at the first time i the eflag is invalid OS_WaitEFlag blocks! thats ok
then i set the eflag to valid...the OS_WaitEFlag doesnt block...ok too!
then i change the eflag to invlid...but the OS_WaitEFlag doesnt block
why not?

[This message has been edited by Gerald (edited April 20, 2008).]

Gerald
 
Posts: 24
Joined: Tue Mar 11, 2008 11:00 pm


Return to Atmel AVR and MegaAVR

Who is online

Users browsing this forum: No registered users and 1 guest

cron