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.

[参考译文] AM6422:DDR R5F 初始化0

Guru**** 2470830 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1453666/am6422-ddr-r5f-init-0

器件型号:AM6422
主题中讨论的其他器件:SysConfig

工具与软件:

您好!

 我们当前的开发基于 SDK8.6版本。 R5F 内核运行并收集数据、然后通过内核间通信将数据发送到 A53内核。 在此前提下、R5F 内核必须在 DDR 上运行

小程序。 我们现在要在 DDR 上保留10个字节以记录当前启动状态、例如软启动、硬启动、启动次数等 当时、该存储器的指定地址数据不会被修改

电源不会中断。 但目前我正在测试一些现象。 我在地址0xA0101000处定义了一个4字节的数据。 如果此地址不是我第一次需要的值、我会向该地址写入一个特定的值

然后重新加载该程序并再次运行它。 发现该位置的值变为0。 如何满足我们的需求?为什么上电后 DDR 的值变为0?他在哪里处理?

相同的函数在 DDR 上运行所需的时间比在 MSRAM 上更长。 是这样吗? 我们可以说在 DDR 上运行时有一些延迟吗?

期待您的回复、谢谢您!

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

    大家好、如果您需要在上电/断电后保存一些变量、则需要使用非易失性存储器、例如闪存。   

    MCU+SDK 用户指南提供了一个 有关如何在闪存中写入和读取的示例。 可以使用类似的方法刷写某些变量。  AM64x MCU+ SDK:OSPI 闪存 IO。 如果我误解了你需要做什么,请告诉我。

    关于您的另一个问题、从 MSRAM 运行的速度比 DDR 快不会感到奇怪。 您可以查看 此应用手册(https://www.ti.com/lit/pdf/spracv1)以了解有关"存储器存取延迟"和其他基准测试数据的更多详细信息。

    此外、请记住、在 MPU 设置中将 DDR 区域用作"高速缓存"。 示例

    谢谢!

    Paula.

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

    您好!

     感谢您的回复!我想我 不会把它弄清楚。我不想把它存储在闪存中。 我想在 RAM 断电后使用数据丢失问题、并在再次上电后读出数据、以确定此启动是硬启动而不是软启动。

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

    您好!

     感谢您的回复!我想我 不会把它弄清楚。我不想把它存储在闪存中。 我想在 RAM 断电后使用数据丢失问题、并在再次上电后读出数据、以确定此启动是硬启动而不是软启动。

     我还发现了一个问题。 在 DDR 上运行时、我定义了一个周期为1S、时钟频率为200MHz 的计时器。 我在接收到标准 PPS 后记录计时器的值、然后记录当前的第二个脉冲和上一次脉冲。 第二个脉冲的计时器计数差在理论上应该是相同的数据、没有太大不同、但我将在下面发布实际测量结果。 您能帮助分析这种情况吗? 在 MSRAM 上运行时也是如此、没有如此大的偏差。我还会发送我的 link.cmd 文件。

    从记录的数据来看、相邻 PPS 之间的时间间隔差相对较大、差异大于1us。 根据这个时钟频率、我想不应该是这样。μ s

    为了获得计时器值、我执行了以下处理操作:

    PPS 脉冲中断函数:μ s

    void PPS_INT()
    
    {
    
    cap32val = TimerP_getCount(gTimerBaseAddr[CONFIG_TIMER1S]);
    cap32val = cap32val-(0xffffffff-(200000000-1));
    
    B_coding.os_time_us1 = cap32val;
    if(B_coding.os_time_us1<B_coding.os_time_us2)
        B_coding.Interval1 = B_coding.os_time_us1 + 200000000 - B_coding.os_time_us2;
    else
        B_coding.Interval1 = B_coding.os_time_us1 - B_coding.os_time_us2;
    inter[bcodecnt++] = B_coding.Interval1;
    // TIM_CLR(gTimerBaseAddr[CONFIG_TIMER1S]);
    inter[bcodecnt++] = val;
    if(bcodecnt==300)
        bcodecnt = 0;
    B_coding.os_time_us2 = B_coding.os_time_us1;
    
    }

    link.cmd

    /* This is the stack that is used by code running within main()
     * In case of NORTOS,
     * - This means all the code outside of ISR uses this stack
     * In case of FreeRTOS
     * - This means all the code until vTaskStartScheduler() is called in main()
     *   uses this stack.
     * - After vTaskStartScheduler() each task created in FreeRTOS has its own stack
     */
    --stack_size=32768
    /* This is the heap size for malloc() API in NORTOS and FreeRTOS
     * This is also the heap used by pvPortMalloc in FreeRTOS
     */
    --heap_size=32768
    -e_vectors  /* This is the entry of the application, _vector MUST be plabed starting address 0x0 */
    
    /* This is the size of stack when R5 is in IRQ mode
     * In NORTOS,
     * - Here interrupt nesting is enabled
     * - This is the stack used by ISRs registered as type IRQ
     * In FreeRTOS,
     * - Here interrupt nesting is disabled
     * - This is stack that is used initally when a IRQ is received
     * - But then the mode is switched to SVC mode and SVC stack is used for all user ISR callbacks
     * - Hence in FreeRTOS, IRQ stack size is less and SVC stack size is more
     */
    __IRQ_STACK_SIZE = 4096;
    /* This is the size of stack when R5 is in IRQ mode
     * - In both NORTOS and FreeRTOS nesting is disabled for FIQ
     */
    __FIQ_STACK_SIZE = 4096;
    __SVC_STACK_SIZE = 4096; /* This is the size of stack when R5 is in SVC mode */
    __ABORT_STACK_SIZE = 4096;  /* This is the size of stack when R5 is in ABORT mode */
    __UNDEFINED_STACK_SIZE = 4096;  /* This is the size of stack when R5 is in UNDEF mode */
    
    SECTIONS
    {
        /* This has the R5F entry point and vector table, this MUST be at 0x0 */
        .vectors:{} palign(8) > R5F_VECS
    
        /* This has the R5F boot code until MPU is enabled,  this MUST be at a address < 0x80000000
         * i.e this cannot be placed in DDR
         */
        GROUP {
            .text.hwi: palign(8)
            .text.cache: palign(8)
            .text.mpu: palign(8)
            .text.boot: palign(8)
            .text:abort: palign(8) /* this helps in loading symbols when using XIP mode */
        } > R5F_TCMA
    
        /* This is rest of code. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .text:   {} palign(8)   /* This is where code resides */
            .rodata: {} palign(8)   /* This is where const's go */
        } > DDR_1
    
        GROUP {
            /* This is the resource table used by linux to know where the IPC "VRINGs" are located */
            .resource_table: {} palign(4096)
        } > DDR_0
    
        /* This is rest of initialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .data:   {} palign(8)   /* This is where initialized globals and static go */
        } > DDR_1
    
        /* This is rest of uninitialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .bss:    {} palign(8)   /* This is where uninitialized globals go */
            RUN_START(__BSS_START)
            RUN_END(__BSS_END)
            .sysmem: {} palign(8)   /* This is where the malloc heap goes */
            .stack:  {} palign(8)   /* This is where the main() stack goes */
        } > DDR_1
    
        /* This is where the stacks for different R5F modes go */
        GROUP {
            .irqstack: {. = . + __IRQ_STACK_SIZE;} align(8)
            RUN_START(__IRQ_STACK_START)
            RUN_END(__IRQ_STACK_END)
            .fiqstack: {. = . + __FIQ_STACK_SIZE;} align(8)
            RUN_START(__FIQ_STACK_START)
            RUN_END(__FIQ_STACK_END)
            .svcstack: {. = . + __SVC_STACK_SIZE;} align(8)
            RUN_START(__SVC_STACK_START)
            RUN_END(__SVC_STACK_END)
            .abortstack: {. = . + __ABORT_STACK_SIZE;} align(8)
            RUN_START(__ABORT_STACK_START)
            RUN_END(__ABORT_STACK_END)
            .undefinedstack: {. = . + __UNDEFINED_STACK_SIZE;} align(8)
            RUN_START(__UNDEFINED_STACK_START)
            RUN_END(__UNDEFINED_STACK_END)
        } > DDR_1
    
        /* Sections needed for C++ projects */
        GROUP {
            .ARM.exidx:  {} palign(8)   /* Needed for C++ exception handling */
            .init_array: {} palign(8)   /* Contains function pointers called before main */
            .fini_array: {} palign(8)   /* Contains function pointers called after main */
        } > DDR_1
    
        /* General purpose user shared memory, used in some examples */
        .bss.user_shared_mem (NOLOAD) : {} > USER_SHM_MEM
        /* this is used when Debug log's to shared memory are enabled, else this is not used */
        .bss.log_shared_mem  (NOLOAD) : {} > LOG_SHM_MEM
        /* this is used only when IPC RPMessage is enabled, else this is not used */
        .bss.ipc_vring_mem   (NOLOAD) : {} > RTOS_NORTOS_IPC_SHM_MEM
    }
    
    /*
    NOTE: Below memory is reserved for DMSC usage
     - During Boot till security handoff is complete
       0x701E0000 - 0x701FFFFF (128KB)
     - After "Security Handoff" is complete (i.e at run time)
       0x701F4000 - 0x701FFFFF (48KB)
    
     Security handoff is complete when this message is sent to the DMSC,
       TISCI_MSG_SEC_HANDOVER
    
     This should be sent once all cores are loaded and all application
     specific firewall calls are setup.
    */
    
    MEMORY
    {
        R5F_VECS  : ORIGIN = 0x00000000 , LENGTH = 0x00000040
        R5F_TCMA  : ORIGIN = 0x00000040 , LENGTH = 0x00007FC0
        R5F_TCMB0 : ORIGIN = 0x41010000 , LENGTH = 0x00008000
    
        /* when using multi-core application's i.e more than one R5F/M4F active, make sure
         * this memory does not overlap with other R5F's
         */
        MSRAM     : ORIGIN = 0x70080000 , LENGTH = 0x40000
    
        /* This section can be used to put XIP section of the application in flash, make sure this does not overlap with
         * other CPUs. Also make sure to add a MPU entry for this section and mark it as cached and code executable
         */
        FLASH     : ORIGIN = 0x60100000 , LENGTH = 0x80000
    
        /* when using multi-core application's i.e more than one R5F/M4F active, make sure
         * this memory does not overlap with other R5F's
         */
        /* Resource table must be placed at the start of DDR_0 when R5 cores are early booting with Linux */
        DDR_0       : ORIGIN = 0xA0100000 , LENGTH = 0x1000
        DDR_1       : ORIGIN = 0xA0101000 , LENGTH = 0xEFF000
    
        /* shared memory segments */
        /* On R5F,
         * - make sure there is a MPU entry which maps below regions as non-cache
         */
        USER_SHM_MEM            : ORIGIN = 0xA5000000, LENGTH = 0x80
        LOG_SHM_MEM             : ORIGIN = 0xA5000000 + 0x80, LENGTH = 0x00004000 - 0x80
        RTOS_NORTOS_IPC_SHM_MEM : ORIGIN = 0xA5004000, LENGTH = 0x0000C000
        LINUX_IPC_SHM_MEM       : ORIGIN = 0xA0000000 , LENGTH = 0x100000
    }
    

    我们目前对这一问题没有任何怀疑、我们希望你能提出一些解决办法。

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

    您好、检查 RAM 可能会起作用。如您所述、断电时、RAM 中的数据通常会丢失。 但是、请务必注意、这种方法并非万无一失。 RAM 中的数据可能会丢失或更改、例如系统崩溃或内存损坏、还有其他原因。  
    我建议查看 AM64x 的 TRM (https://www.ti.com/lit/ug/spruim2h)的"5.3.3复位状态"部分、了解有关位寄存器和具有复位状态的引脚的更多信息。

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

    您好、w.r.t 至计时器问题、您能否打开另一个包含相同信息的 TT? 这可以帮助我们将其路由到正确的专家。

    我们只会想到 Timer1的初始化方式。 可能执行与此处类似的步骤: AM64x MCU+ SDK:计时器? 或者您是否使用 SysConfig 添加计时器模块?

    此外、计时器的 TRM ("、供您参考。">www.ti.com/.../spruim2h)部分为"12.5.3.1计时器概述"、供您参考。

    谢谢!

    Paula.

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

    您好、

      我使用 SysConfig 软件配置了计时器。 我想这是在 DDR 上运行时出现的问题、因为 MSRAM 上不存在这样的问题。创建计时器后、我只使用 API 函数读取计时器的值。它可能与计时器无关、原因仍然是 DDR。

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

    您好、

    我正在看你的查询,你可能会期待星期一回复.

    此致、

    Anil。

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

    您好、检查这是否仍然是一个未决问题。 如果是这样、总结是:在 DDR 中运行代码以检查计时器(PPS_INT)与在 MSRAM 中运行相同代码相比、读取之间有很大差异。 我对问题的理解是否正确?

    谢谢!

    Paula.

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

    您好、

      是、您的 理解是正确的。

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

    感谢确认、我将联系一位同事、征求他们的意见

    Paula.

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

    您好、Wanglili、

    如果进行 SOC WarmReset 或冷复位、则 DDR 或 MSRAM 存储器上的数据将丢失、并且无法保留 DDR 或 MSRAM 上的先前数据。

    通常、与 DDR 相比、MSRAM 中的代码执行速度更快。   

    此致、

    Anil。