cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC Creator & Designer Software

RaAl_264636
Contributor II

Hi,

has anyone succesfully used C++ on PSoC? I want to use a C++ source code. On the first run I want to know if it will fit into a 5LP. I switched to the latest ARM GCC release (9-2020-q2). I replaced the GCC exe file with the G++ exe file.

There was an issue in CyLib.c with the initialization of the SysTick Callbacks regarding the void* 0 pointer. Replacing it with "nullptr" resolved the issue. Now, it seems(!) that it can be linked. As expected, it won't fit into the device on the first run, the error message is:

Build error: <...>/xyz.elf section `.ARM.exidx' will not fit in region `rom'

The bad thing is that the .elf file is deleted directly after the build process - it can be seen shortly in file explorer. Trying to copy it while it exists results in a empty file, unfortunately. I assume the created file is filled with valuable content for checking how much the flash content is in size. Too bad that the output window doesn't show the size in this configuration.

There's also an error "cm3gcc.ld:91: undefined symbol `RomVectors' referenced in expression". I don't know if this is related to the error mentioned above.

So, I've two questions:

1) how to get the information regarding the build size / prevent that the .elf file is deleted

2) how to check what's going on with those RomVectors?

Regards

0 Likes
1 Solution
MotooTanaka
Esteemed Contributor

Hi,

> has anyone succesfully used C++ on PSoC?

I answered I have.

But please note that C++ is not supported by PSoC Creator, so what we are doing is hacking

and not guaranteed nor recommended.

And I also can not guarantee nor recommend it (at least for the time being).

Having written above, you know, I tried my hack using CY8CKIT-059 😉

schematic

002-schematic.JPG

pins

003-pins.JPG

animal.h

==============

#ifndef _ANIMAL_H_

#define _ANIMAL_H_

extern "C" {

#include "project.h"

}

#include "stdio.h"

  

class animal {

public:

    animal(char *name) ;

    ~animal() ;

    void move(int x, int y) ;

    void go(int x, int y) ;

private:

    char *_name ;

    int _x ;

    int _y ;

} ;

#endif /* _ANIMAL_H_ */

==============

animal.cpp

==============

extern "C" {

#include "project.h"

}

#include <stdio.h>

#include <string.h>

#include "main.h"

#include "animal.h"

animal::animal(char *name)

{

    _name = new char[strlen(name) + 1] ;

    strcpy(_name, name) ;

    _x = 0 ;

    _y = 0 ;

}

animal::~animal(void)

{

    delete [] _name ;

    _x = 0 ;

    _y = 0 ;

}

void animal::move(int x, int y)

{

    _x += x ;

    _y += y ;

    snprintf(str, STR_LEN, "%s moved to %d %d\n",_name, _x, _y) ;

    print(str) ;

}

void animal::go(int x, int y)

{

    _x = x ;

    _y = y ;

    snprintf(str, STR_LEN, "%s moved to %d %d\n",_name, _x, _y) ;

    print(str) ;

}

==============

main.h

==============

#ifndef _MAIN_H_

#define _MAIN_H_

extern "C" {

#include "project.h"

extern char str[] ;

extern void print(char *str) ;

}

#define STR_LEN 64

void *operator new(size_t size) ;

void  operator delete(void *ptr) ;

void *operator new[] (size_t size) ;

void  operator delete[] (void *ptr) ;

#endif /* _MAIN_H_ */

==============

main.cpp

==============

extern "C" {

#include "project.h"

}

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include "animal.h"

#include "main.h"

char str[STR_LEN+1] ;

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start() ;

}

int main(void)

{

    animal *cat ;

  

    init_hardware() ;

  

    print("\x1b[2J\x1b[;H") ;

    print("PSoC 5LP C++ Test (Experimental) ") ;

    snprintf(str, STR_LEN, "(%s %s)\n", __DATE__,__TIME__) ;

    print(str) ;

  

    cat = new animal("mikan") ;

  

    cat->move(3, 3) ;

    cat->move(3, 3) ;

    cat->go(2, 4) ;

  

    for(;;) {

    }

}

void *operator new(size_t size)

{

    return malloc(size) ;

}

void operator delete(void *ptr)

{

    free(ptr) ;

}

void *operator new[] (size_t size)

{

    return malloc(size) ;

}

void operator delete[] (void *ptr)

{

    free(ptr) ;

}

==============

Tera Term Log

001-tera-term-log.JPG

So the good news is at least my c++ program could be compiled and my cat can walk a little.

The bad news is that there is no one who will guarantee nor support for further exploration.

moto

View solution in original post

0 Likes
10 Replies
MotooTanaka
Esteemed Contributor

Hi,

I once tried the following URL with PSoC 4 and it worked.

Your mileage may vary for PSoC 5LP.

https://blog.mbedded.ninja/programming/microcontrollers/psoc/using-cplusplus-with-psoc-creator/

moto

0 Likes
RaAl_264636
Contributor II

MoTa_728816​ I know the URL, sorry that I didn't mentioned it. In fact, I think that I've done it as the blog describes. Interestingly, I had not to do most of the things mentioned there regarding undefined references, etc., but the current setup was only switching to the newest GCC build and using G++ instead of GCC, as mentioned in the URL under #13. So, I'm not using any C++ code, just the default code of an empty PSoC project (and the SysTick tweak mentioned). And this results in the error mentioned above.

So, I'd be glad if you can help me to dig deeper into it to check where the error is.

Regards

0 Likes
MotooTanaka
Esteemed Contributor

Hi,

Right now I'm only writing off my head, I have not tried it by myself.

I wonder if ".map" file remains or not.

If ".map" file is left, you can see the rom map.

Meantime, about the symbol problem, from my (old) experience,

I think that  c functions must be protected by using the "extern "C" { }"

moto

0 Likes
RaAl_264636
Contributor II

MoTa_728816

Motoo Tanaka schrieb:

If ".map" file is left, you can see the rom map.

...

I think that  c functions must be protected by using the "extern "C" { }"

I'll check for the map file. Regarding the protection, it means that I've to protect all C files which are automatically generated? I thought that the GCC/G++ automatically detects the "source" type depending on the file extension.

Regards

0 Likes
MotooTanaka
Esteemed Contributor

Hi,

>  I thought that the GCC/G++ automatically detects the "source" type depending on the file extension.

Since C++ allows multiple functions in the same name, the compiler expands the function name with its parameter signature.

So, *.c will be fine, but *.h may need to be protected.

IMHO, you don't have to modify the "Auto Generated" files, but something like below should work

In the source file which could be compiled by c++

===================

#ifdef __cplusplus

extern "C" {

#endif

#include "project.h"

#ifdef __cplusplus

}

#endif

===================

For the details, please "google" "extern c", "c++"

moto

0 Likes
RaAl_264636
Contributor II

MoTa_728816​ Okay, I'll keep that in mind.

But, if the auto-generated files don't have to be modified, why the empty project fails?

Regards

0 Likes
MotooTanaka
Esteemed Contributor

Hi,

> But, if the auto-generated files don't have to be modified, why the empty project fails?

I assumed that ".c" files are compiled with "gcc" or "cc"

and ".cpp" or ".C" files are compiled with "g++" or "c++".

If ".c" files are also to be compiled with "g++" or "c++"

then I think that we need "extern C {" in "*.c" files, but modifying auto generated files are usually not recommended.

moto

0 Likes
RaAl_264636
Contributor II

MoTa_728816​ As far as I know PSoC Creator is fixed to GCC, because it's hard-coded. That's why the blog post item #13 replaces the GCC.exe with the G++.exe.

Regards

0 Likes
MotooTanaka
Esteemed Contributor

Hi,

> has anyone succesfully used C++ on PSoC?

I answered I have.

But please note that C++ is not supported by PSoC Creator, so what we are doing is hacking

and not guaranteed nor recommended.

And I also can not guarantee nor recommend it (at least for the time being).

Having written above, you know, I tried my hack using CY8CKIT-059 😉

schematic

002-schematic.JPG

pins

003-pins.JPG

animal.h

==============

#ifndef _ANIMAL_H_

#define _ANIMAL_H_

extern "C" {

#include "project.h"

}

#include "stdio.h"

  

class animal {

public:

    animal(char *name) ;

    ~animal() ;

    void move(int x, int y) ;

    void go(int x, int y) ;

private:

    char *_name ;

    int _x ;

    int _y ;

} ;

#endif /* _ANIMAL_H_ */

==============

animal.cpp

==============

extern "C" {

#include "project.h"

}

#include <stdio.h>

#include <string.h>

#include "main.h"

#include "animal.h"

animal::animal(char *name)

{

    _name = new char[strlen(name) + 1] ;

    strcpy(_name, name) ;

    _x = 0 ;

    _y = 0 ;

}

animal::~animal(void)

{

    delete [] _name ;

    _x = 0 ;

    _y = 0 ;

}

void animal::move(int x, int y)

{

    _x += x ;

    _y += y ;

    snprintf(str, STR_LEN, "%s moved to %d %d\n",_name, _x, _y) ;

    print(str) ;

}

void animal::go(int x, int y)

{

    _x = x ;

    _y = y ;

    snprintf(str, STR_LEN, "%s moved to %d %d\n",_name, _x, _y) ;

    print(str) ;

}

==============

main.h

==============

#ifndef _MAIN_H_

#define _MAIN_H_

extern "C" {

#include "project.h"

extern char str[] ;

extern void print(char *str) ;

}

#define STR_LEN 64

void *operator new(size_t size) ;

void  operator delete(void *ptr) ;

void *operator new[] (size_t size) ;

void  operator delete[] (void *ptr) ;

#endif /* _MAIN_H_ */

==============

main.cpp

==============

extern "C" {

#include "project.h"

}

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include "animal.h"

#include "main.h"

char str[STR_LEN+1] ;

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start() ;

}

int main(void)

{

    animal *cat ;

  

    init_hardware() ;

  

    print("\x1b[2J\x1b[;H") ;

    print("PSoC 5LP C++ Test (Experimental) ") ;

    snprintf(str, STR_LEN, "(%s %s)\n", __DATE__,__TIME__) ;

    print(str) ;

  

    cat = new animal("mikan") ;

  

    cat->move(3, 3) ;

    cat->move(3, 3) ;

    cat->go(2, 4) ;

  

    for(;;) {

    }

}

void *operator new(size_t size)

{

    return malloc(size) ;

}

void operator delete(void *ptr)

{

    free(ptr) ;

}

void *operator new[] (size_t size)

{

    return malloc(size) ;

}

void operator delete[] (void *ptr)

{

    free(ptr) ;

}

==============

Tera Term Log

001-tera-term-log.JPG

So the good news is at least my c++ program could be compiled and my cat can walk a little.

The bad news is that there is no one who will guarantee nor support for further exploration.

moto

View solution in original post

0 Likes
RaAl_264636
Contributor II

MoTa_728816​ Thank you for creating the 5LP project. I compared it to my attempts, and it seems the 'no exception flag' was causing the missing romvector symbol... Strange... Since it was mentioned in the blog with a different error message, I didn't think of that this might be the issue.

Now I have a base to build on. I know that there's no official support, but maybe this topic might help others to get into it. Too bad that Cypress doesn't implement C++ for PSoC.

EDIT: I was too early... the missing romvector symbol is still present if I try to modify my test project according to your reference project... I'll keep this topic updated about it.

Regards