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.

[参考译文] AM3352:执行的 vldr s0、[R12、#8]、MODE 变为 ABORT。

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/781266/am3352-executed-vldr-s0-r12-8-and-mode-goes-to-abort

器件型号:AM3352

在下图中、ARM 将从 UNION "SPL_SensingMic "内加载变量"UI_SPL_SensingMic "。

执行的操作

1.从 sp 获取基址。

有道理。 它是 struct *(element)的基址。

2.将地址0x803657D2+8中的值加载到寄存器 s0中。

这里的逻辑电路没有问题。

执行后、ARM 从监控器进入中止模式。

引用自 ARM 系统开发人员指南-设计和优化系统软件:

μ「预取中止向量在处理器试图从没有正确访问权限的地址提取指令时发生。 实际中止发生在解码阶段。」

「数据中止向量类似于预取中止、但当指令在没有正确访问权限的情况下尝试访问数据存储器时、会产生该向量。」


在这种情况下、我不确定该中止预取还是数据?

为什么会发生这种情况?

这是编译器测试用例

"c:/ti/ccsv8/tools/compiler/ti-cgt-arm_5.2.5/bin/armcl /ti/ccsv8/ATEIS /ti/ccsv8/ATEIS /ti/ccsv8/ATEIS -mv7A8 --code_state=32 --float_support=VFPv3 --abi=eabi -me --include_path="C:/ti/ccsv8/tools/compiler/ti-cgt-arm_5.2.5/include /ti/ccsv8/ATEIS /ti/ccsv8/ATEIS /ti/ccsv8/ATEIS --include_path="C:/ti/ccsv8/ATEIS AM335X/include/ucos include"--include:/ti/ccsv8/ATEIS AM335X/include:/ti/ccsv8/ATEIS AM335X/include:包含"AM335X/include:/ti/ccsv8/ATEIS /ti/ccsv8/ATEIS include_path="C:/ti/ccsv8/ATEIS /ti/ccsv8/ATEIS am335X/include/Lib_DSP_function"--include_path="C:/ti/ccsv8/ATEIS /ti/ccsv8/ATEIS am335X/include/Lib_DSP_Filter"--include_path="C:/ti/ccsv8/ATEIS /Middleware/DNM_Channel.c am335X/source 代码/include_remote_display_intransc_super-ine_remote_remote_ine_ine_intrade-come-come_ines=-ine_ine_ine_intransc/cc_ine_remote_remote_remote_ines=-ines=-ines=-ine_remote_remote_ine_ine_remote_remote_remote_ines=-ines=-ine_ine_ines=-ine_ine_inese-cov-ines=-ccs_enote_remote_remote_display-ines=-ines=-ines=-ine_ines=-intr-ine_ine_ine_ines=-inese-ines=-inese-ine_inese-inese-cov-ines=-inese-in
已完成构建:"./Middleware/DNM_Channel.c

e2e.ti.com/.../DNM_5F00_Channel.pp.txt

编辑:

引用自 ARM 系统开发人员指南-再次设计和优化系统软件。

我猜中止的原因是地址 0x803657D2+8不是四个字节的倍数。

但为什么编译器不将此变量分配给4的倍数? 我没有指定 packed 到结构、因此它应该是多4的地址。

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

    这是哪个 SDK? 什么版本?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好
    我很抱歉。 我不知道您指的是什么 SDK。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我指的是 AM335x 处理器 SDK: www.ti.com/.../PROCESSOR-SDK-AM335X 您是否在使用它? 如果不是、这是什么软件?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我只想解决我遇到的这个问题。
    我不知道我使用的是什么 SDK。
    我可以问这个问题与 SDK 有关吗?
    或者、我是否在错误的论坛上发布了此问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    问题从该函数开始...

    DNMMChannel_t* DNMMChannel_New (void)
    {
    return (DNMMChannel_t*)&AP_Table_DSP.DNM.Ch;
    }
    

    结构类型 DNMMChannel_t 假定字段 Ch 位于4字节对齐地址、但它仅与2字节对齐地址对齐。  编译器不会检查是否满足此对齐约束。  通过插入 cast、您可以指示类型中的此更改是正常的。   

    首先、我展示了 Ch 不保证为4字节对齐。  字段 Ch 是此类型的结构...

    typedef 结构
    {
    uint16_t IP[2];
    uint16_t Zone_MechanicID;
    uint16_t LED_Working 状态;
    uint16_t SPL_SensingMic [2];
    uint16_t Weight[2];
    uint16_HwVersion;
    }AP_Channel_DNM_s;
    

    重要的一点是、它不包含任何需要4字节对齐的内容。  字段 Ch 来自此结构...

    typedef 结构
    {
    AP_Main_DNM_s 主;
    Amp_Mode_Struct_s ModeAmp[NumAmpMode];
    AP_Channel_DNM_s CH;
    }AP_Master_DNM_s;
    

    事实证明、字段 Ch 与该结构体的开头偏移86个字节。  该结构本身是否为4字节对齐也许很有趣、但没关系。  如果是4字节对齐、则 Ch 永远不是4字节对齐。  如果它是2字节对齐、则 Ch 可以是4字节对齐、但这不能保证。

    现在、我展示结构类型 DNMMChannel_t 需要4字节对齐。  这是这种类型...

    struct DNMMannel_t
    {
    union
    {
    uint32_t MCU_IP;
    uint16_t DSP_IP[2];
    }IP;
    uint16_t Zone_MechanicID;
    uint16_t LED_Working 状态;
    UNION
    {
    float UI_SPL_SensingMic;
    uint16_t DSP_SensingMic [2];
    }SPL_SensingMic;
    uint16_t Weight[2];
    uint16_t HwVersion;
    }; 

    uint32_t 和 float 类型要求这个结构类型为4字节对齐。

    此代码包含大量类型、它们之间有许多关系。  因此、我犹豫是否推荐解决方案。  熟悉代码的人需要推荐解决方案。

    谢谢、此致、

    乔治

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

    谢谢、这是一个很好的解释。

    对此我有几个问题。

    引用自 ARM 系统开发人员指南设计和优化系统软件:

    除 LDR 之外、还有多个不同传输大小的说明。

    我认为编译器足够聪明、可以决定应该使用哪条指令。

    在这种情况下、编译器知道地址是2的倍数、传输大小为4。 为什么编译器使用 LDR 而不是 LDRH?

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

    [引用用户="Andy Lin94"]为什么编译器使用 LDR 而不是 LDRH?

    因为编译器假定它正在访问 DNMMChannel_t 类型结构中的字段   编译器分配的每个此类结构都与4字节边界对齐。  当您为 DNMMChannel_t 指针分配(或从函数返回或类似内容)时、分配的表达式必须具有相同的类型、或者通过转换将其更改为该类型。  通过强制转换、用户承担确保满足任何对齐约束的责任。   

    以下是一些理由。  如果它的工作方式不同、则编译器必须保守地假定所有指针都可能未对齐、并为32位加载发出4条 LDRB 指令。  这会浪费周期和代码空间。

    谢谢、此致、

    乔治

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

    [引用]编译器分配的每个此类结构都与4字节边界对齐。

    编译器仅分配变量、不分配结构类型。

    在本例中、编译器看到的方式是:哦、我知道我需要使用 AP_Channel_DNM_s 类型分配一个变量 、因此我看看 程序员如何定义 AP_Channel_DNM_s、以便决定 如何对齐该变量。 因此、变量 Ch 与2个字节对齐。

    然后、编程人员 请求执行以下操作:

    DNMMChannel_t* DNMMChannel_New (void)
    {
    返回(DNMMChannel_t*)&AP_Table_DSP.DNM.Ch;
    } 

    编译器将类似于:好的、我也可以通过这种方式查看该变量 Ch。

    [引用]通过转换、用户承担确保满足任何对齐约束的责任。

    是的、你是对的、确实是这样。 CH 确实 实现了对齐约束:Ch 中的所有成员都从相同的地址开始、编译器会以 AP_Channel_DNM_s 或 DNMMChannel_t 的方式看到该地址

    [引用]如果其工作方式不同、则编译器必须保守地假设所有指针都可能未对齐

    我不确定"指针可能未对齐"是什么意思。 在这种情况下、指针实际上对齐、指向相同的地址、传输大小也相同。

    [引用]并为32位负载发出4条 LDRB 指令。  这浪费了周期和代码空间。[/quot]

    如何告诉编译器、比如:嘿! 默认情况下不能使用 LDR,因为成员的地址可能是2或4的倍数。 您应该先检查地址、然后确定使用的指令。

    我可以做的另一种方法是强制编译器在多个4地址分配 Ch、以便它不会影响转换。 但如何让编译器执行它呢?

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

    [引用 user="Andy Lin94">如何告诉编译器:嘿! 默认情况下不能使用 LDR,因为成员的地址可能是2或4的倍数。

    遗憾的是、没有方法可以这样做。

    [引用 user="Andy Lin94"]您应先检查地址,然后确定使用的指令。

    这意味着编译器应发出代码、在运行时检查地址是否对齐。  这是不切实际的。

    [引用用户="Andy Lin94"]我可以做的另一种方法是强制编译器在多个4的地址分配 Ch [/引用]

    向需要4字节对齐的结构中添加字段、即使您从未使用过该字段。  如果您使用此方法、请对其进行清晰的注释。

    谢谢、此致、

    乔治