How to call C functions that use "restrict" keyword from C  ?

cancel
Showing results for 
Search instead for 
Did you mean: 

How to call C functions that use "restrict" keyword from C  ?

Jump to solution
1,859 Views
surrealist14
Contributor III

Hi folks,

 

I'm using KSDK1.1.0 and a Kinetis K60DM100 tower board.  I'm also using the IAR Embedded Workbench for ARM Cortex-M, V7.40.2.

 

I am trying to write as much of my code as possible in C++ for a variety of reasons, including re-use of some code that was already developed.

 

One of the classes I have tried to create is a SPIMaster.  To initialize the SPI master and do transfers, I need to call some of the provided DSPI_DRV_* functions from the KSDK,  Unfortunately, some of the fields in various types from fsl_dspi_master_driver.h have the "restrict" keyword, which is a valid keyword in C, but apparently not in C++.

 

A small example:

SPIMaster.cpp

 

// Turn off name mangling for this C header

#if defined(__cplusplus)

extern "C" {

#endif /* __cplusplus */

    #include "fsl_dspi_master_driver.h"

#if defined(__cplusplus)

}

#endif /* __cplusplus */

 

// C++ member functions etc.

 

Included from fsl_dspi_master_driver.h:

 

typedef struct DspiMasterState {

    dspi_ctar_selection_t whichCtar; /*!< Desired Clock and Transfer Attributes Register (CTAR)*/

    uint32_t bitsPerFrame;         /*!< Desired number of bits per frame */

    dspi_which_pcs_config_t whichPcs; /*!< Desired Peripheral Chip Select (pcs) */

    bool isChipSelectContinuous;  /*!< Option to enable the continuous assertion of chip select

                                       between transfers*/

    uint32_t dspiSourceClock;              /*!< Module source clock*/

    volatile bool isTransferInProgress;             /*!< True if there is an active transfer.*/

    const uint8_t * restrict sendBuffer;  /*!< The buffer from which transmitted bytes are taken.*/ <<<This is line 79

    uint8_t * restrict receiveBuffer;     /*!< The buffer into which received bytes are placed.*/ <<<This is line 80

<snip>

 

When I try to compile SPIMaster.cpp, I get the following errors:

 

The line "const uint8_t * restrict sendBuffer;" fails with

Error[Pe065]: expected a ";"

The line right after that fails with

Error[Pe101]:"restrict" has already been declared in the current scope (at line 79)

 

Basically, this means that for any headers that contain the "restrict" keyword, I cannot use or call them directly from within C++ without compile errors.  The only way I have thought of to circumvent this is to create a separate .c file that "wraps" the function I need and includes the necessary fsl_* header.  E.g.:

 

In new .c file:

    #include "fsl_dspi_master_driver.h"

 

bool Wrap_DSPI_DRV_MasterInit(uint32_t instance, dspi_master_state_t * dspiState, const dspi_master_user_config_t * userConfig)

{

     dspi_status_t status = DSPI_DRV_MasterInit(instance, dspiState, userConfig);

     if (kStatus_DSPI_Success == status)

          return true;

     else

          return false;

}

 

Then in my .cpp file, I can call the new wrapper function without having to include fsl_dspi_master_driver.h:

In .cpp file

extern "C" {

bool Wrap_DSPI_DRV_MasterInit(uint32_t instance, dspi_master_state_t * dspiState, const dspi_master_user_config_t * userConfig);

}

 

<snip>

   bool status = Wrap_DSPI_DRV_Master(instance, dspiState, userConfig);

 

I just noticed this won't quite work as is, because dspi_master_state_t and dspi_master_user_config_t are defined in the offending .h file.  I guess I would have to wrap them, too, in some new type of struct that doesn't depend on these types directly. The wrapper function in the .c file would have to take other parameters and fill these structures in before making the call to the driver library.

 

Has anyone else run into this problem trying to use the driver library from C++?  If so, how did you overcome it?  Clearly it works if everything is in C, because the whole ksdk_platform_lib project builds OK.

 

Thanks for your help,

 

Scott

Labels (1)
0 Kudos
1 Solution
681 Views
surrealist14
Contributor III

Hi David,

You may not be a C++ guy, but your idea was still very helpful.  I had sent out a description of the problem to my coworkers, and one of them suggested something stunningly simple:  use the preprocessor like:

#define restrict

Basically, redefine the keyword as nothing.  You'd have to do this both in the ksdk_platform_lib and in your own project, or maybe there would be side effects because of the different function signatures (and maybe because of optimizations that could happen with the restrict keyword).  I tried it in my code, putting this statement at the very top of my .h file, and it worked.

Then I talked with support at IAR, and was informed (based on your Wikipedia link) that IAR also has an option to support the restrict keyword.  In Options/C/C++ Compiler/Extra Options, check the box that says "Use command line options", then add the following line:

--enable_restrict

Once I did that, I was able to compile my C++ code without any warnings or errors, without having to re-define restrict to nothing.

I wanted to share this back to the community in the hope that someone else might benefit from this way to be able to include KSDK headers in your C++ code.

Many thanks for your help,

Scott

View solution in original post

0 Kudos
15 Replies
681 Views
DavidS
NXP Employee
NXP Employee

Hi Scott,

I'm not a C++ guy but hope some day to be much better.  Hopefully a C++ guru will also reply.

I did find following info: restrict - Wikipedia, the free encyclopedia

C++ does not have standard support for restrict, but many compilers have equivalents which usually work in both C++ and C, such as the GNU Compiler Collection __restrict__ and Visual C++ __restrict and __declspec(restrict).

Maybe this will help...

Regards,

David

682 Views
surrealist14
Contributor III

Hi David,

You may not be a C++ guy, but your idea was still very helpful.  I had sent out a description of the problem to my coworkers, and one of them suggested something stunningly simple:  use the preprocessor like:

#define restrict

Basically, redefine the keyword as nothing.  You'd have to do this both in the ksdk_platform_lib and in your own project, or maybe there would be side effects because of the different function signatures (and maybe because of optimizations that could happen with the restrict keyword).  I tried it in my code, putting this statement at the very top of my .h file, and it worked.

Then I talked with support at IAR, and was informed (based on your Wikipedia link) that IAR also has an option to support the restrict keyword.  In Options/C/C++ Compiler/Extra Options, check the box that says "Use command line options", then add the following line:

--enable_restrict

Once I did that, I was able to compile my C++ code without any warnings or errors, without having to re-define restrict to nothing.

I wanted to share this back to the community in the hope that someone else might benefit from this way to be able to include KSDK headers in your C++ code.

Many thanks for your help,

Scott

View solution in original post

0 Kudos
681 Views
DavidS
NXP Employee
NXP Employee

Hi Scott,

Wow...I got lucky...must be Friday!

Thank you for sharing your findings to help one and all (and my efforts to learn C++).

Regards,

David

0 Kudos
681 Views
dave408
Senior Contributor II

DavidS​ do you have any advice / documentation for getting a C++ app written for the Kinetis processors?  From what I can recall, under KSDK 1.1, I had just renamed main.c to main.cpp and then went from there -- but because there were some KSDK issues, I was told to wait for 1.2.  Now that 1.2 is out, I'm trying my luck with C++ again, but am getting tons of errors when I try to compile an empty Kinetis project after renaming main.  Any info you have, or even a demo app that you might have, would be really helpful and greatly appreciated!  Thank you!

Oh, and I am currently running KDS 3.0.

0 Kudos
681 Views
surrealist14
Contributor III

Hi Dave,

I have just downloaded 1.2, so I don't know if I'm going to run into trouble, too.  Let me try a simple example with 1.2 and see if I can get it to build as C++, and I'll let you know.  Are you using the IAR tools?  I hope so, because that's all I have available to me at the moment...

Will get back to you ASAP.

Scott

0 Kudos
681 Views
dave408
Senior Contributor II

Thanks, Scott!  I am not using IAR, I am using the gnu tools that come with KDS 2.0 / 3.0.

0 Kudos
681 Views
surrealist14
Contributor III

Dave, I just tried building the hello world demo for the K60D100.  I made a copy of the whole directory, then opened the project from there, but using IAR's tools.  First I built the platform library, then I built the hello_world application, and everything built and linked without errors.

I then opened main.c and simply did a "save as" main.cpp.  I then removed main.c from the hello_world project, and added main.cpp, and did a Rebuild all on the project.  It built and linked without errors...

I'm using a J-Link debugger from Segger, so I modified the project options to select that debugger instead of the default PE Micro.  Once I did that, I was able to download the application to the K60 tower and see that it has stopped at int main(void), as expected.  Stepping into the hardware initialization, I was able to get the hardware timer to start blinking the orange LED, but noticed that it was initializing the wrong UART for me.  I have a TWR-SER board which uses UART3, so I would probably have to modify the board.h file and rebuild to get serial I/O working.

I didn't take it that far, but I guess the basic point is that a simple application with a main.cpp built and could run, with essentially no changes.  Maybe if you post or send me some of the errors you are getting, I could think of something for you to try.  If you want to take this offline, I can send you an e-mail address for us to chat, or we could do something via Skype for Business.

Hoping this helps.  Looks like you _should_ be able to build something with C++ without excessive pain, but I need more specifics to help further.

Scott

0 Kudos
681 Views
dave408
Senior Contributor II

I'm having horrible luck with this in KDS 3.0.  I built platform lib and then hello_world, and that worked fine.  I couldn't do a save as since the project uses virtual folders, so I just created a copy of main.c and then renamed it to main.cpp.  Then I deleted the reference to main.c and added main.cpp.  It was obvious that there would be a problem here because when I double-click main.cpp, KDS tells me that the file doesn't exist, even though there's no ! on the icon.

I have tried hand-modifying .project to make it point to the right spot.  I basically just copied the locationURI tag from fsl_lptmr_irq.c since that file is physically in the same location as main.cpp.  However, it still doesn't like it and won't build...

0 Kudos
681 Views
surrealist14
Contributor III

Hi Dave,

Sorry, I do not know KDS 3.0 at all.  Maybe this problem needs to be posted to a new question so more people can see it?

Wish I could help,

Scott

0 Kudos
681 Views
dave408
Senior Contributor II

Ok, I'm an idiot.  I just realized that the C++ compiler settings was missing the processor definition!  Compiles and runs now, so I'll go back to helloworld and test it there!

0 Kudos
681 Views
surrealist14
Contributor III

I wouldn't be TOO hard on yourself.  :smileywink:Seems like a very common thing that could be easily overlooked.  Congratulations on solving the mystery, and hopefully it will helps someone else who got stuck on a similar C++ conversion.

Enjoy the weekend,

Scott

0 Kudos
681 Views
dave408
Senior Contributor II

Yeah, hopefully it'll help someone else out!  That's what's so great about these forums.  You just never know if someone will make a mistake and figure out what has been your own problem as well!  Can't enjoy the weekend, now that it looks like C++ is going to finally work, I have to take all of my work I've done in C and port it back to C++ again.  It's well worth the effort.  I just hope there aren't any sudden gotchas along the way that prevent me from using C++.

0 Kudos
681 Views
dave408
Senior Contributor II

Thanks, Scott, no worries.  :smileyhappy:  Yeah, I was just trying to find related posts here while trying not to hijack threads.  Didn't want to pollute the forum with too many new posts.  But yeah, I'll probably have to create a new one!

0 Kudos
681 Views
dave408
Senior Contributor II

Scott, thank you very much for going through the trouble of trying that out for me.  I'll give it a go and will post up my results.  Thanks again!

0 Kudos
681 Views
surrealist14
Contributor III

David,

Sometimes "luck" is actually "skill" that has had some real-world education!  I have to test and prove all of this, but it really does look promising, and I appreciate the tip.  I also think that the #define trick would work as long as you rebuild the KSDK the same way.

Happy Friday and have a great weekend,

Scott

0 Kudos