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.

[参考译文] LP-AM243:从TCM运行代码较慢

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1087172/lp-am243-running-the-code-from-tcm-is-slower

部件号:LP-AM243

大家好,我使用gPIO_INTERRUPT示例,希望通过SW测量中断延迟。

我测量从中断源到ISR端点的起点。  

当我将整个代码放入TCM时,我计算 的周期数比使用缺省linker.cmd时要多,因为在该命令中,所有内容都放置在MSRAM中。

这可能是什么原因? 从TCM运行时,我预期的数值低于MSRAM?  

下面是linker.cmd文件,谢谢!

/*这是在main()中运行的代码所使用的堆栈
*如为NORTOS,
*-这意味着ISR之外的所有代码都使用此堆栈
*如果是FreeRTOS
*-这意味着在main()中调用vTaskStartScheduler()之前的所有代码
*使用此堆栈。
*-在vTaskStartScheduler()之后,在FreeRTOS中创建的每个任务都有自己的堆栈
*/
--stack_size=4096
/*这是NORTOS和FreeRTOS中malloc() API的堆大小
*这也是FreeRTOS中pvPortMalloc使用的堆
*/
--heap_size=4096
-e_vectors/*这是应用程序的条目,_vector必须被加床,起始地址为0x0 */

/*当R5处于IRQ模式时,这是堆栈的大小
*在NORTOS中,
*-此处中断嵌套目前已禁用
*-这是注册为IRQ类型的ISR使用的堆栈
*在FreeRTOS中,
*-此处启用中断嵌套
*-这是在收到IRQ时最初使用的堆栈
*-但随后将模式切换为SVC模式,SVC堆栈将用于所有用户ISR回调
*-因此在FreeRTOS中,IRQ堆栈大小较小,SVC堆栈大小较高
*/
__IRQ_STACK_SIZE = 1024;
/*当R5处于IRQ模式时,这是堆栈的大小
*-在NORTOS和FreeRTOS中,FIQ的嵌套均被禁用
*/
__FIX_STACK_SIZE =256;
__SVC_STACK_SIZE =4096;/*这是R5处于SVC模式时的堆栈大小*/
__abort_stack_size =256;/*这是R5处于中止模式时堆栈的大小*/
__undefined_stack_size =256;/*这是R5在UNDEF模式下时栈的大小*/

章节

/*它具有R5F入口点和矢量表,必须在0x0 */处
矢量:{}palign (8)> R5F_VECS

/*在启用MPU之前,它具有R5F启动代码,必须位于地址< 0x800万
*即,不能将其置于DDR中
*/
组{
text.hwi:{}palign (8)
.text.cache: palign (8)
text.mpu:palign (8)
text.boot:palign (8)
text:abort: palign (8)/*这有助于在使用XIP模式*/时加载符号
}> R5F_TCMA

/*这是代码的其余部分。 如果DDR可用且需要*/,则可以将其放置在DDR中

.text:{} palign (8)> R5F_TCMA

/*这是其余的初始化数据。 如果DDR可用且需要*/,则可以将其放置在DDR中
组{
数据:{}palign (8)/*这是初始化全局和静态GO *的位置
}> R5F_TCMB0

/*这是其余未初始化的数据。 如果DDR可用且需要*/,则可以将其放置在DDR中
组{
bss:{}palign (8)/*这是未初始化的全局变量的位置*/
run_start(__bss_start)
运行结束(__bss_end)
sysmem:{} palign (8)/*这是malloc堆的位置*/
stack:{} palign (8)/*这是main()堆栈的位置*/
.rodata:{}palign (8)/*这是const的目标*/
}> R5F_TCMB0

/*这是不同R5F模式的叠块的位置*/
组{
irqstack:{. =。 +__irq_stack_size;}对齐(8)
run_start(__irq_stack_start)
运行结束(__irq_stack_end)
.fiqstack:{. =。 +__FIX_STACK_SIZE;}对齐(8)
run_start(__fic_stack_start)
运行结束(__FIQ)堆叠结束)
svcstack:{. =。 +__svc_stack_size;}对齐(8)
运行_启动(__SVC_STACK_START)
运行结束(__SVC_STACK_END)
异常栈:{. =。 +__abort_stack_size;}对齐(8)
run_start(__abort_stack_start)
运行结束(__abort_stack_end)
.undefinedstack:{. =。 +__undefined_stack_size;}对齐(8)
run_start(__undefined_stack_start)
运行结束(__undefined_stack_end)
}> R5F_TCMB0

/* C++项目所需的部分*/
//组{
//.arm.exidx:{}palign (8)/* C++异常处理*所需
//.init_array:{} palign (8)/*包含在main */之前调用的函数指针
//.fini数组:{} palign (8)/*包含在main */之后调用的函数指针
//}> MSRAM

/*一般用途用户共享内存,在某些示例中使用*/
//.bss.user_shared_mem (NoLoad):{}> USER_SHM_MEM
/*这在启用到共享内存的调试日志时使用,否则不使用*/
//.bss.log_shared_mem (NoLoad):{}> log_shm_mem
/*仅在启用IPC RPMessage时使用,否则不使用*/
//.bss.ipc_vring_mem (NoLoad):{}> RTOS_NORTOS_IPC_SHM_MEM
/*一般用途不可缓存内存,在某些示例中使用*/
//.bss.nocache (NoLoad):{}> non_cache_mem
}

/*
注:以下内存保留用于DMSC
-在启动过程中,直到安全移交完成
0x701E0000 - 0x701FFFFFFF (128 KB)
-在"安全移交"完成后(即运行时)
0x701F4000 - 0x701FFFFFFF (48 KB)

当此消息发送到DMSC时,安全移交完成,
TISCI_MSG_SEC_CUNCTION

加载所有内核和所有应用程序后,应立即发送此信息
设置特定的防火墙调用。
*/

内存

R5F_VECS:原始= 0x0万,长度= 0x0.004万
R5F_TCMA:原始= 0x0.004万,长度= 0x0.0007万FC0
R5F_TCMB0:原点= 0x4101万,长度= 0x0.8万

/*内存段用于保存CPU特定的非高速缓存数据,请添加MPU条目以将其标记为非高速缓存*/
//non_cache_MEM:起源= 0x7006万,长度= 0x8000

/*当使用多核应用程序时,即多个R5F/M4F处于活动状态时,请确保
*此内存不与其它R5F重叠
*/
MSRAM:原始= 0x7008万,长度= 0x4万

/*此部分可用于将应用程序的XIP部分置于闪存中,确保它不与重叠
*其他CPU。 另外,请确保为该部分添加MPU条目,并将其标记为缓存和代码可执行
*/
//flash:原点= 0x6010万,长度= 0x8万

/*共享内存段*/
/*在R5F上,
*-确保有一个MPU条目将以下区域映射为非高速缓存
*/
//USER_SHM_MEM:原点= 0x701D0000,长度= 0x180
//log_shm_MEM:原始= 0x701D0000 + 0x180,长度= 0x0.4万 - 0x180
//RTOS_NORTOS_IPC_SHM_MEM:原点= 0x701D4000,长度= 0x0000C000
}

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

    E.C,您好!

    您正在使用MCU+SDK 08.01Registered https://software-dl.ti.com/mcu-plus-sdk/esd/AM243X/08_01_00_36/exports/docs/api_guide_am243x/EXAMPLES_DRIVERS_GPIO_INPUT_INTERRUPT.html中的GPIO中断示例

    如果我将链接器命令文件与SDK示例一起使用,是否会复制您正在执行的操作?

    您是否检查了地图文件,以确认所有信息均位于TCM中,如您所愿?

    您如何测量开始/停止时间? 观察GPIO在外部切换时(源),然后观察什么? 在ISR中驱动GPIO并使用逻辑分析器查看时差?

    MSMC和TCM案例的周期计数是多少? 当所有内容都置于TCM中时,循环计数高多少?

    此致,
    弗兰克

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

    您好,Frank,

    是的

    </s>402.5264万

    如果我将链接器命令文件与SDK示例一起使用,是否会复制您正在执行的操作?

    [/引述]

    我想是的

    </s>402.5264万

    您是否检查了地图文件,以确认所有信息均位于TCM中,如您所愿?

    [/引述]

    是的

    \n您402.5264万您如何测量启动/停止时间? 观察GPIO在外部切换时(源),然后观察什么? 在ISR中驱动GPIO并使用逻辑分析器查看时差?[/QUOT]

    不,我不会在外部观察。 我是这样测量的,启动计时器始终在运行,而(1)

    同时(1)

    //写入I2C0 SDL并生成中断
    gStart = CycleCounterP_getCount32();
    }

    按下按钮后,在ISR内部测量gEnd:

    静态void __attribute_((section(".text.hwi))) gPIO_bankIsrFxn(void *args)

    gEnd = CycleCounterP_getCount32();

    }

    然后简单地测量gEnd-gStart。当它在MSRAM上运行时,我得到大约90个周期,当它在TCM上运行时,我得到大约140个周期。

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

    E.C,您好!

    好的,感谢您的反馈。

    您是否在计算MSMC和TCM案例的最小/最大/平均周期计数,您是否在周期计数中看到任何变化?

    从您分享的信息中,我看不到任何明显的原因。 我会看看是否可以重现该行为。

    此致,
    弗兰克

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

    您是否手动按下EVM上的SW5按钮以触发GPIO中断?

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

    是的

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

    E.C,您好!

    我稍微修改了GPIO中断示例。 此文件包含以下更新: /CFS-FILE/__KEY/communityserver-discussions- components_files/908/5684.gPIO_5F00_input_5F00_interrup.c

    我使用了您共享的链接程序命令文件,但在MSRAM中找到了所有内容:

    接下来,我尝试了您与TCM中的所有内容共享的链接器命令文件:

    这表明您对源代码有一些其他修改。 您能否分享您的CCS项目和源代码?

    此致,
    弗兰克

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

    您好,Frank,我想问题是源文件\整个程序对于TCM来说太大了? 也许尝试从SYSCFG中删除不必要的内容?

    不管怎样,下面是我的源代码,我对它做了一些修改,因为我想通过切换GPIO来测量中断。 概念相同:测量从触发时间到ISR执行的时间:

    #include <kernel/DPL/DebugP.h>
    #include <kernel/DPL/ClockP.h>
    #include <kernel/DPL/AddrTranslateP.h>
    #include <kernel/DPL/Hwip.h>
    #include "ti_drivers_config.h"
    包含"ti_drivers_open_close.h"
    包含"ti_board_open_close.h"
    #include "benchmarkdeme.h"

    uINT32_t gGpioBaseAddr = gPIO_PUSH_BUTTOK_BASE_ADDR;
    Hwip_Object gGpioHwiObject;
    易失性UINT32_t gGpioIntrDone =0;

    静态void gPIO_bankIsrFxn(void *args);

    extern void Board_gpioInit (void);
    extern void Board_gpioDeinit(void);
    外部UINT32_t Board_getGpioButtonIntrNum(void);
    外部UINT32_t Board_getGpioButtonSwitchNum(void);

    #include <kernel/DPL/CycleCounterP.h>

    uINT32_t gStart,gEnd,gOverhead;
    uINT32_t pinNum_button,pinNum_Test,intrNum;
    void gPIO_INPUT_INTERRUCING_MAIN (void *args)

    Int32_t RetVal;

    uINT32_t银行编号,等待计数=5;
    Hwip_Params hwiPrms;

    /*打开驱动程序以打开控制台的UART驱动程序*/
    drivers_open();
    Board_driversOpen();
    Board_gpioInit();

    // DebugP_log("GPIO输入中断测试已启动...\r\n");
    // DebugP_log("GPIO中断配置为上升边缘(按钮释放将触发中断)...\r\n");

    pinNum_buttons = gpo_push_button_PIN;
    pinNum_Test = test_gPIO_PIN;
    intrNum = Board_getGpioButtonIntrNum();
    bankNum = gPIO_GET_BANK_INDEX (pinNum_PUSHBUTTON);

    /*地址转换*/
    gGpioBaseAddr =(UINT32_t) AddrTranslateP_getLocalAddr (gGpioBaseAddr);

    /*设置用于中断生成的GPIO */
    GPIO设置方向模式(gGpioBaseAddr,pinNum_button, GPIO推送按钮_DIR);
    gPIO_setTrigType (gGpioBaseAddr,pinNum_button,gPIO_PUSH_BUTTO按钮_trig_type);
    GPIO_BankIntrEnable(gGpioBaseAddr,bankNum);

    /*寄存器引脚中断*/
    hwip_params_init(&hwiPrms);
    hwiPrms.intNum = intrNum;
    hwiPrms.callback =&GPIO _BankIsrFxn;
    hwiPrms.args =(void *) pinNum_button;
    RetVal = Hwip_construct (&gGpioHwiObject,&hwiPrms);
    DebugP_Assert (RetVal == SystemP_Success);

    CycleCounterP_reset();
    app_timerResetStats();

    /*计算管理费用*/
    gStart = CycleCounterP_getCount32();
    gEnd = CycleCounterP_getCount32();
    gOverhead = gEnd - gStart;

    gStart = CycleCounterP_getCount32();
    gPIO_PinWriteHigh (gGpioBaseAddr,pinNum_button);
    GPIO _引脚写入低(gGpioBaseAddr,pinNum_button;

    同时(1)

    //写入I2C0 SDL并生成中断
    //gStart = CycleCounterP_getCount32();
    gStart = CycleCounterP_getCount32();
    gPIO_PinWriteHigh (gGpioBaseAddr,pinNum_button);
    gEnd = CycleCounterP_getCount32();
    gOverhead = gEnd - gStart;
    }

    /*取消注册中断*/
    GPIO_BankIntrDisable(gGpioBaseAddr,bankNum);
    gPIO_setTrigType (gGpioBaseAddr,pinNum_button,gPIO_trig_type_none);
    GPIO _clearIntrStatus (gGpioBaseAddr,pinNum_button);
    hwip_析 构函数(&gGpioHwiObject);

    Board_gpioDeinit();
    Board_driversClose();
    drivers_close();
    }

    静态void __attribute_((section(".text.hwi))) gPIO_bankIsrFxn(void *args)

    gEnd = CycleCounterP_getCount32();
    GPIO针脚写入高(gGpioBaseAddr,pinNum_Test);
    GPIO针脚写入低(gGpioBaseAddr,pinNum_Test);

    uINT32_t pinNum =(UINT32_t)参数;
    UINT32_t bankNum = gPIO_GET_BANK_INDEX (pinNum);
    UINT32_t intrStatus,pinMask = gPIO_GET_BANK_Bit_MASK (pinNum);

    /*获取和清除组中断状态*/
    IntraStatus = gPIO_getBankIntrStatus(gGpioBaseAddr, bankNum);
    GPIO_clearBankIntrStatus (gGpioBaseAddr,bankNum,IntraStatus);

    /*每引脚中断处理*/
    IF (intrStatus和pinMask)

    gGpioIntrDone ++;
    }
    }

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

    E.C,

    谢谢,我来看看。

    此致,
    弗兰克

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

    E.C,您好!

    通过删除所有调试日志,我能够将代码安装到TCM中。

    我测量了四种情况下的中断延迟:

    1. 调试生成,原始链接程序命令文件
    2. 释放build,原始链接程序命令文件
    3. 链接器命令文件,链接到MSRAM的代码/数据
    4. 链接器命令文件,链接到TCM的代码/数据

    我在每个案例中捕获了20个测量值。

    以下是每种情况下的最小/最大/平均测量值:

    构建 最小 最大 平均
    debug,org链接器cmd 文件 249.00 261.00 255.10
    release,org链接程序cmd文件 146.00 212.00 150.50
    release,MSRAM链接器cmd文件 146.00 210.00 150.75
    release,tcm linker cmd文件 134.00 138.00 135.05

    以下是最后两种情况的STEM图解:

    如所见,TCM测量值比MSRAM壳体的测量值低(平均~12个周期)。 此外,对于TCM壳体,MSRAM壳体的初始较大测量值不存在。 我怀疑MSRAM的初始值较大,后面是较小的值,是由缓存引起的。

    我共享了附加文件"Captures.zip"中的原始测量.dat文件。 我还共享了附件文件"gPIO_INPUT_INTERRUPT _am243x_evm_r5fs0-0_nortos_ti-arm-clang.zip"中的CCS项目和源代码。

    请告诉我您的想法。

    此致,
    弗兰克

    /cfs/file/__key/communityserver-discussions-组件-files/908/Captures.zip

    /cfs/file/__key/communityserver-discussions-组件-files/908/gpio_5F00_input_5F00_interrupt_5F00_am243x_2D00_evm_5F00_r5fss0_2D00_0_5F00_nortos_5F00_ti_2D00_arm_2D00_clang.zip

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

    Frank,非常感谢您的详细评论。

    这很有帮助。

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

    E.C,

    没问题,我很乐意为您提供帮助。 我将关闭此线程。

    此致,
    弗兰克

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

    您好,Frank,

    当您运行时,您是否从TCM获得相同的运行值?

    检查周期计数时,我得到不同的值。 TCM的目的不是确定性的吗? 或者,我在这里错过了什么?

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

    E.C,您好!

    对于我之前分享的测试代码,我从TCM运行时获得一致的结果。 我只看到从一个周期计数快照到下一个周期计数略有变化。  以下是在LP上运行的示例:

    我在下面分享了LP示例代码。

    检查405.1763万检查周期计数时,我得到不同的值

    您看到了什么? 您是否发现从捕获到捕获之间存在巨大差异? 或者,您是否看到初始捕获值较大,随后是较小,更一致的捕获值,且变化较小?

    TCM405.1763万 TCM的用途是否确定?

    是的,它应该是决定性的。

    此致,
    弗兰克

    e2e.ti.com/.../gpio_5F00_input_5F00_interrupt_5F00_am243x_2D00_lp_5F00_r5fss0_2D00_0_5F00_nortos_5F00_ti_2D00_arm_2D00_clang.zip

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

    当我运行你的代码时,我有时会看到1401.38136142亿...这种跳跃。它永远不会在固定 值上沉降

    谢谢

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

    E.C,您好!

    我现在理解你的观点。 我会研究一下这个问题并与你一起回来。

    此致,
    弗兰克

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

    好的,谢谢

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

    E.C,

    很抱歉耽误了很长时间。 我今天或明天会进一步调查。

    此致,
    弗兰克