Hamad B
Hamad B

Reputation: 46

Functions vs Queues vs Global Variables in C

This question is more about what in your opinion is most efficient for embedded systems running C with RTOS.

I have a task that only updates a variable every period. This variable is used in other tasks in the program:

TaskA.c

int someVar = 0

void TaskFunc(void) {
    updateVar(someVar);
}

The other tasks in the application are not blocked waiting for this variable, so that tells me that a FreeRTOS queue might be more than needed. It is more of a global variable like reading time.

So the other option is to have an extern to this variable in the header file.

TaskA.h

extern int someVar;

I am hesitant to do this since global variables are usually not advised. So what if I added a function and have that be global instead?

So TaskA.c would change to:

static int someVar;

void TaskFunc(void) {
    updateVar(someVar);
}

void readVar(int *reader){
    *reader = someVar;
}

And TaskA.h:

void readVar(int *reader);

Then I can call readVar from any other tasks running in the program to read the static variable in TaskA.c . Is the use of a pointer here doing more harm than good versus just returning someVar?

Are there drawbacks to this that I am not seeing, or am I just overthinking it? Specifically asking for embedded systems if that makes a difference in this case.

Appreciate the feedback!

Upvotes: 2

Views: 1297

Answers (2)

WITC
WITC

Reputation: 329

You can use taskENTER_CRITICAL()/taskEXIT_CRITICAL to make it safe when reading or writing to global variable. In my case I always try to solve it with queues. Also you can create Var1 in Task 1 (not global), get its pointer (of Var1) and then pass this pointer to the Task2 by using Queue. In that way you can read Var1 in Task2 (but again do not forget to make it Atomic, vTaskSuspendAll/xTaskResumeAll() is enough if you wil not read or write it in IRQ )

Upvotes: 1

bigwillydos
bigwillydos

Reputation: 1371

This question is more about what in your opinion is most efficient for embedded systems running C with RTOS.

Well, I don't believe we are supposed to give opinions here so I'll actually do my best not to.

I am hesitant to do this since global variables are usually not advised

I would be too because having this need is usually a failure to properly encapsulate data. But if you have good reason for doing something like this, then by all means do it.

Is the use of a pointer here doing more harm than good versus just returning someVar?

You could just return someVar as was pointed out in the comments (no pun intended).

int readVar(void){
    return someVar;
}

Then do int reader = readVar();

But for what you did:

void readVar(int *reader){
    *reader = someVar;
}

The pointer is needed. C passes by value and not by reference so if you just passed int reader you are passing a copy of the value of reader so reader = someVar; would be modifying the value of the copy. What your code does is passes a copy of the value of the memory location for reader then writes the value of someVar to that memory location.

Are there drawbacks to this that I am not seeing, or am I just overthinking it?

I don't see any issue with you thinking critically about a design choice like this. You didn't list any drawbacks about this approach so its hard for us to tell what you are not seeing. Furthermore, we lack critical context regarding your specific embedded system. Overall, speaking generally, I'd say implementing proper data encapsulation is a good design choice.

Upvotes: 1

Related Questions