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.

[参考译文] CCS/TMS320F28379D:CLA 启动

Guru**** 2536600 points
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/592635/ccs-tms320f28379d-staring-with-cla

器件型号:TMS320F28379D
Thread 中讨论的其他器件:controlSUITEC2000WARE

工具/软件:Code Composer Studio

你好

使用 controlSUITE->device support -> F28379D 下提供的示例和技术参考手册、我成功了解了 PWM 和 ADC 的工作原理。
现在、我想将 CLA 包含在我的程序中以计算控制律。

在技术参考手册中、他们说您应该执行以下六个步骤:

1)将 CLA 代码复制到 CLA 程序 RAM 中
2)如有必要、初始化 CLA 数据 RAM
3)配置 CLA 寄存器
4)初始化 PIE 矢量表和寄存器
5)启用 CLA 任务/中断
6)初始化其它外设

我尝试在提供的示例中检索这些步骤、但我在使用 CLA 时遇到了很多困难。 是否可以提供显示所有这些步骤的示例? 是否提供了一些函数来方便地用于此目的?

我想将 CLA 用于电力电子转换器中的 PI 控制环路。

此致

Simon

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    controlSUITE 和 C2000Ware 软件包中提供了 CLA 示例。 CLA 示例演示了这一点。

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

    你好 Sal

    很抱歉我迟到了。 在我继续使用 CLA 之前、我首先必须安排一些其他事情

    因此、为了继续我的问题、我尝试查看这些示例、但我并不真正了解它的工作原理。

    在下面、我为 F28379D 粘贴了 CLA_vminfloat 示例的代码。

    您能告诉我前两个步骤的位置吗

    1)将 CLA 代码复制到 CLA 程序 RAM 中
    2)如有必要、初始化 CLA 数据 RAM

    发生、因为我看不到它是如何发生的。 (抱歉、我没有编程背景)

    此致、感谢您的帮助

    Simon

    //######################################################################################################################
    //文件:  cla_vminfloat_cpu01.c
    //标题: F2837xD 的最小矢量示例。
    //
    //! addtogroup cpu01_example_list
    //!

    CLA 矢量最小值(cla_vminfloat_cpu01)


    //!
    //! 任务1计算向量最小值、该向量最小值向后移动穿过数组。 \n
    //! 任务2计算在数组中向前移动的向量最小值。 \n
    //! 任务3使用三元运算符计算向量最小值。 \n
    //!
    //! b 内存\b 分配\n
    //!  - CLA1至 CPU 消息 RAM
    //!    - min1 -向量1中的最小值
    //!    - index1 -向量1中最小值的索引
    //!    - min2 -向量2中的最小值
    //!    -索引2 -向量2中最小值的索引
    //!    - min3 -向量3中的最小值
    //!    -索引3 -向量3中最小值的索引
    //!  - CPU 至 CLA1消息 RAM
    //!    -矢量1 -任务1的输入矢量
    //!    -矢量2 -任务2的输入矢量
    //!    -矢量3 -任务3的输入矢量
    //!    -长度1 -向量1的长度
    //!    - length2 -向量2的长度
    //!    - length3 -向量3的长度
    //!
    //! b 监视\b 变量\n
    //! -矢量1 -任务1的输入矢量
    //! -矢量2 -任务2的输入矢量
    //! -矢量3 -任务3的输入矢量
    //! -最小-矢量1中的最小值
    //! - index1 -向量1中最小值的索引
    //! - min2 -向量2中的最小值
    //! -索引2 -向量2中最小值的索引
    //! - min3 -向量3中的最小值
    //! -索引3 -向量3中最小值的索引
    //!
    //
    //######################################################################################################################
    //$TI 发行版:F2837xD 支持库 v190美元
    //$Release Date:Mon Feb1 16:51:57 CST 2016 $
    //版权所有:版权所有(C) 2013-2016 Texas Instruments Incorporated -
    //            http://www.ti.com/ 保留所有权利$
    //######################################################################################################################
    #include "F28x_Project.h"    //设备头文件和示例 include 文件
    #include "cla_vminfloat_shared.h"

    //
    //定义
    //

    //CLA 定义
    #define WAITSTEP   asm (" RPT #255 || NOP")

    //
    //全局变量
    //
    //任务1 (C)变量
    #ifdef __cplusplus
       // CLA 输入数据
       #pragma DATA_SECTION ("CpuToCla1MsgRAM");
       #pragma DATA_SECTION ("CpuToCla1MsgRAM");
       float vector1[]={1.0、-11.3、6.2、10.8、2.5};
       int32 length1 = 5;
       //长度3和4在 vmaxfloat_shared.h 中是#defed

       // CLA 输出数据
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       浮点32 min1;
       int32  索引1;
    其他
       // CLA 输入数据
       #pragma DATA_SECTION (vector1、"CpuToCla1MsgRAM");
       #pragma DATA_SECTION (Length1、"CpuToCla1MsgRAM");
       float vector1[]={1.0、-11.3、6.2、10.8、2.5};
       int32 length1 = 5;
       //长度3和4在 vmaxfloat_shared.h 中是#defed

       // CLA 输出数据
       #pragma DATA_SECTION (min1、"Cla1ToCpuMsgRAM");
       #pragma DATA_SECTION (索引1、"Cla1ToCpuMsgRAM");
       浮点32 min1;
       int32  索引1;
    #endif

    //任务2 (C)变量
    #ifdef __cplusplus
       // CLA 输入数据
       #pragma DATA_SECTION ("CpuToCla1MsgRAM");
       #pragma DATA_SECTION ("CpuToCla1MsgRAM");
       浮点 矢量2[]={2.0、-11.3、16.2、10.8、2.5、-12.5}
       int32 length2 = 6;

       // CLA 输出数据
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       float32 min2;
       int32  索引2;
    其他
       // CLA 输入数据
       #pragma DATA_SECTION (vector2、"CpuToCla1MsgRAM");
       #pragma DATA_SECTION (length2、"CpuToCla1MsgRAM");
       float vector2[]={2.0、-11.3、16.2、10.8、2.5、-12.5};
       int32 length2 = 6;

       // CLA 输出数据
       #pragma DATA_SECTION (min2、"Cla1ToCpuMsgRAM");
       #pragma DATA_SECTION (索引2、"Cla1ToCpuMsgRAM");
       float32 min2;
       int32  索引2;
    #endif

    //任务3 (C)变量
    #ifdef __cplusplus
       // CLA 输入数据
       #pragma DATA_SECTION ("CpuToCla1MsgRAM");
       浮点 矢量3[]={0.2、2.3、9.6、9.2、6.2、10.8、2.5}
       int32 length3 = 7;

       // CLA 输出数据
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       int32  索引3;
       浮点32 min3;
    其他
       // CLA 输入数据
       #pragma DATA_SECTION (vector3、"CpuToCla1MsgRAM");
       float vector3[]={0.2、2.3、9.6、9.2、6.2、10.8、2.5};
       int32 length3 = 7;

       // CLA 输出数据
       #pragma DATA_SECTION (min3、"Cla1ToCpuMsgRAM");
       #pragma DATA_SECTION (索引3、"Cla1ToCpuMsgRAM");
       int32  索引3;
       浮点32 min3;
    #endif

    //任务4 (C)变量

    //任务5 (C)变量

    //任务6 (C)变量

    //任务7 (C)变量

    //任务8 (C)变量

    //通用(C)变量
    #ifdef __cplusplus
       #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
       Int32  I;
    其他
       #pragma DATA_SECTION (I、"Cla1ToCpuMsgRAM");
       Int32  I;
    #endif
    uint16_t pass = 0;
    uint16_t fail=0;

    //
    //函数原型
    //
    void CLA_RunTest (void);
    void CLA_configClaMemory (void);
    void CLA_initCpu1Cla1 (void);

    _interrupt void cla1Isr1();
    _interrupt void cla1Isr2();
    _interrupt void cla1Isr3 ();
    _interrupt void cla1Isr4 ();
    _interrupt void cla1Isr5 ();
    _interrupt void cla1Isr6 ();
    _interrupt void cla1Isr7 ();
    _interrupt void cla1Isr8 ();

    //
    // main 开始
    //
    void main (void)

    //步骤1. 初始化系统控制:
    // PLL、安全装置、启用外设时钟
    //此示例函数位于 F2837xD_SYSCTRL.c 文件中。
       InitSysCtrl();

    //步骤2. 清除所有中断并初始化 PIE 矢量表:
    //禁用 CPU 中断
       Dint;

    //将 PIE 控制寄存器初始化为默认状态。
    //默认状态为禁用所有 PIE 中断和标志
    //被清除。
    //此函数位于 F2837xD_PIECTRL.c 文件中。
       InitPieCtrl();

    //禁用 CPU 中断并清除所有 CPU 中断标志:
       IER = 0x0000;
       IFR = 0x0000;

    //使用指向 shell 中断的指针初始化 PIE 矢量表
    //服务例程(ISR)。
    //这将填充整个表,即使是中断也是如此
    //在本例中未使用。  这对于调试很有用。
    //可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
    //此函数可在 F2837xD_PieVect.c 中找到
       InitPieVectTable();

    //步骤3. 首先配置 CLA 存储器空间、然后配置
    // CLA 任务矢量
       CLA_configClaMemory();
       cla_initCpu1Cla1();

    //步骤4. 启用全局中断和更高优先级的实时调试事件:
       EINT; //启用全局中断 INTM
       ERTM; //启用全局实时中断 DBGM

    //步骤5. 运行测试
       CLA_RunTest();


    //
    //函数定义
    //
    空 CLA_RunTest (空)

    //   浮点 矢量1[]={1.0、-11.3、6.2、10.8、2.5};
       Length1 = 5;
       vector1[0]= 1.0;
       vector1[1]=-11.3;
       vector1[2]= 6.2;
       vector1[3]= 10.8;
       vector1[4]= 2.5;

    //   浮点 矢量2[]={2.0、-11.3、16.2、10.8、2.5、-12.5};
       length2 = 6;
       vector2[0]= 2.0;
       vector2[1]=-11.3;
       vector2[2]= 16.2;
       vector2[3]= 10.8;
       vector2[4]= 2.5;
       vector2[5]=-12.5;

    //   vector3[]={0.2、2.3、9.6、9.2、6.2、10.8、2.5};
       length3 = 7;
       vector3[0]= 0.2;
       vector3[1]= 2.3;
       vector3[2]= 9.6;
       vector3[3]= 9.2;
       vector3[4]= 6.2;
       vector3[5]= 10.8;
       vector3[6]= 2.5;

       Cla1ForceTask1andWait();

       Cla1ForceTask2andWait();

       Cla1ForceTask3andWait();

       if (索引1!= 1 || min1!=-11.3)
          FAIL++;
       其他
          pass ++;
       if (索引2!= 5 || min2!=-12.5)
          FAIL++;
       其他
          pass ++;
       if (index3!= 0 || min3!= 0.2)
          FAIL++;
       其他
          pass ++;
    #if 0
       Cla1ForceTask4andWait();

       Cla1ForceTask5andWait();

       Cla1ForceTask6andWait();

       Cla1ForceTask7andWait();

       Cla1ForceTask8andWait();
    #endif



    空 CLA_configClaMemory (空)

       extern uint32_t Cla1funcsRunStart、Cla1funcsLoadStart、Cla1funcsLoadSize;
       EALLOW;

    #ifdef _flash
       //将代码从闪存复制到 RAM
       memcpy (((uint32_t *)&Cla1funcsRunStart、(uint32_t *)&Cla1funcsLoadStart、
             (uint32_t)和 Cla1funcsLoadSize);
    #endif //_FLASH

       //初始化并等待 CLA1ToCPUMsgRAM
       MemCfgRegs.MSGxINIT.bit.init_CLA1TOCPU = 1;
       while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU!= 1){};

       //初始化并等待 CPUToCLA1MsgRAM
       MemCfgRegs.MSGxINIT.bit.init_CPUTOCLA1 = 1;
       while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1!= 1){};

       //选择 LS5RAM 作为 CLA 的编程空间
       //首先将 CLA 配置为 LS5的主器件,然后再配置
       //将空间设置为程序块
       MemCfgRegs.LSxMSEL.bit.MSEL_LS5 = 1;
       MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS5 = 1;

       //下一步将 LS0RAM 和 LS1RAM 配置为 CLA 的数据空间
       //首先将 CLA 配置为 LS0 (1)的主器件、然后
       //将空格设置为代码块
       MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1;
       MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 0;

       MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1;
       MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0;

       EDIS;




    void CLA_initCpu1Cla1 (void)

       // 计算所有 CLA 任务矢量
       //在1类 CLA 上,MVECT 寄存器接受完整的16位任务地址为
       //与旧的0类 CLA 上使用的偏移相对
       EALLOW;
       Cla1Regs.MVECT1 =(uint16_t)(&Cla1Task1);
       Cla1Regs.MVECT2 =(uint16_t)(&Cla1Task2);
       Cla1Regs.MVECT3 =(uint16_t)(&Cla1Task3);
       Cla1Regs.MVECT4 =(uint16_t)(&Cla1Task4);
       Cla1Regs.MVECT5 =(uint16_t)(&Cla1Task5);
       Cla1Regs.MVECT6 =(uint16_t)(&Cla1Task6);
       Cla1Regs.MVECT7 =(uint16_t)(&Cla1Task7);
       Cla1Regs.MVECT8 =(uint16_t)(&Cla1Task8);

       //启用 IACK 指令以在软件中启动 CLA 上的任务
       //针对所有 8个 CLA 任务。 此外、全局启用所有8个任务(或 A
       //任务的子集),方法是在中写入它们各自的位
       // MIER 寄存器
       Cla1Regs.MCTL.bit.IACKE = 1;
       Cla1Regs.MIER all   = 0x00FF;

       //为所有的任务结束中断配置向量
       // 8个任务
       PieVectTable.CLA1_1_INT  =&cla1Isr1;
       PieVectTable.CLA1_2_INT  =&cla1Isr2;
       PieVectTable.CLA1_3_INT  =&cla1Isr3;
       PieVectTable.CLA1_4_INT  =&cla1Isr4;
       PieVectTable.CLA1_5_INT  =&cla1Isr5;
       PieVectTable.CLA1_6_INT  =&cla1Isr6;
       PieVectTable.CLA1_7_INT  =&cla1Isr7;
       PieVectTable.CLA1_8_INT  =&cla1Isr8;

       //在组和子组级别启用 CLA 中断
       PieCtrlRegs.PIEIER11.all = 0xFFFF;
       IER |=(M_INT11);


    //
    // ISR
    //
    _interrupt void cla1Isr1 ()

       //确认任务1的任务结束中断
       PieCtrlRegs.PIEACK.ALL = M_INT11;
    //   asm (" ESTOP0");


    _interrupt void cla1Isr2 ()

       PieCtrlRegs.PIEACK.ALL = M_INT11;


    _interrupt void cla1Isr3 ()

       PieCtrlRegs.PIEACK.ALL = M_INT11;


    _interrupt void cla1Isr4 ()

       asm (" ESTOP0");


    _interrupt void cla1Isr5 ()

       asm (" ESTOP0");


    _interrupt void cla1Isr6 ()

       asm (" ESTOP0");


    _interrupt void cla1Isr7 ()

       asm (" ESTOP0");


    _interrupt void cla1Isr8 ()

       //确认任务8的任务结束中断
       PieCtrlRegs.PIEACK.ALL = M_INT11;
    //   asm (" ESTOP0");


    //文件结束

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

    您好、Simon、
    实际的 CLA 程序是 vminfloat.cla。

    //步骤3. 首先配置 CLA 存储器空间、然后配置
    // CLA 任务矢量
    CLA_configClaMemory();//将代码从闪存复制到 CLA RAM
    cla_initCpu1Cla1();

    CPU 和 CLA 在它们之间传递数据的方法是特定的。

    CLA 运行任务。

    CLA 数据 RAM 的一些分配

    //任务1 (C)变量
    #ifdef __cplusplus
    // CLA 输入数据
    #pragma DATA_SECTION ("CpuToCla1MsgRAM");
    #pragma DATA_SECTION ("CpuToCla1MsgRAM");
    float vector1[]={1.0、-11.3、6.2、10.8、2.5};
    int32 length1 = 5;
    //长度3和4在 vmaxfloat_shared.h 中是#defed

    // CLA 输出数据
    #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
    #pragma DATA_SECTION ("Cla1ToCpuMsgRAM");
    浮点32 min1;
    int32索引1;
    其他
    // CLA 输入数据
    #pragma DATA_SECTION (vector1、"CpuToCla1MsgRAM");
    #pragma DATA_SECTION (Length1、"CpuToCla1MsgRAM");
    float vector1[]={1.0、-11.3、6.2、10.8、2.5};
    int32 length1 = 5;
    //长度3和4在 vmaxfloat_shared.h 中是#defed

    // CLA 输出数据
    #pragma DATA_SECTION (min1、"Cla1ToCpuMsgRAM");
    #pragma DATA_SECTION (索引1、"Cla1ToCpuMsgRAM");
    浮点32 min1;
    int32索引1;
    #endif

    您可以尝试使用调试器单步执行代码。
    做更高级的事情的诀窍是弄清楚如何让 CPU 做一些非常有用的事情、而 CLA 忙于与 CPU IMO 并行执行计算

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

    好的、我认为我开始理解:

    如果我错了、请纠正我、但现在我就是这样看到它的:

    - CLA 需要执行的任务被写入一个单独的文件-*。cla -所以在我的例子中、我将 PI 控制器的代码放置在这里

    -要使任务正常工作、CLA 需要与主 CPU 进行一些通信。
    因此、在常规程序的开头、您给出了它将用作 CPU 输入的变量的名称、还给出了您希望从 CLA 中恢复的变量的名称(CLA 输出数据)

    -在程序开始时、你还声明一些 CLA 等待步骤-不知道这里的目的是什么?

    然后、您需要定义一些函数来设置 CLA:
    void CLA_RunTest (void);
    void CLA_configClaMemory (void);
    void CLA_initCpu1Cla1 (void);
    我是否可以复制这些行并在程序中使用与我假设在每种情况下此设置/初始化都是相同的行?

    在 vminfloat 示例中,它们还提供了以下内容:
    _interrupt void cla1Isr1();
    这似乎只是检查 CLA 是否真正运行了代码的检查点:

    _interrupt void cla1Isr1 ()

       //确认任务1的任务结束中断
       PieCtrlRegs.PIEACK.ALL = M_INT11;
    //   asm (" ESTOP0");

    但是、我看不到该函数何时在程序中被调用或使用。 是否真的有必要?

    非常感谢您的帮助。 我已经更好地理解了这一点。

    Simon

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Simon、
    这实际上不是我的程序、而是您在帖子中剪切和粘贴的部分。

    等待步骤? 这话什么意思?
    Cla1ForceTask1andWait();

    这是他们执行例行程序的方式、这在现实世界中是愚蠢的。 它告诉 CLA 运行任务并让 CPU 等待任务完成。 如果这是可以接受的、那么为什么不让 CPU 进行 CLA 计算。

    我不记得 ISR 的确切序列,但是如果我不得不猜测一个典型序列,并且 ADC 转换触发 CLA 任务的执行,那么任务结束时 ISR 将执行以清理,...
    //确认任务1的任务结束中断
    PieCtrlRegs.PIEACK.ALL = M_INT11;

    您可能需要浏览 CLA 文档。

    training.ti.com/c2000-cla-c-compiler-4-part-series