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.
我希望对我们为我们的应用选择的 ESM 配置运行一些最终测试。 这些测试旨在注入故障、然后通过我们的 ESM 处理程序指示哪个诊断使我们跳闸。 我在 Halcogen 中配置了以下诊断、根据它们在我们的应用中的使用情况或作为管理安全标准的要求选择每个诊断。
1:MIBADC2
6:闪存 ECC 单一
7:NHET 奇偶校验
11:内部时钟监控器
15:VIM 奇偶校验
18:MIBSPI3奇偶校验
19:MIBADC1奇偶校验
26:RAM ECC 偶数
27:CPU 自检
28:RAM ECC ODD
31:CCM 自检
35:EEPROM 单通道
36:EEPROM double
37:IOMM Mux 配置
所有 ESM 故障被配置为切换 nERROR 并触发一个低电平中断。
我们的应用和电路板 IO 架构专为使用 nERROR 引脚的所有安全输出而设计、因此在发生 ESM 错误时、我们会切断所有安全输出的电源。
我对 ESM 配置的验证是利用测试构建中的自检例程在启动检查完成后调用 ESM 故障、期望运行 ESM 处理程序、我们将看到故障得到处理。 指示我们已识别的故障可由应用捕获并适当处理。
中断处理程序如下所示
#pragma weak (esmGroup1Notification) void esmGroup1Notification (uint32 channel) { //在用户代码开始和用户代码结束之间输入用户代码。 */ *用户代码开始(1)*/ /*保存 ESM 通道 c:000.SYS.A.115.v7 */ uni_cfg_set_ESM (0U、channel); // *用户代码结束*/} //*用户代码开始(2)*/ *用户代码结束*/ #pragma weak (esmGroup2Notification) void esmGroup2Notification (uint32 channel) {// 在用户代码开始和用户代码结束之间输入用户代码。 */ *用户代码开始(3)*/ /*保存 ESM 通道 c:000.SYS.A.115.v7 */ Uni_cfg_Set_ESM (1U、通道); /*用户代码结束*/ }
uni_cfg_set_ESM 例程会将"通道"保存为 FEE。 随后的加电将允许在复位前询问此值、以便我们有机会确定我们看到的 ESM 故障类型。 我已针对以下渠道成功测试了这一点:
1、7、11、15、18、19、26、10、6、35
在我认为此验证练习已完成之前、我有以下问题、希望 TI 提供您的意见:
1.请确认当时钟监控器诊断失败时 MCU 将恢复到的时钟-是 LPO 吗?
2.确认 checkRAMUERRTest()和 checkFlashEEPROMECC()都将触发 ESM 通道6故障
3.是否有方法注入 RAM ECC 奇校验故障(通道27)?
4.是否有方法注入 EEPROM 双位故障(通道36)?
5.当我从应用程序循环中运行 cpuSelfTest()时,处理器实际上会挂起,并且我已经阅读了许多文章,表明这是预期的。 是否正确地说、在发生真正的运行时 CPU 错误时、我不能指望我的应用程序有机会执行、因此无法尝试记录通道源 ID 以收费?
6.与5类似,CCM 自检例程将不允许我的应用程序捕获并记录信道源 ID 以收费?
7.在每个 ESM 错误的情况下、nERROR 将被驱动为低电平、并在 EKR 寄存器被清除前保持低电平。 我在信道1、7、11、15、18、19、26、10、6、35中成功捕获了这种行为、但对于我上面询问的其他信道、我无法显示 nERROR 保持低电平。
我很感谢这些测试在启动代码中的启动时运行、但为了进行我自己的验证、我希望每个测试至少在工作台上一次触发适当的 nERROR 响应、并记录为 FEE。 如果有一种更好的方法来记录未来的调试、那么触发故障的 ESM 错误也是我感兴趣的。
谢谢
Jamie
在下面的屏幕截图中、您可以看到所需组1通道的典型 halcogen 配置:
以 MIBADC2为例、您可以在下面的屏幕截图中看到我在运行应用程序循环之前调用的带有 adc2ParityCheck 的编译时看到的活动。 正如预期的那样、我的调试输出显示了注册为故障的正确 ESM 通道、并且 nERROR 引脚在检测到故障时保持低电平。
现在、如果我运行一个相似的构建、但是这次调用 CheckFlashECC、正确的通道被记录为生成 ESM 错误、但是由于某种原因、nERROR 引脚不保持低电平。 我的应用中的所有逻辑与我调用 checkFlashECC 来代替 adc2ParityCheck 的逻辑是一样的。 那么、为什么 nERROR 变为高电平? 我必须理解这一点、因为生产意图构建都是假设我配置的任何 ESM 错误都会导致 nERROR 被驱动并保持低电平、直到应用程序确定可以通过清除 EKR 寄存器来释放它。
我认为可能会导致这种情况的原因之一是 ESM EKR 寄存器预加载、但我在自检例程中看不到执行此操作的任何内容。
您好、Sunil、
是的、如上所示、每个组3通道将 nERROR 设置为低电平。 我的期望是每个故障在 nERROR 上提供相同的活动、但其中一些故障不会将 nERROR 保持在低电平。 明天回到办公室时、我可能会更加具体、但在本帖子的早期部分、我列出了我需要为至少一项测试建立的所有组3故障。
谢谢
Jamie
您好、Sunil、
我在2018年9月25日的帖子12:04 AM:显示了 nERROR 的行为是如何根据我执行的自检例程而有所不同的、即使我的 ESM 组1s 都以相同的方式配置了低中断和 nERROR 驱动为低电平。 我怀疑一些例程只是预加载了 EKR 寄存器、但无法确认。 在某些情况下、我可能会使用错误的自检例程来注入故障、如果能提供有关我应该做什么的反馈、将会不胜感激。
扼要重述一下、我选择了与我的应用相关的以下第1组错误、至少需要在工作台上验证我是否可以捕获这些错误并按预期采取措施。 主要问题是
1、nERROR 不会在通道6、26上保持低电平、是什么将其清除?
2.尚未确定测试通道27、31、37的最佳方法,请告知我可以使用的方法或指导我使用测试方法
3. EEPROM 单位和双位错误一旦被注入,就会禁止我的应用程序像以前一样运行,所有输出由于 nERROR 引脚状态而断电,但我无法读取正常情况下会在下电后清除故障状态的输入按钮。 这是因为 EEPROM 上没有恢复、所以 MCU 仍然处于故障状态吗?
诊断 | 通道 | 测试例程 | 注释 |
MIBADC2 | 1 | adc2ParityCheck | n 错误确定、已正确捕获通道 ID |
闪存 ECC 单一 | 6. | CheckFlashECC | nERROR 变为高电平、通道 ID 捕捉正确 |
NHET 奇偶校验 | 7. | het1 ParityCheck | n 错误确定、已正确捕获通道 ID |
VIM RAM | 15. | vimParityCheck | n 错误确定、已正确捕获通道 ID |
MIBSPI3奇偶校验 | 18 | mibspi3 ParityCheck | n 错误确定、已正确捕获通道 ID |
MIBADC1 | 19. | adc1 ParityCheck | n 错误确定、已正确捕获通道 ID |
RAM ECC 偶数 | 26 | 校验 RAMEcc | nERROR 变为高电平、正确捕获通道 ID |
CPU 自检 | 27. | ? | 未识别测试 |
RAM ECC 奇数 | 28. | 校验 RamAddrParity | n 错误确定、已正确捕获通道 ID |
CCM 自检 | 31. | ? | 未识别测试 |
EEPROM 单一 | 35. | 修改了 checkFlashEEPROMEcc | n 错误正常、但无法清除错误? |
EEPROM double | 36. | CheckFlashEEPROMEcc | n 错误正常、但无法清除错误? |
IOMM | 37. | ? | 未识别测试 |
时钟监视器 | 11. | 手动、停止时钟 | n 错误确定、已正确捕获通道 ID |
双时钟比较 | 30 | 信号发生器来改变时钟 | n 错误确定、已正确捕获通道 ID |
感谢您提供这些信息、我正在对其进行详细介绍。
我的 IOMM 方法是在用户模式下对 IOMM 寄存器进行非法写入。 这成功地传送了预期的 ESM 响应和 nERROR 活动。
但它已经引发了其他问题。 nERROR 的活动似乎与我是否处于用户模式有关。 我会尝试解释、但这是一种令人困惑的行为!
我的应用序列如下:
1.从 FEE 初始化 ESM 记录
2.如果在上一个电源周期中未记录 ESM 故障、则注入故障(例如 ADC2Parity)
2A。 ESM 处理程序将从中断运行
2b. ESM 处理程序将通道 ID 写入 FEE 中的 ESM 记录(如步骤1中所读的那样)、nERROR 被驱动为低电平、应用程序不采取任何操作来清除 EKR 寄存器、这样它应该保持低电平
5.如果 ESM 记录显示错误,则采用故障状态
5A。 如果 nERROR 为"高电平"、即此电源循环无 ESM 错误、则允许清除 FEE 中的 ESM 记录、否则我们将保持故障状态
第2步是一个本地函数调用、在该调用中、我在注入错误之后、在进入主循环之前将内核移动到用户模式。 我这样做是因为我知道、除非有充分的理由不这样做、否则我的应用程序实际上应该以用户模式运行。 当我在这个本地函数中转换到用户模式时、nERROR 活动正如我预期的那样、当我们注入故障时、仍然保持低电平。
如果我在本地函数调用后将采用用户模式的指令移动到、但在进入 回路和状态机的 main 之前、nERROR 活动不正确。 在低电平时间计数器到期后、它再次变为高电平。 就好像进入用户模式的指令的位置以某种方式影响了 nERROR 清零或保持低电平一样。 我找不到任何对 EKR 寄存器有影响的用户模式的引用、这将导致 nERROR 再次被驱动为高电平。 我当然不明白为什么在指令显著改变行为后、将指令从本地函数内移动到立即语句中进入用户模式。 这是否与中断排序有关、命令进入用户模式是否有其他可能对 EKR 寄存器状态产生不利影响、从而释放 nERROR 引脚?
作为参考、我使用 Simple asm (" CPS 30x10");指令进入用户模式。
我觉得在连接 FEE 驱动器的过程中有一些奇怪的东西。 我现在看到、当我没有模块处于用户模式时、我的 FEE 写入来重置我的 ESM 工作记录、但是当我在用户模式下运行时、它们是不完整/不成功的。 这是一个这样的函数、它在不处于用户模式时成功写入、但在我将应用程序移至用户模式时不完整/不成功。
void uni_cfg_ESM_UPD (void) { if (uni_cfg_ESM_WRITE 和&(IDLE = TI_FEE (0))) { uni_cfg_packdata (uni_cfg_blk2_params、UNI_CFG_NUMPARAMS_BLK2); TI_fee_WriteSync (2、fee_databuffer); Uni_cfg_ESM_WRITE = false; } }/* end uni_cfg_ESM_UPD_l */
以1秒的间隔读回块、当处于用户模式时、读操作并不表示成功、即我尝试写入的值返回错误。 如果不处于用户模式、则始终会成功。 因此、当处于用户模式时、某些东西会中断或阻止成功读取/写入。
当我与 TI_FEE 读取/写入库函数连接以首先进入特权状态时、我是否应该做一些特定的事情?
在这里、我们绝对要总结一个根本原因。
因此、更早地进入用户模式、当我从 EEPROM 初始化所有全局配置数据时、FEE 读取显然会失败。 如果我在初始化例程之前进入用户模式、我基本上会从 EEPROM 中获取垃圾、如果我在从 EEPROM 初始化之后转到用户模式、则我的配置数据是准确的。 RTI 中断与处于用户模式的情况是否会使我的读取变得更小? 每个块都使用类似如下的结构进行初始化:
TI_FeeModuleStatusType Status_l; TI_fee_read (5、0、(uint8*) fee_databuffer、UNI CFG_SIZE _BLK5); 操作 { TI_fee_MainFunction(); delay(); status_l=TI_fee_GetStatus (0); } while (Status_l!=空闲); uni_cfg_unpackdata (uni_cfg_blk5_params、UNI_CFG_NUMPARAMS_BLK5);
解压功能如下所示:
void uni_cfg_unpackdata (struct fee_data_block* dbp、uint8 numparams) { char *p; P =&FEE 数据库[0]; 数据块中每个参数的/*// for (uint8 i=0;i< numparams;i++) { //写入每个字节并移动数据库指针*/ for (uint8 j=0;j < dbp[i].size;j++) { *(dbp[i].address + j)=*p; P++; } } }/* end uni_cfg_unpackdata *
我认为解包例程是可以的、因为当我在特权模式下运行读取操作时、它工作正常。 因此、我得出的结论是 TI_fee_read、可能还有 TI_fee_Write 等
1.只能在特权模式下运行
2.如果 RTI 中断或类似中断在 FEE 活动期间发生、则可能被中断或返回错误数据
3.收费库函数在用户模式之间切换至初始模式或防止中断时本身并不安全
希望在用户模式下安全/正确使用 TI_FEE 库的任何指导或示例。
您好 QJ、
今天上午、我举了 SPNA218的示例、并通过提供的 SVC 处理程序示例将模式切换器从用户模式集成到系统模式。 由于我在使用 FEE 时仅使用 SVC 在模式之间移动、因此我具有以下汇编器函数:
;------------------------------------------------------------------ ; SWI 包装程序 .global _Svc .text ARM .armfunc _svc .align 4 _svc: asmfunc ;保留程序 A1和 A2可以保存 C 级处理程序中所需的函数参数 ;注意:此处理程序不保留被调用方保存(调用保存)寄存器 A1至 A4和 V9。 ; 换句话说、被调用方函数必须保留它们、当在 C 中使用诸如 SVC 的函数(#pragma SWI_ALIAS ()或__Svc ())时、可以确保这些函数得到保留 ; 在汇编内联 SVC/SWI 时要小心。 夫人 A4、SPSR ;获取 spsr TST A4、#0x20 ;在 Thumb 状态下调用? ;注:从 Thumb 代码调用时,只有256个独特的 SVC 处理程序可以被扩展,因为 Thumb SVC 指令只有一个8位字段。 ; 当从 ARM 代码2^24调用时、由于 ARM SVC 指令有一个24位字段、因此可以对独特的 SVC 处理程序进行扩展。 LDRNEH A3、[LR、#-2] ;是:加载半字和... BICNE A3、A3、#0xFF00 ;...提取备注字段 LDREQ A3、[LR、#-4] ;否:加载字和... BICEQ A3、A3、#0xFF000000;...提取注释字段 ;R2/A3现在包含 SVC 编号 ;R3/A4现在包含 SPSR (保存的程序状态寄存器) CMP A3、#32 BHI 默认(_default) ;如果 LDRLS 较高,则分支 PC,[PC、A3、LSL #2];从表 .word 0x00 _table 加载地址:.word (_case0);未实现 SVC .word (_case1);switchCpuMode .word (_case2);switchToSystemMode .word (_case3);switchToUserMode .word 0x00 _case0:;未实现的 SVC (用于测试故障处理程序) B _default _case1:;switchCpuMode 和 A2、A1、#0x0000001F;确保只有模式位位于 A1中 和 A1、A4、#0x0000001F;在 R0/A1中存储入口模式以将其返回给被调用方 BIC A4、A4、#0x0000001F;清除模式位 OR A4、A4、A2 ;将模式位设置为 A2 (前 A1)中的值 MSR SPSR_cxsf、A4 ;恢复 spsr B _exit_svc ;分支以退出处理程序 _case2:; switchToSystemMode ;BIC A4、A4、#0x0000001F OR A4、A4、#0x0000001F;为系统模式设置位(M0-M4已设置) MSR SPSR_cxsf、A4 ;恢复 spsr B _exit_svc _case3:;switchToUserMode BIC A4、A4、#0x0000001F;清除模式位 OR A4、A4、#0x00000010;为用户模式设置模式位 MSR SPSR_cxsf、A4 ;恢复 spsr B _exit_svc _default: _exit_svc: MOV PC、LR ;异常返回 endasmfunc .end
将#defines 添加到相关的 include 文件中:
#pragma SWI_ALIAS (未实现的 SVC、 0); #pragma SWI_ALIAS (switchCpuMode、 1); #pragma SWI_ALIAS (switchToSystemMode、2); #pragma SWI_ALIAS (switchToUserMode、 3); 无效 未实现 SVC (void);//用于测试故障处理程序*/ uint32_t switchCpuMode (uint32_t u32ModeNum); void SwitchToSystemMode (void); void SwitchToUserMode (void);
我通过复制调用 FEE 驱动程序例程时不切换至系统模式而遇到的故障、验证了模式切换器功能是否正常工作。 所以我认为这些工作。 典型逻辑如下所示:
TI_FeeModuleStatusType Status_l; SwitchToSystemMode(); if (uni_cfg_TIM_WRITE &&(IDLE = TI_FEE (0))) { uni_cfg_packdata (uni_cfg_blk3_params、UNI CFG_NUMPARAMS_BLK3); TI_fee_WriteSync (3、(uint8*) fee_databuffer); Uni_cfg_Timer_write = false; } uni_cfg_unpackdata (uni_cfg_blk2_params、UNI_CFG_NUMPARAMS_BLK2); switchToUserMode();
我现在看到的问题是、我的 RTI 中断在我执行写入时被杀死。 看起来我会得到一个寄生中断、该中断将我发送到 undefEntry 矢量。 您能看到我的汇编器例程存在明显的问题吗? 我将不断挖掘、尝试并了解 UndefEntry 的来源。