主题中讨论的其他器件:C2000WARE
您好、香榭丽舍
当我们确认 值除以零时,值显示 FFFFFFFFh 并继续处理而不进行异常处理。
我参考了下面的 e2e 线程。
然后我确认了"LVF 或 LUF"检测上溢或下溢标志。
您能告诉我们如何在值除以零时设置异常标志吗?
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.
您好、香榭丽舍
当我们确认 值除以零时,值显示 FFFFFFFFh 并继续处理而不进行异常处理。
我参考了下面的 e2e 线程。
然后我确认了"LVF 或 LUF"检测上溢或下溢标志。
您能告诉我们如何在值除以零时设置异常标志吗?
如果在执行相应的 FPU 汇编指令时分别发生数值上溢或下溢、LVF 和 LUF 标志会保护算法。 这些是 FPU 状态寄存器中的标志、因此它们仅与浮点除法相关。 你在干什么?
如果您使用 C 语言编码并执行浮点除法、编译器将调用 RTS 库函数。 对于单精度除法、将调用 FS$$DIV 函数。 该函 数将检测到除以零并返回可在单精度中表达的最大浮点值(即、除以零的单精度将返回3.38953139e+38)。
我已经附加了该函数的代码、因为顶部附近的注释对此进行了说明。 您可以在 以下位置找到此和其他 RTS 源代码:C:\ti\ccsv7\tools\compiler\c2000_#.#.#.#\lib\src
由于调用本身正在处理异常、因此不会设置 LVF 和 LUF 标志。 如果您想捕获此情况、可以修改源代码、以便在相应的行使用 SETFLG 指令设置这些标志。 这也适用于双精度例程。
我已经详细解释了所有这些、因为您询问了仅存在于 FPU 上的 LVF 和 LUF 标志。 从您的描述中、您会看到一个 ACC 值0xFFFFFFFF、如果您尝试用整数除以零、则会发生此情况。 整数数学指令在 C28x 内核(而不是 FPU)上执行、因此不涉及 LVF 和 LVF 标志。
此时、我需要在模式上明确您想要执行的操作。 您能否发送代码片段进行解释?
此致、
Richard
是的、可以这样做、但必须修改 RTS 汇编例程。
使用您发送给我的整数类型执行除法会导致调用 LL$DIV 函数。 您将在 CCS 的拆分窗口中看到该调用。 要在零分频时强制用户中断、您必须修改"LL_div28.asm"文件、以便在代码中插入一个陷阱指令。 我没有这样做、但将分母参数与零进行比较并插入条件分支应该是简单的。 然后、您插入和汇编指令来生成软件中断、例如:
陷阱20
将强制 User1中断。
修改了源代码后、您将需要重新构建 RTS 库、C 编译器用户指南的第8.4节中对此进行了介绍:
http://www.ti.com/lit/ug/spru514m/spru514m.pdf
完成此操作后,您可以在 C 代码中编写 ISR (例如,"TrapIsr()"),并将地址加载到 PIE 矢量表,就像任何其他 ISR 一样:
PieVectTable.User1 =&TrapIsr;
然后、您可以在 ISR 中编写代码、以根据需要处理零分频事件。
此致、
Richard
不用客气!
该文件不在 C2000Ware 中。 它是 codegen 工具的一部分、您可以在我的第一篇文章中找到它:
C:\ti\ccsv7\tools\compiler\c2000_#.#.#\lib\src
其中"#.#.#"是 您安装的 CGT 版本。 例如、在我的计算机上、完整路径名称为:
C:\ti\ccsv7\tools\compiler\ti-cgt-C2000_16.9.3.LTS lib\src
此致、
Richard
是的、您仍需要按照 Richard 的指示插入陷阱。 interrupt_illegalOperationHandler()只是 driverlib 提供的缺省 ISR,在发生 ITRAP 时被调用。 如果要对插入的陷阱使用相同的 ISR,可以通过调用 Interrupt_register()将其地址放入 PIE 矢量表来实现。
Interrupt_register (INT_User1、Interrupt_illegalOperationHandler);
或者、您也可以对全新的 ISR 执行相同的操作。
惠特尼
您好、Whitney、
您能告诉我如何在 C 代码中启用 INT_User1吗?
main(){
:
:
int64 s64_temp;
uint32 u32_temp;
Interrupt_register (INT_User1、Interrupt_illegalOperationHandler);
for (;;)
{
s64_temp = s64_temp / u32_temp;
if (s64_temp < 0){
//用户应如何为 非法中断设置 INT_User1?
}
}
}
静态空 Interrupt_illegalOperationHandler (空)
{
//
//出现了问题。 CPU 试图执行一个非法的
//指令,生成非法指令陷阱(ITRAP)。
//
ESTOP0;
for (;;)
{
;
}
}
此致、
Nagata。
为了检测帖子中代码的零分频条件、您需要相应地修改"LL_div28.asm"文件并重新构建 RTS 库。
在执行任何操作之前、请将"ll_div28.asm"文件从库源目录(请参阅上一篇文章)移动(不要复制)到硬盘上安全的地方、以便备份。
我已将修改后的文件附加到此帖子。 如果您查看附加的文件、您将看到有关176行的一些附加说明、以便在分母为零时强制执行 User1中断。 我没有改变任何其他东西。 将此文件放在旧文件所在的库源目录中。
找到您的库目录。 在我的计算机上、目录为:
C:\ti\ccsv7\tools\compiler\ti-cgt-C2000_16.9.3.LTS \lib
然后、在安全的地方从库目录中移动(不要复制)库(扩展名为.lib 的文件)、这样您就可以进行备份。 删除这些内容将强制 CCS 在编译工程时重新编译库。
在项目中、您需要在初始化代码中启用 User1中断...
PieVectTable.User1 =&TrapIsr;
...并按照我之前所述编写 ISR ...
中断空 TrapIsr (空)
{
asm (" NOP"); //此处为断点
}
然后重新构建您的 CCS 项目。 当分母为相同的零时、您应该获得 User1中断、否则它将像以前一样工作。
它在我的设置上似乎工作正常。 可以尝试一下吗?
此致、
Richard