8 Replies - 427 Views - Last Post: 10 November 2017 - 11:51 AM Rate Topic: -----

#1 tonyp12  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 31
  • Joined: 26-December 11

C Macro don't evaluate a enum

Posted 09 November 2017 - 11:51 AM

I want the user to have just name the tasks in a enum in common.h and once as a define in each task
Each task can also then just refer to itself as "this"
The code below works as "this" is hardcoded as zero.
But not if I do #define this blinkled1
TaskFuncX macro insert the name and not 0

#include "em_gpio.h"
#include "common.h"

//#define this blinkled1  
#define this 0
#define taskname2(x) TaskFunc ## x
#define taskname1(x) taskname2(x)
#define TaskFuncX taskname1(this)


void TaskFuncX (void)
{
  GPIO_PinOutToggle(gpioPortC,10);
  OS_sleep(this,5000);
}

This post has been edited by tonyp12: 09 November 2017 - 11:54 AM


Is This A Good Question/Topic? 0
  • +

Replies To: C Macro don't evaluate a enum

#2 tonyp12  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 31
  • Joined: 26-December 11

Re: C Macro don't evaluate a enum

Posted 09 November 2017 - 12:22 PM

This is so I can use a repeat macro for below jump-to-subroutines table
so 2nd question is: How would I do this repeat? as I want unrolled loop
enum tasknames{
	blinkled1,
	blinkled2,
	TaskListEnd,
};


 while (1) {			   	           // Infinite main loop
    if (!eventset) EMU_EnterEM2(false);  // go to sleep
    uint32_t temp = eventset;		     // atomic way to copy & clear
    eventdo = temp;
    eventset &= ~temp;

    if (eventdo & 1<<0) TaskFunc0();
    if (eventdo & 1<<1) TaskFunc1();
    if (eventdo & 1<<2) TaskFunc2();
    if (eventdo & 1<<3) TaskFunc3();
    if (eventdo & 1<<4) TaskFunc4();
    if (eventdo & 1<<5) TaskFunc5();

  }

This post has been edited by tonyp12: 09 November 2017 - 12:37 PM

Was This Post Helpful? 0
  • +
  • -

#3 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5895
  • View blog
  • Posts: 20,125
  • Joined: 05-May 12

Re: C Macro don't evaluate a enum

Posted 09 November 2017 - 01:24 PM

That is correct. Macros are preprocessor things. Enum values are compiler things. The preprocessor runs before the compiler. Furthermore, the preprocessor ## operator is a concatenation operator which takes the string literally. It doesn't do any expansion on it even if the string might be another macro.
Was This Post Helpful? 0
  • +
  • -

#4 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1852
  • View blog
  • Posts: 6,661
  • Joined: 19-February 09

Re: C Macro don't evaluate a enum

Posted 09 November 2017 - 02:13 PM

So the position of the value in the enum corresponds to the task to be performed.

The index corresponding to the event value can be passed to a function
 if (eventdo & 1<<1 ) OnEventTaskFunctions(1);



In the function if the passed index value equals blinked1 then the blinked1 function can be run.
Was This Post Helpful? 0
  • +
  • -

#5 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5895
  • View blog
  • Posts: 20,125
  • Joined: 05-May 12

Re: C Macro don't evaluate a enum

Posted 10 November 2017 - 07:19 AM

As an aside, naming your functions TaskFunc0(), TaskFunc0(), etc. is really a poor idea. It would actually be better to name them TaskFuncBlinkLed1(), TaskFuncBlinkLed2(), etc. ... which incidentally is exactly what the ## operator ends up doing in:
#define DoTask(task) TaskFunc ## task


Was This Post Helpful? 0
  • +
  • -

#6 tonyp12  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 31
  • Joined: 26-December 11

Re: C Macro don't evaluate a enum

Posted 10 November 2017 - 09:01 AM

As I want a unroll macro in main for eventdo
More than one bit in event can be set,
so check each bit and jump to routine without pushing any data to stack is what is really wanted.

So that stops me from using the tasks real names

Something like this:

REPEAT TaskListEnd X
if (eventdo & 1<< X) TaskFunc ## X();

As I want a unroll macro in main for eventdo
More than one bit in event can be set,
so check each bit and jump to routine without pushing any data to stack is what is really wanted.

So that stops me from using the tasks real names

Something like this:

REPEAT TaskListEnd X // won't work as TaskListEnd is a enum
if (eventdo & 1<< X) TaskFunc ## X();

This post has been edited by tonyp12: 10 November 2017 - 09:01 AM

Was This Post Helpful? 0
  • +
  • -

#7 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5895
  • View blog
  • Posts: 20,125
  • Joined: 05-May 12

Re: C Macro don't evaluate a enum

Posted 10 November 2017 - 10:43 AM

Unrolling loops is not a function of the pre-processor, nor technically the front end of the compiler. It is the optimizer for the compiler as it starts to generate the assembly op codes that can choose to unroll any loops.

What is this "REPEAT" macro that you are talking about?

Anyway for the code from your OP, why not something like this where you unroll the loop yourself?
#define DoIf(eventdo, flag) if (eventdo & (1 << flag)) TaskFunc##flag()

enum EventDoFlags {
    BlinkLed1,
    BlinkLed2,
    TurnOnMotor1,
    CloseSwitch2,
    SetLCD0,
    SetLCD1,
}

void TaskFuncBlinkLed1() {
    :
}

void TaskFuncBlinkLed2() {
    :
}

void TaskFuncTurnOnMotor1() {
    :
}

void TaskFuncCloseSwitch2() {
    :
}

void TaskFuncSwitchLCD0() {
    :
}

void TaskFuncSwitchLCD1() {
    :
}


:
while (1) {			   	           // Infinite main loop
    if (!eventset)
        EMU_EnterEM2(false);  // go to sleep

    uint32_t temp = eventset;		     // atomic way to copy & clear
    eventdo = temp;
    eventset &= ~temp;

    DoIf(eventdo, BlinkLed1);
    DoIf(eventdo, BlinkLed2);
    DoIf(eventdo, TurnOnMotor1);
    DoIf(eventdo, CloseSwitch2);
    DoIf(eventdo, SetLCD0);
    DoIf(eventdo, SetLCD1);
}


Was This Post Helpful? 1
  • +
  • -

#8 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1852
  • View blog
  • Posts: 6,661
  • Joined: 19-February 09

Re: C Macro don't evaluate a enum

Posted 10 November 2017 - 11:33 AM

View Posttonyp12, on 10 November 2017 - 05:01 PM, said:

As I want a unroll macro in main for eventdo

You want this? They look complicated.

Quote

More than one bit in event can be set,
so check each bit and jump to routine without pushing any data to stack is what is really wanted.

Or do you want this?

What about an array of function pointers instead of the enum?
Was This Post Helpful? 0
  • +
  • -

#9 tonyp12  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 31
  • Joined: 26-December 11

Re: C Macro don't evaluate a enum

Posted 10 November 2017 - 11:51 AM

As this is for a cooperative multitask system, and I don't what the user to edit things in main.c
Just import the OS and start adding the c file template as tasks and add their names to the enum taskname in common.h

OS_sleep(taskid,ms) is already working where the real-time-counter wakes up for next nearest time, there is 1ms to year2138 range.
eg a non-greatest-common denominator time scheduler.

I could add task names a define's, but enum auto-count is better.
So 0 to 31 refers to both bit location in uints32 event... and also as taskstruct[x] offsets

Maybe I need to create precompile program anyway, as I notice that forward reference to state names in the task switch/case state-machine is not possible.

This post has been edited by tonyp12: 10 November 2017 - 12:01 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1