This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CODECOMPOSER:将 Volatile 与 CLA 和 CPU 中断结合使用

Guru**** 2022830 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1284917/codecomposer-use-of-volatile-with-cla-and-cpu-interrupts

器件型号:CODECOMPOSER

大家好、我有一个关于将 volatile 与 CPU 和 CLA 之间共享的变量一同使用的编译器问题。 我已经构建了一个包含三个文件的简单示例:

cla_shared.c 声明两个浮点变量、一个在 CLA 到 CPU 消息 RAM 中、另一个在 CPU 到 CLA 消息 RAM 中:

Fullscreen
1
2
3
4
5
6
7
8
9
// 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;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

clatasks.cla 具有 CLA 任务1代码。 CLA 任务采用 iir_input_cpu2cla、并将其传递给一个 IIR 滤波器、其输出为 iir_output_cla2cpu:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 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];
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

cpuisr.c 具有 CPU ISR 代码。 它每次迭代都会更改 iir_input_cpu2cla (制作一个正弦波)、然后根据 iir_input_cpu2cla 和 iir_output_cla2cpu 的值执行某些函数:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 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) {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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 限定符、是否存在根本无法读取这些限定符的风险?

此致、

迈克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有关 易失性 variable 时、编译器需要生成代码、该代码假设可以通过系统中的某些其他方式随时读取或写入该变量。  假设有一系列语句、您知道这是不可能的。  就在语句范围之前、复制 易失性 转换为正常的局部变量。  在该 RANGE 语句中、请改用普通局部变量。  在该语句范围之后、将该普通局部变量复制到 易失性 成正比。

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、感谢您的快速响应。

    我还考虑将消息 RAM 中的易失性变量复制到非易失性局部变量作为权变措施。 听起来是一种非常安全的方法、但还有其他方法吗? 在我的实际代码中、有很多共享变量、在开始和结束时复制所有这些变量的时间很长。ISR/任务。

    此致、

    迈克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    也许这个想法使它实际... 将所有共享变量收集到一个结构中。  创建两个结构实例。  一个是易失性的、另一个不易失。  根据需要在它们之间复制。  使用简单的结构分配实现副本...

    non_volatile_instance = volatile_instance;

    依赖编译器优化该副本。   

    谢谢。此致、

    -乔治