-3

I'm trying to build a solution, where there would be two projects: 'bootloader' (starting after reset and doing smth), and 'mainApplication' getting the control from bootloader.

Initially i've just reproduced the example from here: https://visualgdb.com/tutorials/arm/bootloader/

The final part of this tutorial describes "system call" - passing the pointer to some function residing in bootloader to the main application and then making a call to this function from there.

The intention is to pass not a pointer to a function, but say pointer to an object of a class.

Modified example from tutorial looks like this:

Bootloader:



//sys.h

class SysCalls
{
public:
    SysCalls();
    int sum(int, int);
};



//sys.cpp

#include "sys.h"

SysCalls::SysCalls()
{
}

int SysCalls::sum(int a, int b)
{
    return a + b;
}


// main.cpp

#include <sys.h>

...

SysCalls _sys;

void *g_Syscalls[] __attribute__((section(".syscalls"))) = { (void *)&_sys };



Main Application:

//main.cpp

#include <sys.h> // the same header as in bootloader

extern "C" void *g_Syscalls[];

SysCalls *_sys = (SysCalls*) g_Syscalls[0];

int main(void)
{

...

    int sum = _sys->sum(1, 2);
...



I get an linker error:

undefined reference to `SysCalls::sum(int, int)'

which is predictable, but...

Is there any good way to build this, i wonder? some linker config? or should i include sys.cpp to mainApplication also, and make the content not to be included in final binary somehow?

Also, looking forward - if talking about simple staff like shown sum function, which uses only stack, it is only a linker issue, but if i want to create a kind of 'system service', say singleton object with some heap usage, then the question would be - if there is any good way to freeze the part of heap used by this object when transferring control from bootloader, where it was created to main Application, which should use it...

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • 1
    If your question is misunderstood, then that may be indicative of lack of clarity or misleading title. You should generally address that rather than berating those trying to help in the question. That will win you no friends. A useful guide is to be concise accurate and succinct; get to the point of the question as quickly as possible - structure "question + supporting information" rather than "preamble + question". I'd also suggest writing the title last to ensure the title and the question ask the same thing. You'd be amazed the number of times these appear to ask different things. – Clifford Jan 12 '19 at 09:05
  • agree, there was my fault, creating the title containing a "popular" linker error... And placing the actual problem far to the end... – user2888100 Jan 12 '19 at 17:49

2 Answers2

1

A pointer to an object with data members instantiated by the bootloader would be invalid in the application unless the bootloader's RAM is permanently assigned rather than being reused by the application. Which itself would require memory partitioning by the linker. The only type of class that would be valid without such memory partitioning is one containing static member functions that do not use static data, and therefore the only benefit of a pointer to a class would be to have a single pointer to a collection if functions (which may not be without merit).

Either way, whilst it may be possible to use some sort of linker configuration to manage your requirement, linker scripts are often arcane and are not portable between toolchain. A simpler solution would be to create a vector table populated with the pointers to your functions, classes, or objects (previous caveats notwithstanding), and use the linker and/or compiler linker directives to locate the table in ROM at a known and reserved location. That same table location can then also be placed in your application link map. Your entry points are then simply provided by accessing that table as an array of pointers, with a known index for each access point.

The vectors need not be pointers to functions, you can interpret them (by casting) as a pointer to any entity. Again precious caveats about object validity in the application context notwithstanding.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • My first intention was to create the thing as "singleton service" and pass just one pointer to main application, just because it looks nicer, but, yes, i agree in general with all, that you've said. Actually, I can easily reserve some RAM to keep data members of this singleton still available to main app, even, there is in existance a linker flag like --undefined-reference=ignore-all and some other flag to convert this error to warning and allow the build to finish (pity, but both are not supported by toolchain I forced to use). – user2888100 Jan 12 '19 at 17:44
  • Anyway, what I plan to do, is to create a structure type with pretty names for shared function's pointers, this structure i will share to main app, and also every function i'm going to share would recieve a typedef in this shared header. Also i will share a section of RAM, where all static data for that shared functions will reside. Thank you for the answer. – user2888100 Jan 12 '19 at 17:45
0

This approach is used by many middleware software components. One of the example is the SoftDevices BT NRF middleware. In the linker scripts it gives some RAM for the static objects and some space for the local stack as well. The "main" program has this RAM excluded from use (the flash area occupied by the SDev is also excluded). It works very well.

It is not the actual bootloader - the bootloader is a separate being having acces to the SDev) as NRF bootloader is OTA capable

0___________
  • 60,014
  • 4
  • 34
  • 74
  • but is there any way to pass the single pointer to class, linking it somehow nicely, but not the table of pointers to functions? – user2888100 Jan 12 '19 at 17:53
  • 1
    Possible, but it would be horribly ugly. And a vendor solution like the nrf softdevice wouldn't do that, as most customers would want to interface from C, and it's trivial for those who want to use C++ to call C but very difficult to interact with C++ classes from C. Perhaps it's time to learn that there are ways to do OO that don't rely on the compiler - a simple to understand example would be a struct containing function pointers and data. – Chris Stratton Jan 12 '19 at 18:16
  • @ChrisStratton, agree with what you said about C interfacing, but 'horribly ugly' would be the OO you propose - how would you implement inheritance there, f.e.? I believe you can, but why? and i swear, i don't want to learn it (kidding). Anyway, thank you for the opinion, i've got enough to make my choice ) – user2888100 Jan 12 '19 at 22:02
  • Inheritance is why you use function pointers. The "learning" is having to think about how things actually work, which is rarely a bad idea, and precisely what is needed when you want to design a scheme for passing objects through a narrow channel between largely independent systems. You could also do a stub and ordinal identifier method as in Android Binder IPC. – Chris Stratton Jan 13 '19 at 15:02