How to apply the `__ramfunc` instrinsic to a constructor? - c++

I need to put all my code in ram (I'm writing the flash). I'm using IAR 7.80 and everything works fine with the __ramfunc intrinsic on every function but not for the C++ constructors.
For example I have the following class:
class Os_Timer {
private:
os_tmrcnt_t tmr;
public:
__ramfunc Os_Timer() { reset(); }
__ramfunc void reset() { os_TimerStart( &tmr ); }
};
I haven't find a way to define the constructor Os_Timer in ram. The compiler complains
expected an identifier
and
object attribute not allowed
on the constructor line.
The IAR manual says that the __ramfunc has to be placed before the return value but the constructor doesn't have a return value.
I have tried without success to force the __ramfunc behaviour:
_Pragma("location=\"section .textrw\"")
and
_Pragma("location=\"RAM_region\"")
Someone know how to do it?

To apply __ramfunc to a C++ constructor you have to use _Pragma("object_attribute=__ramfunc") as in the example below.
class Os_Timer
{
private:
os_tmrcnt_t tmr;
public:
_Pragma("object_attribute=__ramfunc") Os_Timer() { reset(); }
__ramfunc void reset() { os_TimerStart(&tmr); }
};
Note that it for this to work os_TimerStart should also be declared as __ramfunc, otherwise os_TimerStart will be placed in flash and may be overwritten by your flash update. To help you detect this the compiler will issue a warning if you try to call a function that is not declared as __ramfunc from a function that is.

Related

C++ Compile time check if a function called before another one

Lets say I have a class with two member functions.
class Dummy {
public:
void procedure_1();
void procedure_2();
};
At compile time, I want to be sure that, procedure_1 is called before procedure_2. What is the correct way do implement this?
Maybe you could do it with a proxy-class. The idea is, that procedure_2 can't be accessed directly from outside (for example by making it private). procedure_1 would return some kind of proxy that allows the access to procedure_2.
Some code below, allthough I don't consider it clean or safe. And if you want, you can still break the system.
IMO such requirements should be handled without explicit validation, because it's quite cumbersome and impossible to make it absolutely safe.
Instead, the dependency should be well documented, which also seems idiomatic in C++. You get a warning that bad things might happen if a function is used incorrectly, but nothing prevents you from shooting your own leg.
class Dummy {
private:
void procedure_2() { }
class DummyProxy
{
private:
Dummy *parent; // Maybe use something safer here
public:
DummyProxy(Dummy *parent): parent(parent) {}
void procedure_2() { this->parent->procedure_2(); }
};
public:
[[nodiscard]] DummyProxy procedure_1() {
return DummyProxy{this};
}
};
int main()
{
Dummy d;
// d.procedure_2(); error: private within this context
auto proxy = d.procedure_1(); // You need to get the proxy first
proxy.procedure_2(); // Then
// But you can still break the system:
Dummy d2;
decltype(d2.procedure_1()) x(&d2); // only decltype, function is not actually called
d2.procedure_2(); // ooops, procedure_1 wasn't called for d2
}
Instead of "checking" it, just do not allow it. Do not expose an interface that allows to call it in any other way. Expose an interface that allows to only call it in specified order. For example:
// library.c
class Dummy {
private:
void procedure_1();
void procedure_2();
public:
void call_Dummy_prodedure_1_then_something_then_produre_2(std::function<void()> f){
procedure_1();
f();
procedure_2();
}
};
You could also make procedure_2 be called from destructor and procedure_1 from a constructor.
#include <memory>
struct Dummy {
private:
void procedure_1();
void procedure_2();
public:
struct Procedures {
Dummy& d;
Procedures(Dummy& d) : d(d) { d.procedure_1(); }
~Procedures() { d.procedure_2(); }
};
// just a simple example with unique_ptr
std::unique_ptr<Dummy::Procedures> call_Dummy_prodedure_1_then_produre_2(){
return std::make_unique<Dummy::Procedures>(*this);
}
};
int main() {
Dummy d;
auto call = d.call_Dummy_prodedure_1_then_produre_2();
call.reset(); // yay!
}
The above are methods that will make sure that inside one translation unit the calls will be ordered. To check between multiple source files, generate the final executable, then write a tool that will go through the generated assembly and if there are two or more calls to that call_Dummy_prodedure_1_then_produre_2 function that tool will error. For that, additional work is needed to make sure that call_Dummy_prodedure_1_then_produre_2 can't be optimized by the compiler.
But you could create a header that could only be included by one translation unit:
// dummy.h
int some_global_variable_with_initialization = 0;
struct Dummy {
....
};
and expose the interface from above into Dummy or add only the wrapper declaration in that library. That way, if multiple souce files include dummy.h, linker will error with multiple definitions error.
As for checking, you can make prodedure_1 and procedure_2 some macros that will expand to something that can't be optimized by the compiler with some mark, like assembly comment. Then you may go through generated executable with a custom tool that will check that the call to prodedure_1 comes before procedure_2.

Segfault when trying to access function of member in a library

I have a library that is all tested thoroughly through google test suite. I am trying to keep it "pimpl" clean, but I'm running into a segfault I can't quite figure out.
Relevant Code:
Interface.h:
class Interface{
public:
Interface();
void Function(const int argument);
private:
std::unique_ptr<Implementation> Implement;
std::unique_ptr<DependencyInjection> Injection1, Injection2;
};
Interface.cpp:
Interface::Interface()
: Injection1(new DependencyInjection()),
Injection2(new DependencyInjection()),
Implement(new Implementation(*Injection1, *Injection2)) {}
void Interface::Function(const int argument){ Implement->Function(argument); }
Implementation.h:
class Implementation{
public:
Implementation(AbstractInjection &injection1, AbstractInjection &injection2);
void Function(const int argument);
private:
AbstractInjection Injection1, Injection2;
};
Implementation.cpp
Implementation::Implementation(AbstractInjection &injection1, AbstractInjection &injection2)
: Injection1(injection1),
Injection2(injection2) {}
void Implementation::Function(const int argument){
injection1.Function(argument); } // code from here out is all well tested and works
So when I create the interface and call Interface.Function() the code segfaults when it tries to evaluate Implementation.Function(). I've ran gdb through everything I can think of, all the pointers are non-null.
If I just create a test that looks like
std::unique_ptr<DependencyInjection1> injection1(new DependencyInjection());
std::unique_ptr<DependencyInjection2> injection2(new DependencyInjection());
std::unique_ptr<Implementation> implement(new Implementation(*injection1, *injection2));
implement->Function(0);
The code works fine and does not segfault
But if I create a test like
Interface iface;
iface.Function(0);
it will segfault.
I am new to the whole unique_ptr thing, but I have a suspicion that isn't the larger problem. It may be a red herring, I don't know.
The problem should actually pop as as a warning.
Initializers are done in the order in which they appear in the class definition, not in which they appear in the constructor!
Switch it to:
class Interface{
public:
Interface();
void Function(const int argument);
private:
std::unique_ptr<DependencyInjection> Injection1, Injection2;
std::unique_ptr<Implementation> Implement;
};
From here: C++: Initialization Order of Class Data Members, this is "12.6.2 of the C++ Standard"
You've got a wrong order of member fields, they are initialized in order they are declared in the class. So implement is initialized before both injections. Use -Werror=reorder to get compiler error (for GCC and probably CLang)

undefined reference in pure virtual function C++

I am having some difficulties with a c++ program that I need to run. The problem itself is not mine and I have to make it compile. The algorithm is pretty huge so for my current error message I will demonstrate a much more simplified version of a code that I produced that gives me the exact same error. Here is the code:
class_1.h (class_1.cpp is empty)
class class_1 {
public:
class_1();
virtual ~class_1();
virtual void function() =0;
};
class_2.h (class_2.cpp is empty)
include"class_1.h";
class class_2 : public class_1{
public:
class_2();
virtual ~class_2();
virtual void function();
};
class_2a.h (class_2a.cpp is empty)
include"class_2.h";
class class_2a : public flos2{
public:
class_2a();
virtual ~class_2a();
};
class_3.h
include "class_2a.h"
include "class_1.h" //I tried unsuccesfully without including class_1.h as well
class class_3 {
public:
class_3();
virtual ~class_3();
virtual void function();
private:
class_2a my_class_2a;
};
class_3.cpp
#include "class_3.h"
class_3::class_3()
:my_class_2a()
{
}
class_3::~class_3()
{
this->function();
}
void flos3::function()
{
my_class_2a.function();
/***Main Body of function***/
}
};
The error I am getting is linker error:
undefined reference to `class_2::function()'
I know that in general the whole algorithm seems to be stupid, but more or less this is the what I was given and I am not allowed to change the structure itself, just to make it working. As you can see in class_1 function is defined as a pure virtual function, and then is called through the other classes. I really don't know how to make this thing work, so any help would be really appreciated...
You need to add:
class_1.cpp:
class_1::~class_1() = default;
class_2.cpp:
class_2::~class_2() = default;
void class_2::function() {
// add code here (or not)
}
... and so on.
You are getting linker error because your function class_2::function() does not have implementation. You need to add it, preferably in class_2.cpp file.
void class_2::function()
{
// Implementation goes here
}
Similar problem is with all virtual destructors. They need implementations as well.

Passing function pointer with scope resolution operator arduino

I'm a newbie to arduino and programming.
I've included a library inside my own library in arduino, but first library contains a function which has a pointer function as a parameter. It is an interrupt service routine(ISR) but I need to call a function in my cpp file when interrupt is occurred. So I need to pass the pointer of that function to the first library code. It works well when I use it in .ino file, I can pass it like,
attachInterrupt(functionISR_name);
but when I use it in .cpp file, I get errors. my function is like,
void velocity::functionISR_name(){
//some code
}
but how can I pass the pointer of this function to the first library function? I tried this way but got errors,
attachInterrupt(velocity::functionISR_name);
You cannot pass a method to a function which expects a function, unless you define it static.
write it static :
static void velocity::functionISR_name()
and
attachInterrupt(&velocity::functionISR_name);
Unfortunately the static method is not bound to a specific instance any more. You should use it only together with a singleton. On Arduino you should write the class like shown below in the code snipped:
class velocity
{
static velocity *pThisSingelton;
public:
velocity()
{
pThisSingelton=this;
}
static void functionISR_name()
{
pThisSingelton->CallWhatEverMethodYouNeeded();
// Do whatever needed.
}
// … Your methods
};
velocity *velocity::pThisSingelton;
velocity YourOneAndOnlyInstanceOfThisClass;
void setup()
{
attachInterrupt(&velocity::functionISR_name);
// …other stuff…
}
This looks ugly, but in my opinion it is totally okay with Arduino as the opportunities are very limited on such a system.
Thinking again over it, I would personal go for the approach Sorin mentioned in his answer above. That would be more like that:
class velocity
{
public:
velocity()
{
}
static void functionISR_name()
{
// Do whatever needed.
}
// … Your methods
};
velocity YourOneAndOnlyInstanceOfThisClass;
void functionISR_name_delegation()
{
YourOneAndOnlyInstanceOfThisClass.functionISR_name();
}
void setup()
{
attachInterrupt(functionISR_name_delegation);
// …other stuff…
}
It would also save you some bytes for the pointer you need in the first example.
As a site note: For the future, please post the exact code (for e.g. attachInterrupt needs more parameter) and copy&paste the error messages. Usually error are exact at a place you do not suspect. This question was an exception. Normally I and other would ask for better specification.
You pass a pointer to the function but the function is a class member. Likely the call will be invalid because the this pointer will be garbage(may compile fine but will throw strange errors at runtime).
You need to define a plain vanilla function, outside of any class, and use that.
If you don't have a very complex project you can get away with having a global pointer to the class instance you should use and just delegate the call in your new function.
If you want to do thing the right way you need some mechanism to get the instance pointer I talked about above. Usually this involves either a singleton or some factory pattern.
Example:
class Foo {
void method() {
x = 5;
}
int x;
}
Having a callback on method will crash because you have an invalid pointer for this so x=5 will write 5 somewhere randomly in memory.
What you need is somehting like:
static Foo* foo_instance; // Initialized somewhere else.
void method_delegator() {
foo_instance->method();
}
Now you can pass method_delegator to the function. It will work because you now also pass foo_instance for this pointer.

C++ beginner's coding mistake: "Undeclared identifier"?

I'm to use C++ for a very small part of my project. I must be coding something wrong, but my knowledge of C++ is what it is and I can't get around this...
See both the AbstractContactListener.h and .mm files below. The problem is in isFixtureCollidingWithFixtureOfType(...) method, I can't access the _contact vector. What could I be doing wrong here?
header:
struct JRContact {
b2Fixture *fixtureA;
b2Fixture *fixtureB;
bool operator==(const JRContact& other) const
{
return (fixtureA == other.fixtureA) && (fixtureB == other.fixtureB);
}
};
class AbstractContactListener : public b2ContactListener {
id contactHandler;
public:
std::vector<JRContact>_contacts;
AbstractContactListener(id handler);
~AbstractContactListener();
void isFixtureCollidingWithFixtureOfType(b2Fixture fix, int type);
virtual void BeginContact(b2Contact* contact);
virtual void EndContact(b2Contact* contact);
};
Implementation:
AbstractContactListener::AbstractContactListener(id handler) : _contacts() {
contactHandler = handler;
}
AbstractContactListener::~AbstractContactListener() {
}
void isFixtureCollidingWithFixtureOfType(b2Fixture fix, int type){
std::vector<JRContact>::iterator ct;
// Next line is faulty... can't call _contacts.begin()
// xCode says: "Use of undeclared identifier _contacts"
ct = _contacts.begin();
}
void AbstractContactListener::BeginContact(b2Contact* contact) {
// ...
}
void AbstractContactListener::EndContact(b2Contact* contact) {
// ...
}
Undeclared? Hmm. I thought I was declaring it in the header, right after the "public:" keyword.
What could I be doing wrong here?
thanks a lot!
J.
You forget to add the scope of the function. Try:
void AbstractContactListener::isFixtureCollidingWithFixtureOfType(b2Fixture fix, int type){
Why is the error pointing you to that strange place? The compiler sees your function definition and thinks that this is a free function, as there is nothing that indicates otherwise and tries to handle it as such. It fails, because it tries to find the variable in the global scope. This can get even funnier (read: more confusing): Image that this function does not use a class member. It will be simply parsed and compiled as a free function. As soon as your try to call it on an object of that type you will get a linker error.
Also, I cannot see a declaration of the type id which is used in AbstractContactListener but that might just be because the code sample is incomplete.
You forgot the class name from
void isFixtureCollidingWithFixtureOfType(b2Fixture fix, int type)
void AbstractContactListener::isFixtureCollidingWithFixtureOfType(b2Fixture fix, int type)
In the implementation.
:)