In the type of embedded programming that I enter, the determinism and transparency of running code are much appreciated. What I mean by transparency is, for example, the ability to browse through arbitrary sections of memory and know which variable is stored there. Therefore, as I am sure, embedded programmers expect that the new should be avoided, if at all possible, and if it cannot be avoided, then it is limited to initialization.
I understand the need for this, but I disagree with how my colleagues have already done this, and I do not know a better alternative.
We have several global arrays of structures and some global classes. There is one array of structures for mutexes, one for semaphores and one for message queues (they are initialized mainly). For each thread that runs, the class that owns it is a global variable.
The biggest problem I am facing is unit testing. How can I insert a mock object when the class I want to check for #include global variables that I don't have?
Here's the situation in the pseudo code:
foo.h
#include "Task.h" class Foo : Task { public: Foo(int n); ~Foo(); doStuff(); private:
bar.h
#include <pthread.h> #include "Task.h" enum threadIndex { THREAD1 THREAD2 NUM_THREADS }; struct tThreadConfig { char *name, Task *taskptr, pthread_t threadId, ... }; void startTasks();
bar.cpp
#include "Foo.h" Foo foo1(42); Foo foo2(1337); Task task(7331); tThreadConfig threadConfig[NUM_THREADS] = { { "Foo 1", &foo1, 0, ... }, { "Foo 2", &foo2, 0, ... }, { "Task", &task, 0, ... } }; void FSW_taskStart() { for (int i = 0; i < NUMBER_OF_TASKS; i++) { threadConfig[i].taskptr->createThread( ); } }
What if I want more or less tasks? Different set of arguments in foo1 constructor? I think I will have to have a separate bar.h and bar.cpp, which seems a lot more work than necessary.