Hi there,
I'm starting a new C++ project with LPC5526. Further I'm using CMSIS USART drivers for the first time.
My problem:
This simple assignment (in my code at line no. 65) fails:
ARM_USART_STATUS status1 = FLEXCOMM0_PERIPHERAL.GetStatus();
The compiler emits three error messages:
../source/LPC55S28_Project_CMSIS-Test.cpp: In function 'int main()':
../source/LPC55S28_Project_CMSIS-Test.cpp:65:60: error: no matching function for call to '_ARM_USART_STATUS(ARM_USART_STATUS)'
65 | ARM_USART_STATUS status1 = FLEXCOMM0_PERIPHERAL.GetStatus();
and
...\workspace\LPC55S28_Project_CMSIS-Test\CMSIS_driver/Driver_USART.h:155:25: note: conversion of argument 1 would be ill-formed:
../source/LPC55S28_Project_CMSIS-Test.cpp:65:59: error: binding reference of type 'const _ARM_USART_STATUS&' to 'ARM_USART_STATUS' {aka 'volatile _ARM_USART_STATUS'} discards qualifiers
65 | ARM_USART_STATUS status1 = FLEXCOMM0_PERIPHERAL.GetStatus();
I
and
...\workspace\LPC55S28_Project_CMSIS-Test\CMSIS_driver/Driver_USART.h:155:25: note: conversion of argument 1 would be ill-formed:
../source/LPC55S28_Project_CMSIS-Test.cpp:65:59: error: binding reference of type '_ARM_USART_STATUS&&' to 'ARM_USART_STATUS' {aka 'volatile _ARM_USART_STATUS'} discards qualifiers
65 | ARM_USART_STATUS status1 = FLEXCOMM0_PERIPHERAL.GetStatus();
All error messages relate to this assignment in line 65.
To reproduce:
Any ideas? Thanks!
Solved! Go to Solution.
Hi,
this issue seems fixed.
I just had a look at SDK_2.x_LPC5526 2.13.0 (after I installed MCUXpresso IDE 11.7.0).
Now CMSIS Driver_USART.h is included as V2.4, i.e., with volatile dropped from ARM_USART_STATUS and ARM_USART_MODEM_STATUS.
This case replied on salesforce.
Hello Daniel.
Not recommend remove "volatile".How about assign data separately:
status1.rx_busy = FLEXCOMM0_PERIPHERAL.GetStatus
status1.tx_busy = FLEXCOMM0_PERIPHERAL.GetStatus
Hello Alice,
Thank you for your reply.
Why do you recommend not to remove "volatile"? Please advise.
What was the reason for adding "volatile" to the struct? The struct is returned by value (copied), so "volatile" seems superfluous.
Why not move the "volatile" declaration to each member instead? I suggested this earlier but you did not respond to it.
I appreciate your support and I'm looking forward to your response.
Best regards,
Daniel
Hello,
How about directly use C project,
Hello Daniel,
It seems this is a C++ grammar issue, have a look at:
https://stackoverflow.com/questions/50274013/binding-to-reference-of-type-discards-qualifiers
BR
Alice
Hi Alice,
I'm pretty sure that it's not a "C++ grammar issue". I checked your references and I think they don't apply here.
The issue arises because the C++ compiler employs a stricter type checking. Further, the implicitly created constructor does not support copying volatile values.
See:
https://stackoverflow.com/questions/49367852/volatile-struct-struct-not-possible-why
Solution: remove "volatile" qualifier from typedef. See also my other posting, please.
Best regards,
Daniel
For your information, ARM_USART_STATUS is defined in "CMSIS_driver/Driver_USART.h" as follows
typedef volatile struct _ARM_USART_STATUS {
uint32_t tx_busy : 1; ///< Transmitter busy flag
uint32_t rx_busy : 1; ///< Receiver busy flag
uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)
uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation)
uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation)
uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation)
uint32_t reserved : 25;
} ARM_USART_STATUS;
I can query specific members directly, e.g.,
uint32_t busy = FLEXCOMM0_PERIPHERAL.GetStatus().tx_busy;
This compiles without errors.
Hello everybody,
I checked the original source files on Github that served as templates for NXP's CMSIS drivers.
The type ARM_USART_STATUS is defined in this file:
https://github.com/ARM-software/CMSIS_5/blob/master/CMSIS/Driver/Include/Driver_USART.h
and the definition omits the volatile qualifier.
The changelog reads:
/* History:
* Version 2.4
* Removed volatile from ARM_USART_STATUS and ARM_USART_MODEM_STATUS
* Version 2.3
* ARM_USART_STATUS and ARM_USART_MODEM_STATUS made volatile
/*
I'd appreciate if you'd forward this information to the SDK team.
Thanks.
Best regards,
Dan
Hi,
this issue seems fixed.
I just had a look at SDK_2.x_LPC5526 2.13.0 (after I installed MCUXpresso IDE 11.7.0).
Now CMSIS Driver_USART.h is included as V2.4, i.e., with volatile dropped from ARM_USART_STATUS and ARM_USART_MODEM_STATUS.
Hi everybody,
If the "volatile" qualifier from ARM_USART_STATUS is removed, the program compiles.
I wonder why "volatile" had been added to this struct in the first place. Usually it's required when a variable may be changed from outside of the current execution flow (i.e., memory mapped registers, interrupt service routines, multithreading). I don't see why it's needed here.
Further, if need be, volatile could be added to specific members that require the use of the "volatile" qualifier, i.e.:
typedef struct _ARM_USART_STATUS {
volatile uint32_t tx_busy : 1; ///< Transmitter busy flag
volatile uint32_t rx_busy : 1; ///< Receiver busy flag
volatile uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)
volatile uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
volatile uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation)
volatile uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation)
volatile uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation)
uint32_t reserved : 25;
} ARM_USART_STATUS;
This compiles, too.