大家好、我有一个关于将 volatile 与 CPU 和 CLA 之间共享的变量一同使用的编译器问题。 我已经构建了一个包含三个文件的简单示例:
cla_shared.c 声明两个浮点变量、一个在 CLA 到 CPU 消息 RAM 中、另一个在 CPU 到 CLA 消息 RAM 中:
// cla_shared.c
// shared variables with cpu
// in cpu2cla message RAM
#pragma SET_DATA_SECTION("SCRATCH_CPU1TOCLA1")
volatile float iir_input_cpu2cla=0;
// in cla2cpu message RAM
#pragma SET_DATA_SECTION("SCRATCH_CLA1TOCPU1")
volatile float iir_output_cla2cpu;
clatasks.cla 具有 CLA 任务1代码。 CLA 任务采用 iir_input_cpu2cla、并将其传递给一个 IIR 滤波器、其输出为 iir_output_cla2cpu:
// clatasks.cla
// shared variables with cpu
// in cpu2cla message RAM
extern volatile float iir_input_cpu2cla;
// in cla2cpu message RAM
extern volatile float iir_output_cla2cpu;
// local variables for CLA only
float IIR_SR[6];
float IIR_B[4];
float IIR_A[4];
// cla task 1 is triggered by ePWM interrupt
interrupt void Cla1Task1(void) {
iir_output_cla2cpu = iir_input_cpu2cla*IIR_B[0] + IIR_SR[5];
IIR_SR[4] = iir_input_cpu2cla*IIR_B[1] + iir_output_cla2cpu*IIR_A[1] + IIR_SR[3];
IIR_SR[5] = IIR_SR[4];
IIR_SR[2] = iir_input_cpu2cla*IIR_B[2] + iir_output_cla2cpu*IIR_A[2] + IIR_SR[1];
IIR_SR[3] = IIR_SR[2];
IIR_SR[0] = iir_input_cpu2cla*IIR_B[3] + iir_output_cla2cpu*IIR_A[3];
IIR_SR[1] = IIR_SR[0];
// trigger the CPU ISR
CLA_forceSoftwareInterrupt(CLA1SOFT_IN_REGS, 1);
}
cpuisr.c 具有 CPU ISR 代码。 它每次迭代都会更改 iir_input_cpu2cla (制作一个正弦波)、然后根据 iir_input_cpu2cla 和 iir_output_cla2cpu 的值执行某些函数:
// cpuisr.c
// shared variables with cpu
// in cpu2cla message RAM
extern volatile float iir_input_cpu2cla;
// in cla2cpu message RAM
extern volatile float iir_output_cla2cpu;
// cpu-only variables in GSRAM
float time=0.0;
// CPU ISR is triggered by CLA task 1, software force interrupt
interrupt void CPU_ISR(void) {
time+=1.0;
iir_input_cpu2cla=sin(idx*2*3.14159/1000.0);
if(iir_output_cla2cpu>0.5) {
// stuff depending on iir_output_cla2cpu
}
if(iir_output_cla2cpu<-0.5) {
// stuff depending on iir_output_cla2cpu
}
if(iir_input_cpu2cla>0.5) {
// stuff depending on iir_input_cpu2cla
}
if(iir_input_cpu2cla<-0.5) {
// stuff depending on iir_input_cpu2cla
}
// ack the pie
PieCtrlRegs.PIEACK.all = PIEACK_GROUP11;
}
CLA 任务是定期触发的(例如、由 ePWM 中断触发)。 在 CLA 任务的末尾,它通过 CLA_forceSoftwareInterrupt ()触发 CPU ISR。 因此、CLA 任务和 CPU ISR 以锁步方式执行。 我们假定 CPU ISR 一直在下一个 CLA 任务开始前返回、这意味着它们永远不会同时执行。
我的问题是、使共享变量 iir_input_cpu2cla 和 iir_output_cla2cpu volatile 是否必要/合适。 如果我知道任务/ISR 永远不会在另一个正在运行时执行、那么在两次访问之间不会有变量改变的风险。 但是、如果变量被 限定为 volatile、那么我担心性能会受到不必要的 RAM 访问的影响。 例如、ClaTask1只需要从 iir_input_cpu2cla 读取一次 并且只需要对 iir_output_cla2cpu 写入一次、但是易失性可能会导致生成的代码每读取一次额外的三倍。 类似地、CPU_ISR 应该只需要对 iir_input_cpu2cla 执行一次写入操作 、并需要对 iir_output_cla2cpu 执行一次读取操作、但是易失性可能会使每个读取操作额外读取两次。
但是、如果删除 volatile 限定符、是否存在根本无法读取这些限定符的风险?
此致、
迈克