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.

[参考译文] TM4C1294NCPDT:FreeRTOS 10.2.1和 Tiva

Guru**** 2534650 points
Other Parts Discussed in Thread: TM4C1294NCPDT

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/874132/tm4c1294ncpdt-freertos-10-2-1-and-tiva

器件型号:TM4C1294NCPDT

你好!

我正在努力将 FreeRTOS 内核移植到 TM4C1294ncpdt 定制板上。 我使用的是 FreeRTOS 10.2.1和 CCS 9.1。

我已经创建了一个项目、为堆分配了51200 (50k)个字节。 堆栈的32768 (32k)字节、我认为我有要匹配的链接器文件。 我使用了一些旧示例以及 FreeRTOS 下载示例进行比较。  

在未创建任何任务的情况下、调度程序会按预期启动并命中 SysTick ISR。  

我遇到的问题是创建任务。 作为任务创建的一部分、tasks.c 文件中有一个 memset 函数、用于"使用已知值填充栈以帮助调试"。 该 memset 将我的微控制器放入故障 ISR。 内存浏览器显示为指示没有单次迭代成功。

我被骗了。 memset 中的什么会导致我的处理器遇到硬故障处理程序? 代码似乎在以逻辑 SRAM 位置和大小传递。 我还需要启用其他功能来支持 memset 吗?  如果有任何见解,将不胜感激。  

谢谢!  

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

    下面是讨论调试 Cortex M 系列器件硬故障的旧应用手册:

    http://www.ti.com/lit/an/spma043/spma043.pdf

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

    我以前见过这份文档。 我感谢链接。 不幸的是,它没有帮助。 它提供的精确总线地址位于存储器的保留区域。  

    然而,我取得了一些进展。 我将其缩小到了三行代码。  

    //启用 EEPROM 外设
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_EEPROM0);
    while (!ROM_SysCtlPeripheralReady (SYSCTL_Periph_EEPROM0)){


    tmp32 = EEPROMInit();//出于某种原因,这不是 ROM_*函数

    if (tmp32!= EEPROM_INIT_OK){
    while (1){


    启用 EEPROM 会在稍后调用 memset 时导致问题。 实际上、我还没有开始进行 EEPROM 调用。 在我的板上启用外设初始化函数。 删除此行,问题就会消失。  

    我需要做更多的挖掘来解释这个。 勘误表似乎没有任何解释。 唯一的关闭代码是当 EEPROM 处于活动状态时、MEM#12代码从闪存跳转到 ROM、并且可能永远不会返回。 但是、EEPROM 的工作位不在计数。 我只会看到 EEPROM 偏移寄存器勾选消失。  

    除非有人对此进行解释、否则我会继续挖掘。

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

    写入保留位置肯定会导致中止。 如果与 memset 函数关联、可能是您以某种方式将未初始化的变量用作地址。 EEPROM 初始化可能会更改所用寄存器中的值、从而不再发生错误。 如果您可以通过查看链接寄存器来识别实际导致中止的地址和汇编指令、则可以在该指令上设置断点并标识正在使用的地址。  

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

    尊敬的 Bob:

    我想您正在做一些事情。 删除 EEPROM 初始化后问题仍然存在。  

    我遇到了一个不精确的总线故障、但按照您提供的链接、我似乎已经将它与 portasm.asm FreeRTOS 端口内的 xPortPendSVHandler 隔离。 按照 FreeRTOS 建议、我将 NVIC_ACTLR 寄存器中的 DISWBUF 位置位。 由于设置了"BFARV"总线故障地址寄存器的有效位以及同时设置了"STAT_PRECISE"位、因此这确实设置了看起来是一个精确的总线故障错误。 但是、给出的地址毫无意义。 这是一种尝试并指出问题的有效方法吗?

    处理不精确总线故障(来自 FreeRTOS)  

    https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

    虽然不是专门写 Flash、但我的问题是否可能与此帖子有关?

    https://e2e.ti.com/support/microcontrollers/other/f/908/p/671683/2494679

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

    您好!

     Bob 不在办公室。  

     由于您有一个精确的故障、因此您应该能够在导致故障的地址放置一个断点并检查指令正在执行的操作。 您知道哪个地址产生了故障吗?  

     您之前说过您正在尝试使用 memset 来初始化堆栈。 您是调用 memset 还是由 FreeRTOS 调用? 传递给 memset 的长度是多少? 我不确定为什么使用 memset 来初始化堆栈。 在 memset 和 memset 刚刚擦除存储器之前、栈可能已被压入以存储一些上下文、当您返回时、弹出窗口会导致故障。 这只是一个猜测。  

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

    您好、Charles、

    感谢您的参与。  

    我相信我是前一个记忆组的领导者。 或者我有一个非常脆弱的项目。 memset 似乎不再是问题了。 更新后禁用高速缓存并强制模糊故障成为精确故障、我得到上面的屏幕截图。 0xFFFFFFDC 的故障位置对我来说毫无意义。 在禁用高速缓存之前、我按照 Bob 为调试硬故障提供的链接进行了操作。 使用异常堆栈框、我将其缩小到 portasm.asm 内的一个汇编代码块。 特别是 xPortPendSVChandler。  

    设置 DISWBUF 并使用调试器进行设置后、我将进入以下行、向故障 ISR 发送我的消息:

    ;/*保存内核寄存器。 */
    stmdb r0!、{R4-r11、r14}
    

    我不能加快 M4汇编指令的速度、但我不确定该指令为什么会导致错误的硬件故障地址。

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

    尊敬的 Jeff:

     r0寄存器中包含什么内容? 这个指令正在尝试将数据压入堆栈。 如果 r0包含损坏的值、则可能导致总线故障。 例如、如果 r0包含无效的地址指针、则会导致存储器系统出现总线故障。 您是否可以尝试增大堆栈大小并查看这是否会产生影响?  

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

    您好、Charles、

    在故障发生之前、它为0x00。 随附的是故障前的寄存器屏幕截图以及堆栈大小(32k)和 cmd 文件。 我将尝试使堆栈大小加倍、但看起来太大了。  

    谢谢!


    /********* * *德州仪器 TM4C1294NCPDT 的默认链接器命令文件 * 这是从 TivaWare 库的修订版15071衍生而来的。 * * / -retain=g_pfnVectors #define CRC_SIZE4 #define FW_ID_SIZE72 #define APP_BASE 0x00000000 #define APP_SIZE0x38000 - FW_ID_SIZE - CRC_SIZE #define FW_ID_BASE APP_SIZE + APP_SIZE + APP_SIZE + FW_ID_RAM_SIZE #define HF000_RAM#define HF000_SIZE #define HF000_RAM_BASE_SIZE #define 0x2000_RAM#define RAM _SIZE #define HF000_RAM_SIZE #define HF000_MEMORT_SIZE #define 0xL 闪存(RX):origin = app_BASE,length = app_size FWID (R):origin = FW_ID_base、length = FW_ID_SIZE、fill = 0xFFFFFFFF CRC (R):origin = CRC_BASE,length = CRC_SIZE SRAM (rwx):origin = RAM_base,length = RAM_SIZE HFLT (RW):origin = HFLT_BASE,length = HFLT_size } //以下命令行选项作为 CCS 项目的一部分进行设置。 */ /*如果您使用命令行进行构建,或者出于某种原因想要在 此处定义*/*,则可以根据需要取消注释并修改这些行。 */ /*如果您使用 CCS 进行编译、最好 在 CCS 工程中进行任何此类*///*修改并将此文件单独保留。 */ * // /*--heap_size=0 */ *--stack_size=256 /* --library=rtsv7M4_T_le_eabi.lib 内存中的*//*段分配*/ 段 { .intvecs:load = app_base .text:palign (32),load = flash fwid:load = FWID .crc:load = crc .const:palign (32),load = flash .cinit:palign (32),load = flash .pinit:palign (32),load = flash init_array:> FLASH .stack:> RAM_base .vtable:> SRAM .data :> SRAM .bss:> SRAM .sysmem:> SRAM .hflt:>HFLT 类型= NOINIT }

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

    尊敬的 Jeff:

     r0不正确。 0x0是闪存存储器的地址。 您不能将数据推送到闪存中、因此、写入闪存控制器时会生成总线错误。 堆栈将位于从0x20000000开始的 SRAM 上。 您将需要滚动一些说明以了解为什么加载了错误的值 r0。  

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

    您好、Charles、

    感谢您的确认。 该行被很好地嵌在 FreeRTOS port.asm 文件中。 我没有解释为何这会导致故障。  

    我注意到的一点是、在可用的一个示例项目上、优化已启用到2级全局优化。 为了乐趣,我尝试了它。 问题消失了。 这不会给我一种温暖和模糊的感觉。 我将在他们的留言板上发帖。  

    再次感谢!

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

    尊敬的 Jeff:

     如何增加堆栈大小? 通常、链接器命令将具有以下示例行、但我在.cmd 文件中看不到。 您能否将此行添加到您的中、但用您拥有的32k 替换4096?  

    __STACK_TOP =__STACK + 4096;

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

    您好、Charles、

    我一直通过项目属性->ARM linker->basic options->set c system stack size->32768进行更新。  

    在将存储器段重新排列为 cmd 文件的一部分后、我删除了该行。 我的理解是、对于更新了其搜索方法(使用_stack_top 的标准编译器定义)或不再需要该定义的库而言、这是一个必需的旧行。

    这不是正确的假设吗?

    谢谢、

    Jeff

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

    尊敬的 Jeff:

     _stack_top 是指向堆栈顶部的指针、该堆栈顶部将被加载到 SP 寄存器。 请参阅下面的 startup_ccs.c 您是否未使用标准的 startup_ccs.c 文件? 如何加载 SP 寄存器?

    //
    //
    //矢量表。 请注意、必须在这个上放置适当的结构、
    以//确保它在物理地址0x0000.0000处结束、或者
    在//程序的开头(如果位于0以外的起始地址)结束。
    ////
    *****************
    #pragma DATA_SECTION (g_pfnVectors、".intvecs")
    void (* const g_pfnVectors [])(void)=
    {
    (void (*)(void)((uint32_t)&_stack_top)、
    //初始堆栈指针
    ResetISR、 //重置处理程序
    NmiSR、 // NMI 处理程序
    FaultISR、 //硬故障处理程序 

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

    您好、Charles、

    同意。 我确实需要更新我的 startup_ccs 文件。 我将__STACK_TOP 与__STACK_END 交换,它们看起来是相同的定义地址。 _stack_end 只是编译器支持的定义、删除了在两个位置定义栈大小的要求。 (我很难记住这两个方面的更新)。

    谢谢、

    Jeff

     

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

    尊敬的 Jeff:

     您能告诉我问题是否因此得到解决吗?