Why is my FreeRTOS task not seeing the class members? - c++

I'm trying to understand FreeRTOS building a C++ class which contains a LED blinking task. But in the task body (which is also a class member), other class members i.e. LED1_delay are empty/not-initialized. It seems like the task body was linked to another instance.
Class function which sets the blinking frequency and starts the task: (gpio.cpp)
void c_gpio::LED_blink_on(float frequency){
LED1_delay=(uint32_t)(1000/frequency);
if(LEDTaskcreated!=true){
//Create task
LEDTaskHandle = osThreadNew(startTask_LED1_blinker, LEDTask_args, &LEDTask_attributes);
LEDTaskcreated=true;
}
}
Wrapper function avoiding static declaration: (gpio.cpp)
void c_gpio::startTask_LED1_blinker(void* _this){
static_cast<c_gpio*>(_this)->taskbody_LED1_blinker((void*)0);
}
Task body: (gpio.cpp)
void c_gpio::taskbody_LED1_blinker(void* arguments){
//All class members are uninitialized here..
while(1)
{
HAL_GPIO_TogglePin(GP_LED_1_GPIO_Port,GP_LED_1_Pin);
osDelay(this->LED1_delay); //LED1_delay is not set.
}
}
Class declaration (gpio.hpp)
class c_gpio{
public:
void LED_blink_on(uint8_t LED_id, float frequency);
private:
static void startTask_LED1_blinker(void* _this);
void taskbody_LED1_blinker(void *arguments);
uint32_t LED1_delay;
//Task handles & attributes
osThreadId_t LEDTaskHandle;
osThreadAttr_t LEDTask_attributes;
uint16_t LEDTask_args[2];
};
Instantiation (main.cpp)
#include "gpio.hpp"
c_gpio gpio;
int main(void)
{
gpio.LED_blink_on(1,10);
/* Init scheduler */
osKernelInitialize();
/* Start scheduler */
osKernelStart();
}
I thought, the members taskbody_LED1_blinker() and LED1_delay are belonging to the same instance. But this doesn't seem to be so. Why? How to properly construct such a task?

Problem:
You have used the class object "gpio" for setting the blicking frequency. meaning the blinking frequency is updated inside the gpio object . Whereas "startTask_LED1_blinker" is a static method of a class which is not bound to any object
Solution:
Take advantage of the "arguments" to the task body function startTask_LED1_blinker. You can send 'this' pointer to the osThreadNew instead of LEDTask_args and then use that pointer to invoke task body "taskbody_LED1_blinker". Correction in your code for reference
void c_gpio::taskbody_LED1_blinker(void* arguments){
//All class members are uninitialized here..
while(1)
{
HAL_GPIO_TogglePin(GP_LED_1_GPIO_Port,GP_LED_1_Pin);
osDelay(LED1_delay); //LED1_delay is not set.
}
}
void c_gpio::LED_blink_on(float frequency){
LED1_delay=(uint32_t)(1000/frequency);
if(LEDTaskcreated!=true){
//Create task
LEDTaskHandle = osThreadNew(startTask_LED1_blinker, this, &LEDTask_attributes);
LEDTaskcreated=true;
}
}

Related

How to declare a class member that may be one of two classes

I am working with a project that is largely not of my creation, but am tasked with adding in some functionality to it. Currently, there is a device class that has a member variable that is responsible for storing information about a storage location, setup like this:
device.hpp
class device {
public:
// Stuff
private:
// Stuff
StorageInfo storage_info_;
// Even more stuff
}
StorageInfo.hpp
class StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
I am tasked with implementing a different storage option so that the two can be switched between. The information functions that this new storage option has would be the same as the initial storage option, but the implementation in retrieving that information is vastly different. In order to keep things clean and make it easier to maintain this application for years to come, they really need to be defined in two different files. However, this creates an issue inside of device.cpp, and in every single other file that calls the StorageInfo class. If I create two separate member variables, one for each type of storage, then not only will I need to insert a million different ifelse statements, but I have the potential to run into initialization issues in the constructors. What I would instead like to do is have one member variable that has the potential to hold either storage option class. Something like this:
StorageInfoA.hpp
class StorageInfoA: StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
StorageInfoB.hpp
class StorageInfoB: StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
device.hpp
class device {
public:
// Stuff
private:
// Stuff
StorageInfo storage_info_;
// Even more stuff
}
device.cpp
//Somewhere in the constructor of device.cpp
if(save_to_cache){
storage_info_ = StorageInfoA();
} else {
storage_info_ = StorageInfoB();
}
// Then, these types of calls would return the correct implementation without further ifelse calls
storage_info_.updateStorageInfo();
However, I know that cpp absolutely hates anything with dynamic typing, so I don't really know how to implement this. Is this kind of thing even possible? If not, does anyone know of a similar way to implement this that does work with cpp's typing rules?
You are on the right track, but you have to learn how to use polymorphism. In your example, you need the following fixes:
In the base class, make all functions virtual, and add a virtual
destructor:
class StorageInfo {
public:
virtual ~StorageInfo(){}
virtual void initializeStorage();
//...
};
Make your inheritance public:
class StorageInfoA: public StorageInfo {
Instead of holding StorageInfo by value, hold it in a smart pointer:
class device {
private:
std::unique_ptr<StorageInfo> storage_info_;
};
device constructor will look like
//Somewhere in the constructor of device.cpp
if(save_to_cache){
storage_info_ = std::make_unique<StorageInfoA>();
} else {
storage_info_ = std::make_unique<StorageInfoB>();
}
Finally, you will use it like an ordinary pointer:
storage_info_->updateStorageInfo();

C++ design for init static members, any time required

I'm developing a little game engine for Android with Android NDK and opengl es 2.0, recently the project is getting big, and I need to refactor some code, and I couldn't find a proper design pattern for the next problem.
On android when the app reach the OnPause() state the opengl context is destroyed, but the state of the variables and objects in java and c++ are maintained. so each time the player pauses and resumes the app I have to reinitializate the opengl part, buffers, shaders, vertex, etc.
I have classes like "Square" that makes "square objects", and each one has its own attributes, and each "square object" can be drawn, so the squares can access to static (opengl) members of the class, that are used to be properly rendered. So this static members must be initialized before objects can be drawn, I do it when the opengl context is created or recreated.
moreover each class has its own opengl attributes, so each class is initialized individually with its own parameters, so I want a design in what each class can set some initial parameters, pass or catch those parameters to initialize the static members of the class (I forgot to say that these parameters are private). But as I said before, these parameters need to be reinitialized each time the app is resumed.
currently I initialize these members individually like
Square::init(/*hardcoded parameters*/);
Circle::init(/*hardcoded parameters*/);
Triangle::init(/*hardcoded parameters*/);
Polygon::init(/*hardcoded parameters*/);
Shape::init(/*hardcoded parameters*/);
.
.
.
.
// Many other inits.....
.
and I want to write something like
// here all the classes with opengl part are initialized
// all init methods of each class are called here, with their respective parameters
Opengl_Initializer::init(); // <--- magic way, no other init calls
So I want to set some (static/harcoded) variables to the class and then when the opengl context be created, the class be initialized in a "magic" way, and not having the need to code the call to an init method for each class.
I've tried to use inheritance, but the issue is that I need to initialize the class not the object, also tried to implement a static object and initialize this object in the cpp file, and store a pointer to the object in a vector when this is created in his contructor, in a vector that is in the object's own class, but this design has gave me many problems.
Does anyone know some design that can help me?
EDIT: the stucture of my classes
the init() function is really big because shader and frag parameters are paths file and I perform some task on them, pass the result of that perform to opengl and returns me a ID that is the program static variable, all clases with opengl part implement this same process, the parameter camera is just to attach it into a camera
class Square {
// static variable all classes have
static GLuint program;
// other glparameters not in common, initialized in the same static init() method
static GLint uniform1;
static GLint uniform2;
public;
// the static init function has the same header on all the classes
static init(const char* shader, const char* frag, const char *camera);
}
and maybe some structure I'd want is
class Square {
static GLuint program;
static const char *vertex = "hardcode";
static const char *frag = "hardcode";
static const char *cam = "harcode";
static init();
/// or somethig like
static Initializer init(
"harcode shader", "hardcode frag", "hardcode camera",
[&] (void) ->void {
//this is the init function
}
);
public:
}
This is one more solution how your task can be solved. The idea is to have some initialization list (std::vector) of functions that should be called in yout Opengl_Initializer::init() :
std::vector<std::function<void()>> initializer_list;
If we can put all your Square/Circle/Triangle... init functions into this list, your task become trivial - just iterate list and call all functions:
// inside Opengl_Initializer::init()
for (auto fn : initializer_list)
fn();
You can add functions manually, for example, from int main():
initializer_list.push_back(&Square::init);
...
But I suggest that you need some arhitecture design that will make you able adding functions into initializer list without changing main or any other global code.
To solve this task we can make small helper class that will register your init functions automatically:
struct OpenGLHelper_initializer
{
OpenGLHelper_initializer(std::function<void()> fn)
{
initializer_list.push_back(fn);
}
};
So you can declare instance of this class in your Square/Circle:
struct Square
{
static OpenGLHelper_initializer __initializer;
};
And in your Square.cpp file:
OpenGLHelper_initializer Square::__initializer(&Square::init);
So, when program loads, all this initializer will be constructed and all your "init" function will be registered into initializer_list.
This looks like more code, but it will make you able to add as many shapes as you need without changing Opengl_Initializer::init(); or main.cpp or any other global code
Your can now remove init functions, if you dont like them and use lambdas:
// in square.cpp
OpenGLHelper_initializer Square::__initializer([](){
std::cout << "Square is initialized now" << std::endl;
});
Here is complete source code (Updated with using static function) (but without cpp files - all in one):
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
/////////////////////////////////////////
// opengl_helper.h
// this is some manager class that knows what should be initialized later
struct OpenGLHelper
{
typedef std::function<void()> function_type;
static std::vector<function_type>& get_initialization_list();
static void register_initializer(function_type fn);
static void run_init();
};
// helper class that will register some function at construction time
struct OpenGLHelper_initializer
{
OpenGLHelper_initializer(OpenGLHelper::function_type fn)
{
OpenGLHelper::register_initializer(fn);
}
};
/////////////////////////////////////////
//opengl_helper.cpp
// using this function we will make our initializer_list be constructued
// before adding anything into it
std::vector<OpenGLHelper::function_type>& OpenGLHelper::get_initialization_list()
{
static std::vector<function_type> initializer_list;
return initializer_list;
}
// function that puts initializer into a list.
void OpenGLHelper::register_initializer(OpenGLHelper::function_type fn)
{
get_initialization_list().push_back(fn);
}
void OpenGLHelper::run_init()
{
for (auto fn : get_initialization_list())
fn();
}
/////////////////////////////////////////
// figure.h
// here is sample class that will be registered for initialization
struct Square
{
static int to_be_initialized;
// static member that will register Square class to be initialized
static OpenGLHelper_initializer __initializer;
};
/////////////////////////////////////////
// Square.cpp
int Square::to_be_initialized = 0;
// this is the most interesting part - register square into initializer list
OpenGLHelper_initializer Square::__initializer([](){
Square::to_be_initialized = 15;
std::cout << "Called Square::init: " << to_be_initialized << std::endl;
});
int main()
{
std::cout << "Before initialization : " << Square::to_be_initialized << std::endl;
OpenGLHelper::run_init();
std::cout << "After initialization : " << Square::to_be_initialized << std::endl;
return 0;
}
Output:
Before initialization : 0
Called Square::init: 15
After initialization : 15
Live test
BTW, such way of initialization is used by QT's metatype system - it uses macros to simplify code
UPDATE:
As Ben suggested, we can eliminate small memory leak from bynamic link allocation if we will put initialization list into a static function. Here is new code
I suggest a versioning system, so that initialization can be automatically performed at time-of-use, but in a way that skips it very cheaply when the initialization has already been done. Something like
int global_gl_generation = 0; // increment each time you recreate the context
inline bool check_gl_generation(int& local_generation)
{
if (local_generation == global_gl_generation)
return false;
local_generation = global_gl_generation;
return true;
}
and then in each class,
class Square
{
// static variable all classes have
static int generation_inited;
static GLuint program;
static GLint uniform1;
static GLint uniform2;
static init(const char* shader, const char* frag, const char *camera);
public;
void draw() override
{
if (check_gl_generation(generation_inited)) init(...);
// use program, uniform1, uniform2
}
};

Use volatile class members for interrupt handling

Lets suppose it is embedded development of some ARM controller. Lets suppose we have some variable, which can be assigned from an interrupt or "mainThread" - (is it a "main loop" or RTOS thread). In C world volatile keyword should be used in this case and code may look like this:
/* Some subsystem .C file */
static volatile uint8_t state;
void on_main_thread(void) {
state = 1; /* Changing state in this context */
}
void on_interrupt(void) {
state = 0; /* Changing state from interrupt */
}
uint8_t get_state(void) {
return state; /* Getting the state in whatever context */
}
volatile keyword is essential in this situation. Now our company rewrites some code to C++ and the same subsystem example looks like this (I use enum here to emphasize the problem)
class SomeSubsystem
{
public:
enum class States
{
Off,
Idle,
Up,
Down,
};
States getState() const { return mState; }
void onMainThread(void) {
mState = States::Idle; // Changing state in this context
}
// Somehow this function is called from the interrupt
void onInterrupt(void) {
mState = States::Up; // Changing state from interrupt
}
private:
States mState; // <-- Here! Volatile?
//...
};
Now States mState should be volatile because it is shared among different contexts. But If one sets it as volatile... Then volatile works like plague for C++ class and one have to volatilize everything around. Like volatile enum class States, getState() volatile etc. Which doesn't look good for me (am I wrong?)
So. What is the right way to handle this situation in C++?
P.S. I would try to define "this situation" as: "possible usage of a class members from different contexts like interrupts and normal code execution"
This could work if you only need a single instance of SomeSubsystem in your program (which I assume as per the c code you posted.
If you need multiple instances, then maybe you could modify mState to be a States array or some similar structure instead.
class SomeSubsystem
{
public:
enum class States
{
Off,
Idle,
Up,
Down,
};
States getState() const { return mState; }
void onMainThread(void) {
mState = States::Idle; // Changing state in this context
}
// Somehow this function is called from the interrupt
void onInterrupt(void) {
mState = States::Up; // Changing state from interrupt
}
// Make mState public in order to access it from the rest of your code
// Otherwise, keep it private and create static set/get functions
public:
static volatile States mState; // <-- Here! Volatile?
//...
};
Then define mState somewhere (eg. in SomeSubsystem.cpp)
volatile SomeSubsystem::States SomeSubsystem::mState = SomeSubsystem::States::Off;
Now you are able to access mState from anywhere in your code like this
SomeSubsystem::mState = SomeSubsystem::States::Off;
I believe you only need to volatile-qualify the methods if the class object itself is volatile. However, I don't think you should have any issues if you just make the relevant member variables volatile. I have done this successfully (i.e. it compiled/ran) on something similar to what you are trying to achieve.. E.g.:
class SomeSubsystem
{
public:
...
void onMainThread(void); // no volatile qualification necessary
void onInterrupt(void); // "
private:
States volatile mState; // only make the relevant member variables volatile
}
SomeSubsystem aSubsystem; // don't make the object volatile
...
aSubsystem.onMainThread();
aSubsystem.onInterrupt();

"Stealth" class to enclose a variable in C++

I'm currently using two identical libraries for parsing commands received in Arduino (via TCP/IP and via Serial). All the difference is in the object type being passed to the parser.
//main.cpp
SerCmd sCmd;
EthCmd eCmd;
void setup() {
sCmd.listen("#",dumpCmd);
eCmd.listen("#",dumpCmd);
}
void loop() {
HardwareSerial SerClient = Serial.available();
EthernetClient EthClient = Server.available();
eCmd.read(SerClient);
sCmd.read(EthClient);
}
//SerCmd.h
class SerCmd {
public:
void read(HardwareSerial &dataObj);
}
//EthCmd.h
class EthCmd {
public:
void read(EthernetClient &dataObj);
}
It's obvious that:
The two objects are nearly identical, and they share lots of common methods (sCmd, eCd).
The two classes (SerCmd, EthCmd) can be replaced with a single class to reduce the sketch size.
How can I create a "stealth" class which could be passed to the read() method, while still addressing any of the two different objects underneath?
What's the common practice used in such situations?
So far, I am able to compile the below code, but cannot initialize any methods:
class Communication {};
HardwareSerial *SerClient;
Communication *Comm;
void setup() {
Comm = (Communication*) SerClient;
//Comm.begin(9600);
//Error: request for member 'print' in 'Comm',
//which is of non-class type 'Communication*'
}

What's a good safe way to initialise memory for types I don't yet know about?

I started thinking about this after receiving an answer for this question. This is a bit tricky to explain, but I'll do my best.
I'm building a small(ish) 2D game engine. There are certain requirements that I need to satisfy, since this engine has to "work" with existing code that others have written for a different engine. Some change to existing code is inevitable, but I want to minimise it.
Users of my engine need to define entities called "gadgets". These are basically structs containing shapes and other state variables. These "gadgets" fall into classes, e.g. they may decide to define an icon gadget or a button gadget - or whatever.
They will also define a message handler for that class of gadgets.
E.g.
typedef struct
{
shape shapelist[5];
int num_options;
}interface;
static void interface_message_handler( interface * myself, message * msg )
{
switch( msg->type )
{
case NEW_MSG:
{
interface_descriptor * desc = msg->desc;
// initialize myself with contents of this message.
...
}
break;
....
}
}
Users have already given me the corresponding message handler function and also the number of bytes in a interface object. And they can then ask the engine to create new instances of their gadgets via IDs e.g:
engine->CreateNewGadget( interface_gadget_class_ID, welcome_interface_ID );
where interface_gadget_class_ID is the ID for that class of gadgets and welcome_interface_ID is the instance ID. At some point during CreateNewGadget I need to a) allocate memory to hold a new gadget and then call the gadget class's message handler on it, with a NEW_MSG so that it can initialize itself.
The problem is, if all I'm doing is allocating memory - that memory is uninitialized (and that means all the struct members are uninitialized - so if interface contains a vector, for example, then I'm going to get some wierd results if the message handler does anything with it ).
To avoid wierd results caused by doing stuff to unintialized memory, I really need to call a constructor for that memory as well before passing it to the gadget's message handler function.
e.g in the case of interface:
pfunc(new (memory) interface);
But my question is, if I have no knowledge of the types that users are creating, how can I do that?
// We create a typedef that refers to a function pointer
// which is a function that returns an interface pointer
typedef interface * (*GadgetFactory)(void);
// we'll actually create these functions by using this template function
// Different version of this function will produce different classes.
template<typename T>
interface * create_object()
{
return new T;
}
// This function takes care of setting everything up.
template<typename T>
void RegisterGadgetType(int gadget_type_id)
{
// Get outselves a copy of a pointer to the function that will make the object
GadgetFactory factory = create_object<T>;
// store factory somewhere
}
interface * CreateGadget(int gadget_type_id)
{
// get factory
GadgetFactory factory;
// factory will give me the actual object type I need.
return (*factory)();
}
RegisterGadgetType<S>(2);
CreateGadget(2);
as i see it, you always know because interface_gadget_class_ID defines the type to create.
you create a base c++ class: (corresponds to class interface in your example). this base class contains all of data members which are used by every interface subclass (that is, every gadget).
the base class also declares all methods common to every gadget. example: each gadget is able to receive a call handleMessage. handleMessage is pure virtual, because this method is the subclasses' role to fulfill.
then you extend/subclass to support the stuff you have to do with each gadget's specialization. at this point, you add the members and methods specific to each gadget subclass.
CreateNewGadget serves as a factory for all your subclasses, where the arguments determine which class you will create.
from there, c++ will handle construction/destruction, allocation sizes, etc..
if you're allowing plugins with their own factories in your engine, then you'll need another level, where third parties register their custom types and inherit from your base(s).
here's a simple layout of the interfaces (in non-compiled pseudo code):
namespace MONGadgets {
class t_interface {
protected:
t_interface(/* ... */);
public:
virtual ~t_interface();
/* each subclass must override handleMessage */
virtual t_result handleMessage(const t_message& message) = 0;
};
namespace InterfaceSubclasses {
class t_gadget1 : public t_interface {
public:
t_gadget1(const welcome_interface_ID& welcome);
virtual ~t_gadget1();
virtual t_result handleMessage(const t_message& message) {
std::cout << "t_gadget1\n";
}
/* gadget1 has no specific instance variables or methods to declare */
};
class t_gadget2 : public t_interface {
public:
t_gadget2(const welcome_interface_ID& welcome);
virtual ~t_gadget2();
virtual t_result handleMessage(const t_message& message) {
std::cout << "t_gadget2\n";
}
private:
/* here is an example of a method specific to gadget2: */
void drawShape(const unsigned& idx);
private:
/* here is gadget2's unique data: */
shape shapelist[5];
int num_options;
};
namespace ClassID {
enum { Gadget1 = 1, Gadget2 = 2 };
}
}
/* replaced by virtual t_result t_interface::handleMessage(const t_message&)
- static void interface_message_handler( interface * myself, message * msg );
*/
class t_gadget_factory {
public:
t_interface* CreateNewGadget(const interface_gadget_class_ID& classID, const welcome_interface_ID& welcome) {
switch (classID) {
case InterfaceSubclasses::ClassID::Gadget1 :
return new InterfaceSubclasses::gadget1(welcome);
case InterfaceSubclasses::ClassID::Gadget2 :
return new InterfaceSubclasses::gadget2(welcome);
/* ... */
}
}
};
}
Example code (ignoring my other suggestion, about factories and virtual functions):
typedef struct
{
shape shapelist[5];
int num_options;
} interface;
static void interface_message_handler( void * myself, message * msg )
{
switch( msg->type )
{
case NEW_MSG:
{
interface *self = new (myself) interface;
interface_descriptor * desc = msg->desc;
// initialize myself with contents of this message.
...
}
break;
case OTHER_MSG:
{
interface *self = static_cast<interface*>(myself);
...
}
break;
....
}
}
Then your CreateNewGadget code does:
void *ptr = malloc(some_amount);
msg newmsg;
newmsg.type = NEW_MSG;
// other fields
some_message_handler(ptr, &msg);
// now we have an initialized object, that we can add to our tree or whatever.
The less horrible version is more like this:
struct gadgetinterface {
virtual ~gadgetinterface() {}
virtual void handle_message(msg *) = 0;
};
struct mygadget : gadgetinterface {
void handle_message(msg *m) {
// no need for NEW_MSG, just do other messages
}
};
gadgetinterface *mygadget_factory(some parameters) {
// use some parameters, either passed to constructor or afterwards
return new mygadget();
}
Then we register a pointer to mygadget_factory with the gadget manager, and CreateNewGadget does this:
gadgetinterface *some_factory(some parameters); // that's it!
Where some_factory is the function pointer that was registered, so in the case of this gadget type, it points to mygadget_factory.