EWL C++ in MQX.

cancel
Showing results for 
Search instead for 
Did you mean: 

EWL C++ in MQX.

Jump to solution
6,754 Views
raulnorthstar
Contributor II

Hi Freescale Community.

I need to use the EWL C++ in MQX project. I've started with the C++ example "cplus" from MQX example applications. And it works fine (this project doesn't include "${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include"), then when I included the path "${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include" in "Include User Search Paths" it doesn't compile. I've reduced the errors putting "ewl_c++" on "Properties"->"C/C++ Build "->"Settings"->"Librarian"->"Model". Also I've enabled (MQX_ENABLE_CPP 1) on "user_config.h" and I've rebuilded MQX libraries.

The errors that CW shows are:

**** Build of configuration twrk40x256_Int_Flash_Debug for project MQX_C++ ****

C:\Freescale\CW MCU v10.3\gnu\bin\mingw32-make -j16 all

'Building file: ../Sources/cplus.cpp'

'Executing target #1 ../Sources/cplus.cpp'

'Invoking: ARM Compiler'

"C:/Freescale/CW MCU v10.3/MCU/ARM_Tools/Command_Line_Tools/mwccarm" -gccinc @@"Sources/cplus.args" -o "Sources/cplus_cpp.obj" -c "../Sources/cplus.cpp" -MD -gccdep

C:/Freescale/CW MCU v10.3/MCU/ARM_Tools/Command_Line_Tools/mwccarm|Compiler|Error

(C:\Freescale\Freescale_MQX_4_0\lib\twrk40x256.cw10\debug\psp\lwsem.h|89|4|12|3061|12)

=    QUEUE_STRUCT               TD_QUEUE; 

>undefined identifier 'QUEUE_STRUCT'

C:/Freescale/CW MCU v10.3/MCU/ARM_Tools/Command_Line_Tools/mwccarm|Compiler|Error

(C:\Freescale\Freescale_MQX_4_0\lib\twrk40x256.cw10\debug\psp\lwmem.h|63|3|20|2306|20)

=   QUEUE_ELEMENT_STRUCT LINK; 

>undefined identifier 'QUEUE_ELEMENT_STRUCT'

C:/Freescale/CW MCU v10.3/MCU/ARM_Tools/Command_Line_Tools/mwccarm|Compiler|Error

(C:\Freescale\Freescale_MQX_4_0\lib\twrk40x256.cw10\debug\psp\fio.h|103|8|5|3712|5)

=#define stdin     (MQX_FILE_PTR)_io_get_handle(IO_STDIN) 

>macro 'stdin' redefined

C:/Freescale/CW MCU v10.3/MCU/ARM_Tools/Command_Line_Tools/mwccarm|Compiler|Note

(C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\file_struc.h|182|8|5|3777|5)

=#define stdin   (&__std(__files[0])) 

>    (location of previous definition)

Errors caused tool to abort.

mingw32-make: *** [Sources/cplus_cpp.obj] Error 1



I am working with CW10.3 and MQX4.0 on Windows 7. Thanks in advance for any ideas to resolve the problem.

1 Solution
973 Views
Martin_
NXP Employee
NXP Employee

Hi Raul,

those are conflict in names, like "stdin" defined by MQX fio.h as well as by EWL C++ header file. The QUEUE is also defined by PSP project as well as by EWL C++. As you have all MQX source codes, a doable solution exist - rename MQX names to be MQX specific, like rename stdin to _mqxio_stdin.

Make sure you enable #define MQX_ENABLE_CPP 1 in user_config.h and configure MQX_SUPPRESS_STDIO_MACROS: in user_config.h:

#define MQX_ENABLE_CPP 1

#define MQX_SUPPRESS_STDIO_MACROS 1

Then replace the original MQX 4.0 PSP fio.h with the attached file fio.h.

now when attempted to build MQX 4.0 libs, a lot of errors due to names occur.

In all MQX library project source files, replace "fopen" by "_io_fopen", then replace "stdin" by "_mqxio_stdin" and replace "stdout" by "_mqxio_stdout". Specifically in PSP, MFS, RTCS and SHELL projects.

Also in "tchres.c" replace "fopen" by "_io_fopen"

PSP

in fio.h

rename definition of stdin, stdout and stderr to _mqxio_stdin, etc., and change fio PSP, RTCS and SHELL usage accordingly.

RTCS

rtcscmd.c, httpd_supp.c, httpd.c, ftpc_cmd.c, rtcs_sh.c, telnet.c, telnsrv.c

"fopen" to "_io_fopen"

many files in SHELL the same change:

fopen to _io_fopen

stdin to _mqxio_stdin

stdout to _mqxio_stdout

When MQX libraries build with these settings we can move on to cplus example.

Cplus example

******************************

Using CW 10.3 New Project Wizard, create New MQX 4.0 project based on cplus example.

In the properties, change librarian of the project from EWL C to EWL C++

add C++ compiler settings include path:

"${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include"

we need both includes paths and move both paths to the last position in C++ compiler search paths settings

"${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include"

"${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C/include"

Attached is the example that can build and execute on my board with MQX 4.0, and CW 10.3. It uses #include <string> and #include <iostream> EWL C++.

_io_printf() is MQX implementation of printf function. Default std::cout stream goes to debug console in CW console window, via semihosting.

If you wish to redirect std::cout stream to MQX serial console, we need to redefine also low level __write_console() function, which is called by the EWL C++ library when it prints characters. For an example you can refer to the attached project.

I notice the default MQX 4.0 linker command files don't have .ARM.extab section (I think C++ exception table?). In case your application needs this, the section will need to be added to the linker command file.

View solution in original post

12 Replies
973 Views
Nana
Contributor II

Hello,

I'm sorry if this post is not related to the original post !

I have a problem with a project that was original build on MQX 3.8 and now I want to upgrade to the new MQX4.0. The problem is that the original project it contains some libs ( allready compiled) with the stdio.h functions and when I compile with the new MQX i received a lots of errors like :

Description    Resource    Path    Location    Type

identifier '_EWL_CDECL' redeclared as 'void'    Test1        line 68, external location: C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\cstdio    C/C++ Problem

identifier '_io_fclose(struct mqx_file *)' redeclared as 'int (struct mqx_file *)'    Test1        line 41, external location: C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\cstdio    C/C++ Problemidentifier '_io_fputc(long, struct mqx_file *)' redeclared as 'int (int, struct mqx_file *)'    Test1        line 57, external location: C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\cstdio    C/C++ Problem

Description    Resource    Path    Location    Type

identifier 'FILE' redeclared was declared as: 'struct mqx_file' now declared as: 'struct _FILE' (included from:        C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\cstdio:27        C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\stdio.h:17        D:\Alexandru Nan\Kinetis K60\CW WorkSpace\Test1\Sources\main.c:7)    Test1        line 100, external location: C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\file_struc.h    C/C++ Problem

undefined identifier '_EWL_END_NAMESPACE_STD'    Test1        line 195, external location: C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\cstdio    C/C++ Problem

undefined identifier '_EWL_IMP_EXP_C'    Test1        line 62, external location: C:\Freescale\CW MCU v10.3\MCU\ARM_EABI_Support\ewl\EWL_C\include\cstdio    C/C++ Problem

etc...

many  errors are related with the _io functions that are described in fio.h from PSP lib. I have tried with

  1. #define MQX_SUPPRESS_STDIO_MACROS 1   but nothing have changed   !

Any suggestion to solve this problem  !




0 Kudos
973 Views
Martin_
NXP Employee
NXP Employee

Attached "my_hello2" project which is standard /mqx/examples/hello2 application, with #include <stdio.h>. It uses MQX for _io_printf() and stdlib.h for snprintf(). I attach also user_config.h that I used to configure MQX 4.0 twrk40x256 BSP. Into user_config.h I add also:

#define MQX_SUPPRESS_FILE_DEF                     1

In my application, I rename all objects that I wish to link with MQX libraries:

printf to _io_printf

ioctl to _io_ioctl

FILE to MQX_FILE

Check the compiler and linker settings of "my_hello2" project. Builds with CodeWarrior for MCUs 10.3.

0 Kudos
973 Views
Nana
Contributor II

Hello again Martin,

I have made the changes that you suggested in user_config.h but now the bsp and psp libs are not compiling anymore. It gives me the next errors:

Description    Resource    Path    Location    Type

illegal implicit conversion from 'int' to 'struct mqx_file *'    tchres.c    /bsp_twrk40x256/Peripheral IO Drivers/tchres    line 301    C/C++ Problem

Description    Resource    Path    Location    Type
undefined identifier 'stdin'    io_misc.c    /psp_twrk40x256/PSP Generic/fio    line 78    C/C++ Problem


And the solution to my problem is not replacing the printf and other functions from stdin and stdlib with MQX proprietary functions because my proprietary "RTCS" lib that I use in my project is already built with this functions !

Anyway thank you for the time given to solve my problem !

0 Kudos
973 Views
Martin_
NXP Employee
NXP Employee

Hi Alexandru,

trying to re-write this suggested solution with other words: whatever you wish to link with MQX, library, it should have MQX specific name. Whatever you wish to link with EWL C, use EWL C name. For example with "stdin", by default both MQX fio.h and EWL C stdio.h define the same name. Thus, in MQX library, (your tchres.c) you should rename "stdin" to "_mqxio_stdin" if you wish to use MQX standard input file stream. And you need to do this in all MQX lib sources, as described above, when building MQX libraries with the two SUPPRESS macros in user_config.h.

Similar with printf() in your application code. If you wish to use MQX printf, then rename it to _io_printf(). If you wish to use  printf() from <stdlib.h> then just #include <stdlib.h> in your application.

This is assuming MQX libraries are built with the two SUPPRESS macros as 1.

974 Views
Martin_
NXP Employee
NXP Employee

Hi Raul,

those are conflict in names, like "stdin" defined by MQX fio.h as well as by EWL C++ header file. The QUEUE is also defined by PSP project as well as by EWL C++. As you have all MQX source codes, a doable solution exist - rename MQX names to be MQX specific, like rename stdin to _mqxio_stdin.

Make sure you enable #define MQX_ENABLE_CPP 1 in user_config.h and configure MQX_SUPPRESS_STDIO_MACROS: in user_config.h:

#define MQX_ENABLE_CPP 1

#define MQX_SUPPRESS_STDIO_MACROS 1

Then replace the original MQX 4.0 PSP fio.h with the attached file fio.h.

now when attempted to build MQX 4.0 libs, a lot of errors due to names occur.

In all MQX library project source files, replace "fopen" by "_io_fopen", then replace "stdin" by "_mqxio_stdin" and replace "stdout" by "_mqxio_stdout". Specifically in PSP, MFS, RTCS and SHELL projects.

Also in "tchres.c" replace "fopen" by "_io_fopen"

PSP

in fio.h

rename definition of stdin, stdout and stderr to _mqxio_stdin, etc., and change fio PSP, RTCS and SHELL usage accordingly.

RTCS

rtcscmd.c, httpd_supp.c, httpd.c, ftpc_cmd.c, rtcs_sh.c, telnet.c, telnsrv.c

"fopen" to "_io_fopen"

many files in SHELL the same change:

fopen to _io_fopen

stdin to _mqxio_stdin

stdout to _mqxio_stdout

When MQX libraries build with these settings we can move on to cplus example.

Cplus example

******************************

Using CW 10.3 New Project Wizard, create New MQX 4.0 project based on cplus example.

In the properties, change librarian of the project from EWL C to EWL C++

add C++ compiler settings include path:

"${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include"

we need both includes paths and move both paths to the last position in C++ compiler search paths settings

"${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include"

"${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C/include"

Attached is the example that can build and execute on my board with MQX 4.0, and CW 10.3. It uses #include <string> and #include <iostream> EWL C++.

_io_printf() is MQX implementation of printf function. Default std::cout stream goes to debug console in CW console window, via semihosting.

If you wish to redirect std::cout stream to MQX serial console, we need to redefine also low level __write_console() function, which is called by the EWL C++ library when it prints characters. For an example you can refer to the attached project.

I notice the default MQX 4.0 linker command files don't have .ARM.extab section (I think C++ exception table?). In case your application needs this, the section will need to be added to the linker command file.

View solution in original post

973 Views
Rick_Li
NXP Employee
NXP Employee

Hi Martin Latal,

follow your steps and building your example project 'my_cplus', one of our customer got the problem (see the attached image).

could you please kindly suggest?

0 Kudos
973 Views
Martin_
NXP Employee
NXP Employee

do you have cplus.cpp source file in your application build project ? In the build output I can see Clean then Build but only console_to_mqx.c source file is built.

MQX template list is defined in cplus.cpp, which seems missing.

Perhaps you have special version of CodeWarrior for MCU ? If I remember correctly you need to have Professional license to unlock C++ compiler (or use time limited Evaluation version).

some update for Freescale MQX 4.1:

Re: MQX C++ project in CodeWarrior

0 Kudos
973 Views
michael_wahler
Contributor III

Hi Martin,

Thanks for your help. I am the customer mentioned above :smileyhappy: I am using CW 10.6 and MQX 4.1. I started from scratch following the instructions from this thread. I've got it almost working, but I have another linker problem.

I followed the instructions from https://community.freescale.com/message/393786#393786 and changed user_config.h and the macro definitions. Afterwards, I rebuilt BSP and PSP successfully. Then I created a new MQX 4.1 project with the "cplus" example.

When changing the directories for the C++ compiler as described here, I noticed that in the automatically generated project, the directories contain "GCC" instead of EABI.

Therefore I changed (I hope that's OK)

  ${MCUToolsBaseDir}/ARM_EABI_Support/ewl/EWL_C++/include

to

  ${MCUToolsBaseDir}/ARM_GCC_Support/ewl/EWL_C++/include

The project derived from "cplus" now builds fine. I can even use STL classes like std::map or std::string, hooray!


However, when I add

  #include <iostream>

to cplus.cpp, there are linker errors:

**** Build of configuration twrk60f120m_Int_Flash_Debug for project cpp41 ****

"C:\\Freescale\\CW MCU v10.6\\gnu\\bin\\mingw32-make" -j8 all

'Building file: ../Sources/cplus.cpp'

'Executing target #1 ../Sources/cplus.cpp'

'Invoking: ARM Ltd Windows GCC C++ Compiler'

"C:/Freescale/CW MCU v10.6/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-g++" "../Sources/cplus.cpp" @"Sources/cplus.args" -Wa,-adhlns="Sources/cplus.o.lst" -MMD -MP -MF"Sources/cplus.d" -o"Sources/cplus.o"

'Finished building: ../Sources/cplus.cpp'

' '

'Building target: cpp41.elf'

'Executing target #2 cpp41.elf'

'Invoking: ARM Ltd Windows GCC C++ Linker'

"C:/Freescale/CW MCU v10.6/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-g++"    @"cpp41.args" -o"cpp41.elf"

In file included from C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/EWL_C++/include/lib_ewl_c++.prefix:12:0,

                 from <command-line>:0:

C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/EWL_C/include/lib_ewl.prefix:16:0: warning: "_EWL_C99" redefined [enabled by default]

../Sources/cplus.cpp:46:1: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/lib/armv7e-m\libstdc++.a(iostream.o): In function `std::char_traits<wchar_t>::copy(wchar_t*, wchar_t const*, unsigned int)':

ARM_GCC_Support/ewl/EWL_C++/../EWL_C++/include/char_traits:246: undefined reference to `wmemcpy'

C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/lib/armv7e-m\libuart.a(uart_console_io.o): In function `__init_uart_console':

ARM_GCC_Support/ewl/EWL_C/src/sys/uart_console_io.c:200: undefined reference to `InitializeUART'

C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/lib/armv7e-m\libuart.a(uart_console_io.o): In function `__read_console':

ARM_GCC_Support/ewl/EWL_C/src/sys/uart_console_io.c:93: undefined reference to `ReadUARTN'

C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/lib/armv7e-m\libuart.a(uart_console_io.o): In function `__init_uart_console':

ARM_GCC_Support/ewl/EWL_C/src/sys/uart_console_io.c:200: undefined reference to `InitializeUART'

C:/Freescale/CW MCU v10.6/MCU/ARM_GCC_Support/ewl/lib/armv7e-m\libuart.a(uart_console_io.o): In function `__write_console':

ARM_GCC_Support/ewl/EWL_C/src/sys/uart_console_io.c:151: undefined reference to `WriteUARTN'

mingw32-make: *** [cpp41.elf] Error 1

I guess I need to override the functions __read_console, __write_console etc. Therefore I copied console_to_mqx.c from your example project into my project. In this file, the function __write_console is defined. However, the linker error stays the same - I expected the last error regarding __write_console to disappear. Can you help?


Kind regards


Michael


0 Kudos
973 Views
raulnorthstar
Contributor II

Hi Martin.

First of all, thanks for your fast and correct answer, it works for me. I have still a question, your last lines talk about C++ exceptions handle:

"I notice the default MQX 4.0 linker command files don't have .ARM.extab section (I think C++ exception table?). In case your application needs this, the section will need to be added to the linker command file."

I've bought the professional edition of CodeWarrior C++ license, specially to use exceptions in my project, it is very important for me. I need to know if really exceptions works with this solution. In case that I need to add this section that you say, how do I have to do it?

Thanks in advance.


0 Kudos
973 Views
Martin_
NXP Employee
NXP Employee

Hi Raul,

in the properties of your project ARM compiler, make sure checkbox "Enable Exceptions" (under Language) is checked.

Then, the code below uses exceptions (try, throw, catch). It won't link due to missing .ARM.extab.

try

{

global.test();

   throw "Completed!";

}

catch (char * str)

{

std::cout << "Exception raised: " << str << std::endl;

}

So I added the .ARM.extab to the linker command file (attached for twrk40x256 BSP). You can copy the lcf into your project directory, such as ${PROJECT_LOC}\Project_Settings\intflash.lcf and change the path to the linker command file in the Linker properties. With this lcf the code builds and executes, exception prints "Exception raised: Completed!" to terminal.

973 Views
patrikčižmár
Contributor II

You are the BEST !!!

Many thanks. This has saved my life ! :-)

0 Kudos
973 Views
raulnorthstar
Contributor II

Hi Martin.

A lot of thanks! All works fine.

0 Kudos