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.

[参考译文] TMS320F28P550SJ:MCAN 的整个消息 RAM 的大小

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1360801/tms320f28p550sj-size-of-whole-message-ram-for-mcan

器件型号:TMS320F28P550SJ
主题中讨论的其他器件:test2C2000WARE

亲爱的香榭丽舍大街,

我是为我们的客户提出这个问题的。

在数据表(SPRSP85 - 2024年4月)中、

关于 MCAN 的消息 RAM、  

1."(CPU 访问模式)"和"(外设模式)"是什么意思? 外设意味着 MCAN 或者 DMA、还是其它?  

2、 包括 一个 MCAN 模块的 TX 缓冲区/RX 缓冲区/RXFIFO0/RXFIFO1/TX 事件在内的"整个消息 RAM"的大小是多少?

3.与 F28003x 相比,整个消息 RAM 的大小只有 P55x 的一半。 对吗?

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

    韦恩、您好!

    将获得#1 (外设模式/CPU 访问模式之间的差异)的答案。  每个模块的整个 MCAN 消息 RAM 为4K。  该中断由缓冲区和 FIFO 以及 RX 和 TX 共享。  F28003x 中消息 RAM 的大小是 P55x 的两倍。

    此致、

    约瑟夫  

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

    韦恩、您好!

    以下是关于第1项的附加信息。  CpuSysRegs 中有一位。 MCANRAMACC、它用于配置如何使用消息 RAM。  在 MCAN 模式下、MCAN_A_RAMACC 和 MCAN_B_RAMACC 位清零、这会为 MCAN 分配消息 RAM 空间、每模块4K。  如果 MCAN 未在应用中使用、并且用户决定将 MCAN 消息 RAM 用于其他用途、则位 MCAN_A_RAMACC 和 MCAN_B_RAMACC 可以设置为"1"。  这将允许用户访问 MCANA 消息 RAM 上0x58000-587FF 范围内的2K 存储空间、以及 MCANB 消息 RAM 上0x5A000-5A7FF 范围内的另2K 存储空间。

    此致、

    约瑟夫

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

    尊敬的 Joseph:

    您的意思是、当 MCAN_A_RAMACC/MCAN_B_RAMACC = 1时、如果用户不想使用 MCAN/B、那么用户可将相应的 RAM 2K x 16位用于其他用途。

    例如、用户只需在包括.bss 和.TI.ramfunc 在内的两个部分上分配全局变量数据或函数/ISR 代码 。

    我的理解是否正确?

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

    韦恩、您好!

    可以,只要在应用程序之前设置访问位,就可以使用这些位置存储静态、全局和执行代码。

    此致、

    约瑟夫

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

    尊敬的 Joseph:

    该函数看起来很有用。

    我对如何实施有点困惑。

    例如、

    如果这些 RAM 用于代码、用户可以设置  MCAN_A_RAMACC/MCAN_B_RAMACC = 1、然后将代码从闪存复制到这些 RAM 来运行。

    但是、如果这些 RAM 用于静态/全局变量等数据、运行时支持库(RTS)如何在用户设置 MCAN_A_RAMACC/MCAN_B_RAMACC = 1之前分配它们?

    也就是说、如果用户为.bss 分配这些 RAM 并在此处定义全局变量、链接器和 RTS 如何为这些全局变量执行操作?

    调用 RTS 以便在 main ()之前初始化它们、其中用户可以在  初始化时设置 MCAN_A_RAMACC/MCAN_B_RAMACC = 1。

    如果可能、您会帮助您澄清一下并说明示例吗?

    或者这是否意味着用户应  在 codestartbranch.asm 中设置 MCAN_A_RAMACC/MCAN_B_RAMACC = 1、然后再跳到入口点和 RTS?

    有点奇怪……

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

    韦恩、您好!

    这是一个有效的问题。  看到 RAMACC 可以在什么点更新。  让我来联系我们的软件/设计团队看看效果如何。  这将需要我一段时间。  很好奇、F28P55x 拥有足够的 RAM、但我想客户希望获得更大的内存空间?  当前存储器有什么限制?

    此致、

    约瑟夫

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

    尊敬的 Joseph:

    用户正在使用 F28003x、询问了类似的问题:MCAN 消息 RAM 是否可用于应用、因为用户不需要 CAN 总线。

    e2e.ti.com/.../tms320f280039c-mcan-message-ram-usage

    用户需要使用不带复位的实时固件更新、这需要  尽可能多的 RAM、因为代码的 RAM 被分为旧映像使用和新映像使用。 他们发现 F28003x 69 KB RAM 现在还勉强够用。

    P55x 512KB 闪存器件的 LSx RAM 比003x 多32KB、看上去一切正常。

    更好的是、MCAN 消息 RAM 也可用于没有 CAN 总线的 P55x 上的应用。

    使用更多的 RAM、用户可以将更多代码从闪存移动到 RAM、因为应用对时序要求非常严格、并且需要计算能力。

    用户可以将 MCAN 消息 RAM 用于全局变量、并为代码执行留下更多的 GSx/LSx RAM。

    这就是为什么我们更详细地要求这部分。

    您最好可以展示一个实现示例。

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

    韦恩、您好!

    感谢您的讲解。  我从设计中得到确认、即该存储器可用于数据存储器(.data/.bss)但不可用于执行、因为 MCAN RAM 仅可从 CPU 访问数据。  该功能有用的正确步骤是在 cinit 之前设置 MCANRAMACC。  一旦置位、该位只能由 POR 和不受影响的 ty SYSRSn 和 XRSn 复位。  看起来客户可以使用此功能进行上述任务的数据移动。  目前没有当前示例代码、但试图看看我们是否可以从我们的软件团队请求。

    此致、

    约瑟夫  

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

    尊敬的 Joseph:

    我仍然对如何实施 "这有用的正确步骤是在 cinit 前设置 MCANRAMACC "感到困惑?

    要求用户查看 RTS 是没有意义的、所以这是否意味着用户必须使用 codestartbranch.asm 来设置 MCANRAMACC?

    或者,用户可以  在不进行初始化的情况下声明全局变量(即没有.cinit ),然后在 main ()中由用户对其进行初始化吗?

    以下面的 PEUDO 代码为例、

    浮点 test1;

    uint16_t test2;

    ...

    主要()

    {

    ...

    MCAN_A_RAMACC/MCAN_B_RAMACC = 1;

    测试1 = 1.0;

    测试2 = 1;

    ...

     

    您能否确认以上示例是否有效?

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

    韦恩、您好!

    这是不起作用的。 在 main 的开头设置 MCAN RAMACC 位不会影响 test1和 test2的重定位。  这些变量仍将在代码的.data 段结束。  以下是使用指针的一种选项、但使用指针会很麻烦、因为用户必须注意字对齐和变量的位置以及重叠的地址:

    主要()

    {

       float * test1 =(float *) 0x58000;//映射到 MCANA 位置

       uint16_t * test2 =(uint16_t *) 0x5A000;//映射到 MCANB 位置

       MCAN_A_RAMACC/MCAN_B_RAMACC = 1;

       //开始写入值

       *(测试1)++= 1.1;

       *(测试1)++= 1.5;

          :

       *(test2)++= 123456;    

       *(test2)++= 56789;

    将写入到 MCAN 消息 RAM 地址位置。  您可以通过循环和递增指针将代码从一个存储器移动到消息 RAM、但必须注意要移动的数据的数量和类型以及字对齐(请注意只从偶数地址开始写入32位或浮点值)、以便存储器中使用的位置数能够适应而不超过允许的大小。

    我有人在 cinit 之前尝试写入 RAMACC 位。  我认为这可能是一个自动为消息 RAM 分配.data/.bss 的更好选择。  下周同一时间再见、我们将为您提供一个示例代码。

     此致、

    约瑟夫  

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

    韦恩、您好!

    这只是为了清楚在 MCAN 中 RAMACC 寄存器的用途。  这是 F28P55x 中的一个新实现。  如果该位不置位、CPU 仍可以访问 MCAN 消息 RAM、但该空间不能作为连续空间进行访问。  写入第一个地址位置会复制相邻位置的数据(请参阅 CAN TRM 中的数据/地址总线桥主题)、由于具有用于移动数据的连续存储器空间、因此作用不大。 RAMACC 负责这一操作、因此 RAMACC 不允许访问每个其他存储器位置、它允许使用一个连续的存储块、该存储块是 MCAN 消息 RAM 的一半。

    此致、

    约瑟夫

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

    尊敬的 Joseph:

    我了解。

    感谢您的澄清。

    请在您或其他 AE 尝试使用更好的选项后让我保持发布。

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

    韦恩、您好!

    下面是一个实现示例。  下面是为 main.c 文件中的 MCANRAMACC 配置调用外部函数的 cinit 实现。

     

    ;// TI File $Revision: /main/2 $
    ;// Checkin $Date: December 7, 2011   18:25:05 $
    ;//###########################################################################
    ;//
    ;// FILE:  F2837x_CodeStartBranch._asm	
    ;//
    ;// TITLE: Branch for redirecting code execution after boot. 
    ;//
    ;// For these examples, code_start is the first code that is executed after
    ;// exiting the boot ROM code. 
    ;//
    ;// The codestart section in the linker cmd file is used to physically place
    ;// this code at the correct memory location.  This section should be placed 
    ;// at the location the BOOT ROM will re-direct the code to.  For example, 
    ;// for boot to FLASH this code will be located at 0x3f7ff6. 
    ;//
    ;// In addition, the example F2837x projects are setup such that the codegen
    ;// entry point is also set to the code_start label.  This is done by linker 
    ;// option -e in the project build options.  When the debugger loads the code,
    ;// it will automatically set the PC to the "entry point" address indicated by
    ;// the -e linker option.  In this case the debugger is simply assigning the PC, 
    ;// it is not the same as a full reset of the device. 
    ;// 
    ;// The compiler may warn that the entry point for the project is other then
    ;//  _c_init00.  _c_init00 is the C environment setup and is run before 
    ;// main() is entered. The code_start code will re-direct the execution 
    ;// to _c_init00 and thus there is no worry and this warning can be ignored. 
    ;// 
    ;//###########################################################################
    ;// $TI Release: F2837x C/C++ Header Files and Peripheral Examples V100 $
    ;// $Release Date: November 30, 2011 $
    ;//###########################################################################
    
    ***********************************************************************
    
    WD_DISABLE	.set	1		;set to 1 to disable WD, else set to 0
    
        .ref _c_int00
        .global code_start
    
    ***********************************************************************
    * Function: codestart section
    *
    * Description: Branch to code starting point
    ***********************************************************************
    
        .sect "codestart"
        .ref MCANRAM_Init
    
    code_start:
    	LCR MCANRAM_Init
        .if WD_DISABLE == 1
            LB wd_disable       ;Branch to watchdog disable code
        .else
            LB _c_int00         ;Branch to start of boot._asm in RTS library
        .endif
    
    ;end codestart section
    
    ***********************************************************************
    * Function: wd_disable
    *
    * Description: Disables the watchdog timer
    ***********************************************************************
        .if WD_DISABLE == 1
    
        .text
    wd_disable:
        SETC OBJMODE        ;Set OBJMODE for 28x object code
        EALLOW              ;Enable EALLOW protected register access
        MOVZ DP, #7029h>>6  ;Set data page for WDCR register
        MOV @7029h, #0068h  ;Set WDDIS bit in WDCR to disable WD
        EDIS                ;Disable EALLOW protected register access
        LB _c_int00         ;Branch to start of boot._asm in RTS library
    
        .endif
    
    ;end wd_disable
    
    	.end
    	
    ;//===========================================================================
    ;// End of file.
    ;//===========================================================================

    这是 main.c 文件:

    #include "stdint.h"
    #include "sysctl.h"
    
    #define MCANA_BASE 0x00058000U
    #define MCANB_BASE 0x0005A000U
    #define SYSCTL_O_MCANRAMACC       0x0090U
    
    uint32_t Uninitialized_Array[10];                           // while halted at main, you will see this array as 0
    uint32_t Initialized_Array[10] = {1,2,3,4,5,6,7,8,9,10};   // while halted at main, you will see this array initialized
    
    uint32_t MCAN_isMemInitDone_local(uint32_t baseAddr);
    void MCANRAM_Init(void);
    
    int main(void)
    {
    
        SysCtl_disableWatchdog();
    
        int i = 0;
    
        for(i=0;i<10;i++){
            Uninitialized_Array[i] = i*2;
            Initialized_Array[i] = i*3;
        }
    
        done();
    }
    
    void done()
    {
        asm(" ESTOP0"); // check the values updated in both array location.
        for (;;);
    }
    
    
    uint32_t MCAN_isMemInitDone_local(uint32_t baseAddr)
    {
        uint32_t memInit;
        uint32_t state;
    
        memInit = ((HWREG(baseAddr + MCAN_MCANSS_STAT) & MCAN_MCANSS_STAT_MEM_INIT_DONE_MASK) >> MCAN_MCANSS_STAT_MEM_INIT_DONE_SHIFT);
        if(1U == memInit)
        {
            state = (uint32_t) 1;
        }
        else
        {
            state = (uint32_t) 0;
        }
        return state;
    }
    
    void MCANRAM_Init(){
    
        if(HWREG(CPUSYS_BASE + SYSCTL_O_MCANRAMACC) != 0x3){
            // PCLKCR
            SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCANA);
            //MCAN RAM Check
            //
            // Reset the peripheral.
            //
            SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_MCANA);
            //Wait till Memory initialization is done
            while (MCAN_isMemInitDone_local(MCANA_BASE) == 0)
                ;
    
            SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCANB);
            //MCAN RAM Check
            //
            // Reset the peripheral.
            //
            SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_MCANB);
            //Wait till Memory initialization is done
            while (MCAN_isMemInitDone_local(MCANB_BASE) == 0)
                ;
    
            EALLOW;
            HWREG(CPUSYS_BASE + SYSCTL_O_MCANRAMACC) |= 0x3U;
            EDIS;
        }
        // MCANRAMACC
    }

    ...这里是将 MCAN 消息 RAM 用于.bss 和.data 段的链接器命令。

    -stack 0x100
    -heap 0x100
    --retain MCANRAM_Init
    
    MEMORY
    {
    PAGE 0 :
       RAMLS012           	: origin = 0x00008000, length = 0x0001800
       RESET           	: origin = 0x003FFFC0, length = 0x00000002
       BOOT_RSVD_SYSBIOS: origin = 0x00000780, length = 0x00000080
       MCANARAM			: origin = 0x00058000, length = 0x800
       MCANBRAM			: origin = 0x0005A000, length = 0x800
    
    }
    
    
    
    SECTIONS
    {
       .text            : > RAMLS012
       .cinit           : > RAMLS012
       .reset           : > RESET,     					TYPE = DSECT /* not used, */
       codestart		: > RAMLS012
       .stack           : > RAMLS012
       .bss:.cio        : > RAMLS012
       .sysmem          : > RAMLS012
       .const			: > RAMLS012
       .rodata 			: > RAMLS012
    
       .data            : >> MCANARAM | MCANBRAM
       .bss             : >> MCANARAM | MCANBRAM
    }
    
    /*
    //==============
    =============================================================
    // End of file.
    //===========================================================================

    此致、

    约瑟夫

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

    尊敬的 Joseph:

    非常感谢。

    非常有用。

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

    尊敬的 Joseph:

     对于 MCANRAM_Init (),用户是否可以只使用 int _system_pre_init (),而不是 codestartbranch.asm ,因为大多数用户只是从 C2000ware 链接 codestartbranch.asm 而不修改它?

    int _system_pre_init (void)

    {

          MCANRAM_Init ();

    主要()

    {

    ...

    请参阅  

    第178页、共页

    www.ti.com/.../SPRU514Z

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

    韦恩、您好!

    这是一个有趣的问题。  让我进一步检查这一点、让您知道、但我的初始评估是、如果在 cinit 之前调用此函数、它应该是可行的。

    此致、

    约瑟夫