2016-03-21 48 views
0

我在一些安全关键汽车模块中运行代码。下面是代码的一个粗略估计:丢失挥发性限定

在下面的代码是一个模块的一部分 - “主模块”,拥有该易失性可变/数组“x_ast”

Main Module.c 

//The structure x contains the major data that needs to be stored in case of a crash event. i.e. a real car crash 
// x contains data such a vehicle speed, environment data, sensor data, CAN related data,etc. Basically x itself has lot of structures inside it. 


typedef struct x x_tst; 
volatile x_tst x_ast[5]; 
//x_ast is being used in realtime and background functions, considering proper interrupt disabling and enabling. 

在下面的代码是模块的一部分 - “DependentModule”,可以共享缓冲区“x_ast”。

DependentModule.c 

extern volatile x_tst x_ast[5]; 


//x_ast is owned by a separate module 
//Now I need to share this buffer "x_ast" to a different module that will inturn fill data in it for some conditions. Say for a particular condition that is activated, the buffer "x_ast" will be shared across to a module "Conditional Data Record". 
//The base address of first indexed buffer "x_ast[1]" is provided to "Conditional Data Record" for access. 
//The main module will not access the buffer that is shared, once the "Conditional Data Record" is activated/requested. 

// Below is a mechanism to share the buffer "x_ast" to module "Conditional Data Record". 

// This API will be called by module - "Conditional Data Record" once it is activated. It is ensured that this takes place only during intialization of whole system, and no other time. 

boolean GetConditionalBuffer(uint8 **PtrToBuffer) 
{ 
    boolean BufferShared = FALSE; 
    void* Temp_ptr; 
    *PtrToBuffer = NULL; 

// if module "Conditional Data Record" is activated? then share the buffer "x_ast", else do not share the buffer. 

if(Conditional Data Record == activated) { 
    Temp_ptr = (x_tst*)&x_ast[1]; 
    *PtrToBuffer = Temp_ptr; 
    BufferShared = TRUE; 
} 

return BufferShared; 

} 



Referring to the line of code: 
Temp_ptr = (x_tst*)&x_ast[1]; 

的代码(Tempptr =(x_tst *)& x_ast [1])的上面的行抛出一个警告“消息(7:0312)。危险指针铸造导致挥发性资格的损失 “ 上述警告是强制性警告,因此有必要解决它。

我知道我将一个volatile变量的地址赋值给一个void指针,导致volatile限定的丢失。 我尝试了不同的方法试图解决警告,但无法得到确凿的方法。

有没有什么办法,我可以修改代码并删除这个警告,或者可以绕过这个警告。

+1

而不是使用'volatile void ** PtrToBuffer'函数。另一种选择是在不同的缓冲区中完成您的工作,并根据需要将其复制到易失性缓冲区中。后者风险较小。请记住,您将需要锁定缓冲区以防止您自己并发访问以及其中一个后台功能。 –

+0

在“条件数据记录”模块中处理并发条件。确保避免比赛条件。 –

+0

如果你的意思是该函数锁定了缓冲区(并且稍后你将要解锁它),那么使该函数采用'volatile void ** PtrToBuffer'。 (不易挥发uint8_t)。抛出volatile和write会导致未定义的行为,即使你锁定了缓冲区。您需要使用赋值运算符一次读取和写入缓冲区1的值。 –

回答

1

如果您将值分配给易失性对象或在不使用易失性限定指针的情况下读取易失性对象的值,则会出现未定义的行为。

编译器必须以比非易失性对象更严格的方式处理易失性对象(这意味着将非易失性对象当作易失性对象处理很好,将易失性对象视为非易失性对象可以有坏的后果)。

将易失性对象的地址投射到非易失性指针使您面临严重风险。不要这样做。无论谁使用void *指针都会引发未定义的行为。例如,仅使用memcpy复制该易失性数组是未定义的行为。任何事情,通常都是坏事,都可能发生。

声明一个功能

boolean GetConditionalBuffer(volatile x_tst **PtrToBuffer) 

因为挥发性x_tst *是它存储到PtrToBuffer。为什么你会丢弃类型信息?我实际上将其更改为

volatile x_tst* GetConditionalBuffer (void); 

这使得它更容易开发人员的大脑,使功能更容易使用。

+0

这里的另一个依赖是模块“Conditional Data Record”将逐字节访问共享缓冲区“x_ast”。即模块“条件数据记录”需要一个大小为7KB的缓冲器用于其操作。 x_ast [1] ... x_ast [5]:总大小约为8KB。因此,模块“条件数据记录”不会将x缓存作为x_ast使用,而只是将其用作8KB的数组 –