我一直在使用微处理器来读取传感器的温度,并且遇到有关挥发性声明的以下警告。
“赋值从指针目标类型中丢弃'volatile'限定符”
我收到一个温度值,在重新启动程序之前,值不会改变。
volatile uint16_t temp_value = 0;
if (value_type == UA_TYPE_UInt16)
{
data_value.value_UInt16 = &temp_value; // warning*******
switch (handle)
{
case HANDLE_TEMP1:
temp_value = ADC_GetConversionValue(ADC3);
break;
}
}
在搜索堆栈溢出后,我意识到将temp_value声明为volatile将表示temp_value将更改值。我在这个网站上找不到的是为什么我不能为data_value.value_UInt16使用volatile无符号整数
我将ADC值存储在服务器中,并希望随时访问更新后的值。是否有一个额外的类型转换我应该指向temp_value?谢谢阅读。
答案 0 :(得分:8)
您的volatile uint16_t temp_value
对编译器说了#34;我的变量temp_value
可能会被您不知道的事情所改变" (特别是,访问和写入用于存储变量的内存的其他进程)。除此之外,它还会阻止编译器进行某些优化。
当你这样做时:
data_value.value_UInt16 = &temp_value;
(我认为value_UInt16
是非易变的)
您将volatile
的地址分配给非易失性字段:编译器警告您允许对其进行优化,忽略可能会更改指针对象& #34;它不知道"。
解决方案:
1)Typecast data_value.value_UInt16 = *(uint16_t*)&temp_value
,对编译器说:"我知道我在做什么,我知道我在这里忽略了挥发性限定符"。
或者,
2)同时将value_UInt16
volatile
字段设为
重要提示:
您标记了C ++和C但是:
答案 1 :(得分:1)
Volatile的工作方式与const的工作方式大致相同。这段代码
const int i = 1;
int* iPtr = &i; //error
无效,因为它尝试将指向const的指针指定给指向非const的指针。 类似地,
volatile int i = 1;
int* iPtr = &i; //error
除了volatile之外,因同样的原因无效。虽然您的示例不完整,但这就是问题所在。
答案 2 :(得分:0)
您应该添加embedded
标记。
除非您可以让链接器将变量分配给特定地址,否则应始终通过指针或引用访问硬件:
// Using linker notation:
volatile uint16_t temperature @ "temperature_segment";
// Using pointer, pointer to a volatile uint16_t
uint16_t volatile * temperature = 0x44000025; // Example address
// Because the variable is a pointer to a volatile value,
// a "snapshot" copy should be made before using.
uint16_t snapshot_temperature = *temperature;
if (snapshot_temperature > 100 /* celsius */)
{
SYSTEM_FAILURE(TEMPERATURE_OVERHEATING);
}
volatile
关键字指示编译器避免优化与温度变量相关的代码。此外,由于目标值(硬件寄存器)可能会更改,因此应在进行任何比较之前进行快照复制。
答案 3 :(得分:0)
我打开了data_value.value_UInt16的声明,以找到有关该类型的更多信息,因为问题是它接受的类型不是我设置的类型等于。事实证明它只接受在另一个头文件中预定义的数据类型。
要解决这个问题,我只需查看它会接受的类型并插入其中一个,如下所示;
typedef enum
{
UA_TYPE_Invalid = 0, /**< Invalid type */
UA_TYPE_Boolean = 1, /**< Boolean */
UA_TYPE_SByte = 2, /**< signed byte */
UA_TYPE_Byte = 3, /**< unsigned byte */
UA_TYPE_Int16 = 4, /**< signed 16 bit integer */
UA_TYPE_UInt16 = 5, /**< unsigned 16 bit integer */
UA_TYPE_Int32 = 6, /**< signed 32 bit integer */
UA_TYPE_UInt32 = 7, /**< unsigned 32 bit integer */
UA_TYPE_Int64 = 8, /**< signed 64 bit integer */
UA_TYPE_UInt64 = 9, /**< unsigned 64 bit integer */
UA_TYPE_Float = 10, /**< 32 bit single precision floating point */
UA_TYPE_Double = 11, /**< 64 bit double precision floating point */
UA_TYPE_String = 12, /**< UTF8 string */
UA_TYPE_DateTime = 13, /**< 64 bit signed integer containing date and time */
UA_TYPE_Guid = 14, /**< 16 byte long array of unsigned bytes */
UA_TYPE_ByteString = 15, /**< variable length array of unsigned bytes */
UA_TYPE_XmlElement = 16, /**< UTF8 string containing XML */
UA_TYPE_NodeId = 17, /**< Not supported for application */
UA_TYPE_ExpandedNodeId = 18, /**< Not supported for application */
UA_TYPE_StatusCode = 19, /**< Not supported for application */
UA_TYPE_QualifiedName = 20, /**< Not supported for application */
UA_TYPE_LocalizedText = 21, /**< Not supported for application */
UA_TYPE_ExtensionObject = 22, /**< Not supported for application */
UA_TYPE_DataValue = 23, /**< Not supported for application */
UA_TYPE_Variant = 24, /**< Not supported for application */
UA_TYPE_Range = 884,/**< Not supported for application */
UA_TYPE_EUInformation = 887 /**< Not supported for application */
} UA_Value_type_t;
uint16_t server_value = 0;
if (value_type == UA_TYPE_UInt16)
{
data_value.value_UInt16 = &server_value;
source_timestamp = my_variables[handle - 1].source_timestamp;
status_code = my_variables[handle - 1].status_code;
ADC_SoftwareStartConv(ADC3);