我回答了关于std :: vector of objects和const-correctness的问题,得到了不应有的 downvote和关于undefined行为的评论.我不同意,因此我有一个问题.
考虑使用const成员的类:
class A {
public:
const int c; // must not be modified!
A(int c) : c(c) {}
A(const A& copy) : c(copy.c) { }
// No assignment operator
};
Run Code Online (Sandbox Code Playgroud)
我想要一个赋值运算符,但我不想const_cast在下面的代码中使用其中一个答案:
A& operator=(const A& assign)
{
*const_cast<int*> (&c)= assign.c; // very very bad, IMHO, it is undefined behavior
return *this;
}
Run Code Online (Sandbox Code Playgroud)
我的解决方案是
A& operator=(const A& right)
{
if (this == &right) return *this;
this->~A()
new (this) A(right); …Run Code Online (Sandbox Code Playgroud) 通过“原子访问防护”或“中断防护”强制对与 ISR 共享的易失性变量进行原子访问的标准技术,特别是在没有操作系统的情况下运行裸机、单线程协作多任务应用程序时,如下所示:
// 1. save interrupt state
// 2. disable only the interrupts necessary
// You get atomic access to volatile variables shared with ISRs here,
// since ISRs are the only other "context" or running "thread" which
// might attempt to modify a shared memory block or variable.
// 3. restore interrupt state
Run Code Online (Sandbox Code Playgroud)
另请参阅我在这里详细描述的地方,包括最佳实践(在短时间内保持中断关闭)以及如何通过我的doAtomicRead()重复读取循环函数进行原子读取而不首先禁用中断:读取 64 位变量,即由 ISR 更新。
我之前已经记录过如何对 AVR 微控制器/Arduino 执行此操作:How do I Forceatomity in Atmel AVR mcus/Arduino? …
以下是STM32微控制器上的数据类型:http : //www.keil.com/support/man/docs/armcc/armcc_chr1359125009502.htm。
这些微控制器使用32位ARM核心处理器。
哪些数据类型具有自动原子读取和原子写入访问权限?
我很确定所有32位数据类型都可以(因为处理器是32位),而所有64位数据类型都不能(因为要读或写一个64位字至少需要2个处理器操作),但是bool(1个字节)和uint16_t/ int16_t(2个字节)呢?
上下文:我正在STM32上的多个线程(在FreeRTOS中称为单核,但有多个线程或称为“任务”)之间共享变量,并且需要知道是否需要通过使用中断关闭中断来强制进行原子访问互斥锁等
更新:
参考此示例代码:
volatile bool shared_bool;
volatile uint8_t shared u8;
volatile uint16_t shared_u16;
volatile uint32_t shared_u32;
volatile uint64_t shared_u64;
volatile float shared_f; // 32-bits
volatile double shared_d; // 64-bits
// Task (thread) 1
while (1)
{
// Write to the values in this thread.
// What I write to each variable will vary. Since other threads
// are reading these values, I need to …Run Code Online (Sandbox Code Playgroud) 我的具体上下文是 STM32 ARM M0,但问题更笼统。
读取或写入内存映射外设(例如 GPIO 端口或串行端口缓冲区)的内容与物理 RAM 中的位置是否需要相同数量的时钟?这是否因架构而异?
我只是失去了几天,从字面上看,大约25个小时的工作,因为我试图调试我的代码而不是我不知道的简单.
事实证明,在C++中减少单字节数组的元素,在AVR上,ATmega328 8位微控制器(Arduino)不是原子操作,需要原子访问保护(即关闭中断).为什么是这样???此外,在Atmel AVR微控制器上确保原子访问变量的所有C技术是什么?
这是我所做的一个愚蠢的版本:
//global vars:
const uint8_t NUM_INPUT_PORTS = 3;
volatile uint8_t numElementsInBuf[NUM_INPUT_PORTS];
ISR(PCINT0_vect) //external pin change interrupt service routine on input port 0
{
//do stuff here
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
numElementsInBuf[i]++;
}
loop()
{
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
{
//do stuff here
numElementsInBuf[i]--; //<--THIS CAUSES ERRORS!!!!! THE COUNTER GETS CORRUPTED.
}
}
Run Code Online (Sandbox Code Playgroud)
这是循环的版本,没关系:
loop()
{
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
{
//do stuff here
noInterrupts(); //globally disable interrupts
numElementsInBuf[i]--; //now it's ok...30 hrs of …Run Code Online (Sandbox Code Playgroud)