AnsweredAssumed Answered

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

Question asked by Scott Whitney on Apr 23, 2015
Latest reply on May 16, 2015 by dave408

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

Outcomes