C++ Development
응답
18. 5. 2 오전 9:55

Dear XDK-Community,

I would like to develop my XDK projects in C++.

I found this old post on how to use a C++ library (https://xdk.bosch-connectivity.com/community/-/message_boards/message/248231) and used it as a starting point.

Since that post, the makefile changed a lot and I tried to change it to compile the C++ code. It does that as well without any issue now, but when flashing the application to the XDK, it just crashes without any output. Unluckily I currently don't have a debugger at hand.

I build a minimal Example and pushed it to https://github.com/jendrikjoe/LEDExampleCPP.

You will see, that the actual C++ is still commented out and everything is basically extern C (and yes it is quite ugly ;) ).

I hope however someone could have a look on it, as I think I am not the only one who would be keen to use C++ for the development on the XDK. I would be happy to provide as well to provide C++ classes for most of the hardware as soon as it is running :)

Already thank you very much for every input :)

Cheers,

Jendrik

0 (0 투표)
RE: C++ Development
응답
18. 5. 2 오후 3:18 as a reply to Jendrik Jördening.
Hello Jendrik,

First, I would like to welcome you to the XDK community.

The post you linked is indeed an old one, but the described steps should still apply even if the makefiles changed. At this point, it may be also worth taking a look at the XDK Library guide. There an is explanation on how to link a static C library into the XDKs SDK, but the same steps with small modification apply also to linking a C++ library.

In general, the XDK-Workbench does only allow developing XDK applications in C instead of C++ out of the box. To develop in C++, more changes would need to be made to the makefiles, especially to the makefiles of the SDK.

A working solution should be to write your application in C++ while using the interfaces from the SDK. Then build this in a C++ library and link it to the SDK and use it in your C project. This way you do not have to figure out how to get the XDK's startup routines running in C++.

Alternatively, you could try to code your application C++, compile it for the XDK, and leave the startup procedure as it is and compile it independently. Then you would need to link the two components.

In regards to your already existing approach, could you go more into detail about what kind of error you are receiving?

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 2 오후 3:56 as a reply to Franjo Stjepandic.

Hello Franjo,

thank you for the warm welcome and all your input.

My plan is to code the application in C++ while using the XDK libraries. I wanted to just hand member function pointer callbacks to all the interrupts and then use C++ classes for everything. It simply makes it way easier for me to structure my code.
I therefore tried the last approach, using the LED and button example as a start-off. I am compiling my C++ code separatly and link it then. For that I basically wrapped all the C Code using:

#ifdef __cplusplus
extern "C" {
#endif

 C-Code....

#ifdef __cplusplus

}
#endif

and renamed Main.c to Main.cpp.

I changed the application.mk for that in the following way:

$(BCDS_XDK_APP_DEBUG_OBJECT_DIR)/%.o: %.c
	@mkdir -p $(@D)
	@echo "Building file $<"
	$(CC) $(DEPEDENCY_FLAGS) $(BCDS_CFLAGS_DEBUG_COMMON) $(BCDS_XDK_INCLUDES) $(BCDS_XDK_EXT_INCLUDES) -DBCDS_PACKAGE_ID=$(BCDS_PACKAGE_ID) -c $< -o $@
	
#Compile the sources from application
$(BCDS_XDK_APP_DEBUG_OBJECT_DIR)/%.o: $(BCDS_APP_SOURCE_DIR)/%.cpp 
	@mkdir -p $(@D)
	@echo $(BCDS_XDK_APP_PATH)
	@echo "Building file $<"
	@$(CPLUS) $(DEPEDENCY_FLAGS) $(BCDS_CPPFLAGS_DEBUG_COMMON) $(BCDS_XDK_INCLUDES) $(BCDS_XDK_EXT_INCLUDES) -DBCDS_PACKAGE_ID=$(BCDS_PACKAGE_ID) -c $< -o $@
	
$(BCDS_XDK_APP_DEBUG_OBJECT_DIR)/%.o: %.S
	@mkdir -p $(@D)
	@echo "Assembling $<"
	@$(CPLUS) $(ASMFLAGS) $(BCDS_XDK_INCLUDES) $(BCDS_XDK_EXT_INCLUDES) -c $< -o $@
	
$(BCDS_XDK_APP_DEBUG_DIR)/$(BCDS_APP_NAME).out: $(BCDS_LIBS_DEBUG) $(BCDS_XDK_APP_OBJECT_FILES_DEBUG) 
	@echo "Creating .out $@"
	@$(CPLUS) $(LDFLAGS_DEBUG) $(BCDS_XDK_APP_OBJECT_FILES_DEBUG) $(BCDS_DEBUG_LIBS_GROUP) $(LIBS) -o $@

 

With $(CPLUS) being g++ and BCDS_CPPFLAGS_DEBUG_COMMON replacing std=c99 with std=c++11.

and changed the Makefile.mk to have:

export BCDS_XDK_APP_SOURCE_FILES = \
    $(BCDS_APP_SOURCE_DIR)/Main.cpp \
    $(BCDS_APP_SOURCE_DIR)/DataLog.cpp

The compiling works as well without an issue. However, when flashing the binary to the XDK it boots and immediatly disconnects from the serial interface and nothing works anymore, except for switching it off and switching it back on while holding PB1. I assume that the main function isn't properly linked anymore, as setting an infinite while loop behind the MainCmdProcessor call doesn't solve the issue either. I am not sure at all though. Makescripts and assembler where never my strong side to be honest ;)

Does the description help to understand the problem better?

Cheers and thank you very much,

Jendrik

 

0 (0 투표)
RE: C++ Development
응답
18. 5. 3 오후 12:31 as a reply to Jendrik Jördening.

Hi Jendrik,

it looks like your main file is in C++. Please start the system using the C components since this ensures that the board, hardware and RTOS components are initialized.

The scheduler will call appInitSystem(void * , uint32_t ) and in this function you may call the C-wrapper (a function with exposed C-interface, but C++ internals) for your C++ module

Regards

Francisco
+1 (1 투표)
RE: C++ Development
응답
18. 5. 3 오후 1:36 as a reply to Francisco Llobet Blandino.
Hello Jendrik,

Thank you for the further information.

Please note that the XDK-Workbench initially was designed to program the XDK with C, not with C++. As such, I can only confirm that linking a C++ library is currently possible.

But from the first glance, the changes you made should work as expected.

Please note that it can take a lot of additional modification effort to make C++ with the XDK work and it does not necessarily work with the XDK-Workbench as well since the XDK-Workbench does not support it out of the box.

On that behalf, I would recommend to follow the recommendation Francisco and I gave you to leave the startup procedure including appInitSystem() as C compiled object and call from within your C++ code.

Additionally to that, I have two questions regarding your makefile modifications.

Did you only make changes to the application. mk makefile or to the common_settings. mk makefile as well?

Which g++ compiler did you actually use? The arm-none- eabi -g++ , which is integrated in the XDK-Workbench or the g++ compiler from your OS?

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 3 오후 7:41 as a reply to Franjo Stjepandic.

Hi Francisco and Franjo,

thanks again for the input :)

The way Francisco described was something I tried yesterday as well. For that, I build an extra step to compile all C++ code into a shared library and then link that to the C-Program. This however failes when calling the XDK-C-Functions in C++ as those are static libraries and it seems that it is not possible to link to static libraries from shared libraries. (There were some sugestions to compile the C-stuff with -fPIC, but that didn't solve the issue). I might try to compile the C++ one as a static library. That might work. Will do so asap tomorrow morning and let you know the outcome.

For the makefile configuration I only changed the project's Makefile.mk and the application.mk as posted in the github. For compilation I used the XDK's arm-none-eabi-g++. I could try to build new compilers using the cross-compilation-tools out there (I did that for Pi and an STM32 a long time ago, but not sure how lang that would take me now :D)


Cheers,

Jendrik

0 (0 투표)
RE: C++ Development
응답
18. 5. 4 오후 2:13 as a reply to Jendrik Jördening.

Hi everyone,

so I tried linking to static C++ libraries now. It now compiles (*yay*), but the application crashes as soon as it calls the function which is defined via extern "C".

I checked it using the LED and Button example and putting the function call to C++ to the very end. It sets up the Interrupts for the buttons well, but when clicking one of them it outputs:


 INFO | XDK DEVICE 1: Enqueuing for Button 2 callback failed

This is not the case when commenting the call to the C++ bridge function.

Anyone an idea what the issue might be? I updated my git code accordingly in case you want to check it and try it on your own. Thank you very much for any input on it :)

Cheers and have a nice weekend,

Jendrik

 

 

0 (0 투표)
RE: C++ Development
응답
18. 5. 7 오후 4:06 as a reply to Jendrik Jördening.
Hello Jendrik,

Thank you for the additional information.

On first glance, I would assume that it is working as expected since you are able to compile the CPP along with the C files and link them together.

Unfortunately, the error you are receiving in the XDK's Workbench console does not actually mean that your function call of testStuff() is the cause of the issue.

As such, I would recommend examining the return code thrown by CmdProcessor_EnqueueFromIsr() in the function Button2Callback() to see why the interrupt was not processed properly.

Otherwise, I would recommend to try out creating C++ code working with an empty XdkApplicationTemplate and adding some printf() function calls before and after the call of testStuff() and catching its return value to see if this is actually working.

Additionally, please note that you can remove the extern "C" {...} statement in the header-file, since it is only needed to declare C code in C++.

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 9 오전 7:52 as a reply to Franjo Stjepandic.

Hi Franjo,

thanks again for the input. It is definitely helpful and sorry that it took me some time to reply.

I investigated the return code using:

printf("Enqueuing for Button 2 callback failed 0x%X\n\r", (unsigned int) returnValue)

Funnily I get 0x20F2001, which seems interesting as I would not expect this from and enum. However, I realised that I have to press the buttons multiple times before the error occurs, so I assume the queue fills up.

The other thing I did is as well including the printf functions (I took me some time to figure out, that I have to delay my main thread, such that the serial connection gets established before the printfs get executed).  Now, I can actually see, that the programm crashes on testStuff(89).


    printf("Before testStuff\n");
    testStuff(89);
    printf("After testStuff\n");

 

Using this results in outputting Before testStuff only. Commenting the function prints After testStuff as well. The only thing I have to figure out now is why this happens :)

Cheers,
Jendrik

0 (0 투표)
RE: C++ Development
응답
18. 5. 9 오후 2:28 as a reply to Jendrik Jördening.
Hello Jendrik,

I am always glad to help and please take your time to try things out.

Furthermore, I did assume something like that the command processor queue gets full and the thrown error does not relate to your C++ implementation.

However, I am glad to hear that you managed to port your implementation into a clean XdkApplicationTemplate and that you figured out that you need a delay to allow establishing the USB connection before sending data out over it.

That is the bottleneck because the XDK's MCU is ready after restart before the USB connection is established to your PC/notebook.

A delay of 5 seconds passed in as 5000 milliseconds would be helpful to display all incoming printf() function calls. Additionally, I would recommend appending a \n\r to every string     you want to send over printf() to the XDK-Workbench's console to ensure that the content is printed correctly. This is necessary because the internal API is parsing for this statements and without them, not every printf() is displayed properly.

However, may I ask which behavior you observe when you are calling testStuff() ? Maybe I can get a helpful hint on that.

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 11 오후 4:17 as a reply to Franjo Stjepandic.

Hey Franjo,

awesome!

Actually, I still didn't port the project. I just tried the same within the LED project. The funny thing is that the only difference between the queue filling up and it not filling up is, that that in the first I include C++ code and the other one not. I assume that the call to the C++ just crashes the main thread and the event handling of RTOS, but I am not sure at all ;)

I went with your recommendation and appended \n\r ( actually only \n cause I am on Linux ;) ) .

Regarding the behaviour when calling testStuff(): What I observe is that the execution of the main thread simply stops. Every print statement before is executed perfectly fine and as soon as hitting testStuff() it fails. When commenting the call out again, everything works as expected. All print statements are executed and all Button interrupts work as in the example.

Cheers,

Jendrik

0 (0 투표)
RE: C++ Development
응답
18. 5. 14 오후 4:23 as a reply to Jendrik Jördening.
Hello Jendrik,

I tried out the project you uploaded on GitHub, too, and tested multiple approaches determine what is causing that the application to not respond anymore. I came to the conclusion that it is caused by the call of testStuff , even if compiled correctly.

I am going to analyse this in more in detail to see how to to make the C++ function call work. This might take some days. Until then I would ask you for patience.

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 15 오전 7:04 as a reply to Franjo Stjepandic.

Hey Franjo,

awesome thank you so much for trying!
It is nice that the problem is reproducable as well :)

Of course take your time, I know that this is definitely not a one day problem :)
I will as well try to go through it again. I actually assume, that I don't flash the cpp stuff correctly. Will try to find where I am missing to do that ;)

Cheers and again thanks a lot,

Jendrik

0 (0 투표)
RE: C++ Development
응답
18. 5. 16 오후 4:23 as a reply to Jendrik Jördening.
Hello Jendrik,

I am always happy to help and I was able to make it work. There are only two modifications which need to be applied, and then the build should also be possible on your end.

The error was caused because you did not compile any flags into your C++ object. You are using the variable BCPPDS_CPPFLAGS_COMMON for the flags, but your rule to build the object files from the cpp files uses the variable BCDS_CPPFLAGS_DEBUG_COMMON .

A simple assignment, as shown below, should solve the issue:

BCDS_CPPFLAGS_DEBUG_COMMON = BCPPDS_CPPFLAGS_COMMON

Furthermore, you would need to change the used compiler for building object files from assembler files back from CPLUS to CC .

Afterwards you should be able to build a working binary for the XDK.

Please note that I used the project and application.mk makefile you provided on GitHub. I hope the content does not differ much from the files you are currently using.

I also recommend changing the rule in application.mk generating your .out file by setting the compiler variable from CC to CPLUS , if not already done.

In addition, I faced the issue that not all C++ standard libraries are supported and I found a very helpful thread on stackoverflow regarding this problem for the AVR platform, but some of the statements does also apply for the XDK. As such, I would recommend taking a look at the thread I linked.

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 17 오후 3:39 as a reply to Franjo Stjepandic.

Hey Franjo,

thank you so much!
I highly appreciate your effort.

I tried to get it running and will continue tomorrow. (Ihave some issues, since I updated to Ubuntu 18.04 and the XDKs don't appear anymore ;)) Had to change back to the slow Windows computer I have here.

I will definetely let you know, when it is working on my side as well!

Thanks as well for the other hints. I will migrate them and especially the StackOverflow link will save me some debugging :)

Cheers and really thank you so much already,

Jendrik

 

0 (0 투표)
RE: C++ Development
응답
18. 5. 18 오전 7:44 as a reply to Jendrik Jördening.
Hello Jendrik,

I am always glad to help.

Regarding the issue with Ubuntu 18.04, does the XDK not appear in the XDK-Workbench? Or does it not appear at all, even when you run the command lsusb in the console? If it's only the first case, have you tried running the XDK-Workbench with sudo privileges (i.e. run sudo XDK-Workbench in the console).

In the latter case, I may have to investigate this further, and eventually report this issue to the responsible developer.

Kind regards,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 18 오전 8:44 as a reply to Franjo Stjepandic.

Hi Franjo,

it is working!!!!! *party* *celebrate*

You really deserve your Yoda rank :)

sudo priviliges solve the issue and renaming the C++ flags as well!

Thank you very much!

I will now start building C++ classes for all the sensors! :)

Cheers and thanks sooooo much,

Jendrik

 

0 (0 투표)
RE: C++ Development
응답
18. 5. 18 오후 1:43 as a reply to Jendrik Jördening.
Hello Jendrik,

I am very happy to help and I am glad to hear that it is working on your end as well, and it is also great to hear that the XDK-Workbench works now on Ubuntu 18.04, too.

On that behalf, are you going to push your sensor class implementations onto your public GitHub repository? It sounds very interesting and I would be very interested to see how you build them.

Please feel free to ask if you have any other question or concern.

Party on,
Franjo
+1 (1 투표)
RE: C++ Development
응답
18. 5. 24 오전 6:33 as a reply to Franjo Stjepandic.

Hey Franjo,

 

sorry for the long silence, was on travel.
I will definitely push the implementations to the github so everyone can use them.
Will come back to you as soon as everything is set up.

Cheers,


Jendrik

0 (0 투표)
RE: C++ Development
응답
18. 5. 24 오전 11:21 as a reply to Jendrik Jördening.
Hello Jendrik,

I hope you enjoyed your travel. Thank you for updating the repository, this will definitely be helpful.

Kind regards,
Franjo
0 (0 투표)