Other Parts Discussed in Thread: SYSBIOS
您好!
我正在解决由于从 DSP-BIOS 移植到 C6746上的最新 SYS-BIOS 而产生的运行时问题。 我不断收到异常错误、但仍不知道原因。 我想、如果我从下面的 ROV 中发布异常转储、是否有人可以给我一些关于可能出错的问题的指示、或者要尝试的后续步骤。
谢谢、
Robert
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.
[引用 user="Brad Griffies">SWI 在出现问题之前运行了多少次? 那么、它在达到该 SWI 后是否崩溃? 可能根本的问题是 SWI 结构损坏。 也许我们需要看一下。
[/报价]
它永远不会到达 SWI。 我目前正在尝试单步执行一些 BIOS 代码、以查看会导致它关闭的原因。 不过、我不确定这是否起作用、因为可能是导致异常的某种事件组合、单步执行时我不会看到这种情况。 不过、它似乎通过了 Swi_post () ok。 因此、可能在 POST 和实际 Swi 函数之间的某个位置出现了问题。
Robert
您好!
异常发生在对与其关联的 SWI 的第一次调用上、这是应用程序中的第一个 SWI、因此我可以在 Swi.c 中设置一个断点、就在它发生之前。 下面是到目前为止找到的序列:
1) 1)程序加载后、按 F8。 它涉及 Swi.c/Swi_run ()中的第116行、如第一个图所示。 第二个和第三个图显示了 fxn 和参数、它们都是合理的。
2) 2)按 F8。 在这种情况下、它在第114行达到断点、而不是118、如第四个图所示。 这告诉我它重新进入了 Swi_run 函数、而没有退出或移动到它的第一个条目。
3) 3)按 F8。 它到达第116行的断点
4) 4)按 F8键、会出现异常、不会在114、116或118处执行任何断点、也不会在关联的 SWI 函数处理程序的开头设置断点。
是否存在某种可重入性问题?
如果有任何关于增加步骤的想法,将不胜感激。
Robert
下面是相关的配置。
VAR Swi = xdc.useModule ('ti.sysbios.KNL.Swi');
SWI.numPriorities = 9;
var swi_params_edma_acq_left = new swi.params();
SWI_params_EDMA_ACQ_LEFT.priority = 7;
swi_params_edma_acq_left.instance.name ="swi_edma_acq_left";
program.global.swi_edma_acq_left = swi.create ('&swi_fxn_edma_acq_left'、swi_params_edma_acq_left);
不过、发生了有趣的事情。 我更改了配置文件中有关诊断程序的一些内容、它似乎不再例外。
我做了这个改变... 请参阅注释行和未注释行
//Main.common$.diags_INFO = Diags.always_on;
//Main.common$.diags_ANALYSIS = Diags.always_off;
//Main.common$.diags_STATUS = Diags.always_off;
//Main.common$.diags_ENTRY = Diags.always_off;
//Main.common$.diags_EXIT = Diags.always_off;
//Main.common$.diags_LIFECYCLE = Diags.always_off;
//Main.common$.diags_INTERNAL = Diags.always_off;
//Main.common$.diags_ASSERT = Diags.always_off;
//Main.common$.diags_USER1 = Diags.always_off;
//Main.common$.diags_USER2 = Diags.always_off;
//Main.common$.diags_USER3 = Diags.always_off;
//Main.common$.diags_USER4 = Diags.always_off;
//Main.common$.diags_USER5 = Diags.always_off;
//Main.common$.diags_USER6 = Diags.always_off;
Main.common$.diags_INFO = Diags.always_on;
Main.common$.diags_ANALYSIS = Diags.always_on;
Main.common$.diags_STATUS = Diags.always_on;
Main.common$.diags_ENTRY = Diags.always_on;
Main.common$.diags_EXIT = Diags.always_on;
Main.common$.diags_LIFECYCLE = Diags.always_on;
Main.common$.diags_INTERNAL = Diags.always_on;
Main.common$.diags_ASSERT = Diags.always_on;
Main.common$.diags_USER1 = Diags.always_on;
Main.common$.diags_USER2 = Diags.always_on;
Main.common$.diags_USER3 = Diags.always_on;
Main.common$.diags_USER4 = Diags.always_on;
Main.common$.diags_USER5 = Diags.always_on;
Main.common$.diags_USER6 = Diags.always_on;
和
//Defaults.common$.diags_INFO = Diags.always_off;
//Defaults.common$.diags_ANALYSIS = Diags.always_off;
//Defaults.common$.diags_STATUS = Diags.always_off;
//Defaults.common$.diags_ENTRY = Diags.always_off;
//Defaults.common$.diags_EXIT = Diags.always_off;
//Defaults.common$.diags_LIFECYCLE = Diags.always_off;
//Defaults.common$.diags_INTERNAL = Diags.always_off;
//Defaults.common$.diags_ASSERT = Diags.always_off;
//Defaults.common$.diags_USER1 = Diags.always_off;
//Defaults.common$.diags_USER2 = Diags.always_off;
//Defaults.common$.diags_USER3 = Diags.always_off;
//Defaults.common$.diags_USER4 = Diags.always_off;
//Defaults.common$.diags_USER5 = Diags.always_off;
//Defaults.common$.diags_USER6 = Diags.always_off;
Defaults.common$.diags_INFO = Diags.always_on;
Defaults.common$.diags_ANALYSIS = Diags.always_on;
Defaults.common$.diags_STATUS = Diags.always_on;
Defaults.common$.diags_ENTRY = Diags.always_on;
Defaults.common$.diags_EXIT = Diags.always_on;
Defaults.common$.diags_LIFECYCLE = Diags.always_on;
Defaults.common$.diags_INTERNAL = Diags.always_on;
Defaults.common$.diags_ASSERT = Diags.always_on;
Defaults.common$.diags_USER1 = Diags.always_on;
Defaults.common$.diags_USER2 = Diags.always_on;
Defaults.common$.diags_USER3 = Diags.always_on;
Defaults.common$.diags_USER4 = Diags.always_on;
Defaults.common$.diags_USER5 = Diags.always_on;
Defaults.common$.diags_USER6 = Diags.always_on;
我试图控制与诊断相关的开销、因此关闭了除主信息之外的所有内容。 但是、将它们全部打开似乎已经改变了某些东西、所以异常不再发生、我可以看到正在进入和退出 SWI。
Robert
您好、Robert、
我想 Brad 已经成功了。 您能否执行其中一项操作(粗体更改)
void swi_fxn_edma_acq_left (UArg0、UArgarg1)
{
blah blah;
}
bol_t swi_edma_acq_left_notched (int32_t * buffer_rx_ping、int32_t * buffer_TX_ping)
{
Swi_Params swi_params_edma_acq_left;
Swi_funcPtr swifxn;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、&swiFxn、&swi_params_EDMA_ACQ_LEFT);
Swi_params_edma_acq_left.arg0 =(ARG) buffer_rx_ping;
Swi_params_edma_acq_left.arg1 =(ARG) buffer_TX_ping;
Swi_setAttrs (SWI_EDMA_ACQ_LEFT、swifxn、&swi_params_EDMA_ACQ_LEFT);
(笑声)
或者更好地执行以下操作、因为您不会更改函数。
bol_t swi_edma_acq_left_notched (int32_t * buffer_rx_ping、int32_t * buffer_TX_ping)
{
Swi_Params swi_params_edma_acq_left;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、NULL、&swi_params_EDMA_ACQ_LEFT);
Swi_params_edma_acq_left.arg0 =(ARG) buffer_rx_ping;
Swi_params_edma_acq_left.arg1 =(ARG) buffer_TX_ping;
Swi_setAttrs (SWI_EDMA_ACQ_LEFT、 NULL、&swi_params_EDMA_ACQ_LEFT);
(笑声)
此外、我要使 Swi_Params 变量成为局部变量、而不是全局变量。 您的实现目前不是线程安全的。 多个线程可以调用此函数吗? 如果是这样、较高优先级的线程可能会在全局变量更新的中间优先于较低优先级、并且可能会发生混乱。 您现在可能没有遇到问题、但它相当微妙、如果设计在未来发生变化、那么这可能是一个问题。
我认为更改诊断设置只是移动内存、使其不会成为灾难性的。 如果进行上述更改、您能否使用诊断设置验证该假设?
Todd
[引用 user="ToddMullanix"]
此外、我要使 Swi_Params 变量成为局部变量、而不是全局变量。
[/报价]
我没有这样做的原因是、在您展示的实现中、参数永远不会初始化。 在任何 Swi 运行之前、我有一个初始化过程、这个过程经过这些全局 Swi_Params_init ()、所以它们在所有启动前处于某种已知状态。 重要、不是吗? 我想我可以在 Swi_post 之前执行每个初始化、以及我的相关参数 args 更新。 这肯定值得让事情变得更线程安全。
Robert
[引用 user="ToddMullanix"]
bol_t swi_edma_acq_left_notched (int32_t * buffer_rx_ping、int32_t * buffer_TX_ping)
{
Swi_Params swi_params_edma_acq_left;
Swi_funcPtr swifxn;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、&swiFxn、&swi_params_EDMA_ACQ_LEFT);
Swi_params_edma_acq_left.arg0 =(ARG) buffer_rx_ping;
Swi_params_edma_acq_left.arg1 =(ARG) buffer_TX_ping;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、swifxn、&swi_params_EDMA_ACQ_LEFT);
(笑声)
或者更好地执行以下操作、因为您不会更改函数。
bol_t swi_edma_acq_left_notched (int32_t * buffer_rx_ping、int32_t * buffer_TX_ping)
{
Swi_Params swi_params_edma_acq_left;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、NULL、&swi_params_EDMA_ACQ_LEFT);
Swi_params_edma_acq_left.arg0 =(ARG) buffer_rx_ping;
Swi_params_edma_acq_left.arg1 =(ARG) buffer_TX_ping;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、 NULL、&swi_params_EDMA_ACQ_LEFT);
[/报价]
在这些示例中,Swi_post ()如何知道要调用哪个函数? 还是因为该函数已经通过配置文件设置连接到 Swi 句柄? 我想我想知道为什么在 API 中甚至需要函数指针、但可能是我要忽略的东西/用例。
谢谢、
Robert
param_init 上的好点。 Swi_getAttrs API 当前 将在提供的参数结构中设置以下字段:arg0、arg1、优先级和触发器。 Swi_setAttrs API 目前只设置完全相同的字段。 但是、我们不会记录这种情况、因此未来可能会发生变化。 因此、为了安全起见、调用 Swi_Params_init。 就是这样
bol_t swi_edma_acq_left_notched (int32_t * buffer_rx_ping、int32_t * buffer_TX_ping)
{
Swi_Params swi_params_edma_acq_left;
Swi_Params_init (&swi_params_edma_acq_left);
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、 NULL、&swi_params_EDMA_ACQ_LEFT);
Swi_params_edma_acq_left.arg0 =(ARG) buffer_rx_ping;
Swi_params_edma_acq_left.arg1 =(ARG) buffer_TX_ping;
Swi_setAttrs (SWI_EDMA_ACQ_LEFT、 NULL、&swi_params_EDMA_ACQ_LEFT);
(笑声)
供参考...您的临时"艺术作品"评论让我感到很高兴!
Todd
[引用 user="ToddMullanix"]
param_init 上的好点。 Swi_getAttrs API 当前 将在提供的参数结构中设置以下字段:arg0、arg1、优先级和触发器。 Swi_setAttrs API 目前只设置完全相同的字段。 但是、我们不会记录这种情况、因此未来可能会发生变化。 因此、为了安全起见、调用 Swi_Params_init。 就是这样
bol_t swi_edma_acq_left_notched (int32_t * buffer_rx_ping、int32_t * buffer_TX_ping)
{
Swi_Params swi_params_edma_acq_left;
Swi_Params_init (&swi_params_edma_acq_left);
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、 NULL、&swi_params_EDMA_ACQ_LEFT);
Swi_params_edma_acq_left.arg0 =(ARG) buffer_rx_ping;
Swi_params_edma_acq_left.arg1 =(ARG) buffer_TX_ping;
Swi_setAttrs (SWI_EDMA_ACQ_LEFT、 NULL、&swi_params_EDMA_ACQ_LEFT);
(笑声)
[/报价]
好的、可以了。 我实际上在我的一些其他应用程序中添加了 Swi (在全局变量上具有类似的 get/set Attrs)、并再次开始获取异常。 因此、我将仔细检查并相应地更改它们、看看异常是否消失。
[引用 user="ToddMullanix"]
供参考...您的临时"艺术作品"评论让我感到很高兴!
Todd
编辑按钮-适合整理帖子,或在事实之后删除多余的注释 :)
[引用 user="Brad Griffies">我很清楚--诊断与这一点无关吗? 为了回答你之前的问题、由于 Swi_post 而运行的函数在构建时被配置为你的 cfg 文件的一部分。 这就是为什么我建议只为该关联参数使用 NULL 并将其保留为单独的原因。 这就是您用于解决方案的原因吗? 或者、您是否按照 Todd 建议的方式执行了该操作?
[/报价]
抱歉、我刚刚意识到我错过了您之前的回答、建议为 NULL。 好的、是的、它是配置链接。
我从这些页面获取提示、其中指示两个 Attr 调用中都需要该函数、首先是 getAttrs 中的指针:
并且没有 setAttrs 的指针:
除非我忽略某些内容、否则其他人引用这些在线 API 可能会因为同样的事情而被触发?
诊断结果与它无关。 在进行这些最终更改后、我将所有内容都放回、以便在默认设置中关闭断言、但仍然没有例外。
这是我执行的最后一个实现、这是 Todd 最后建议的、包括你指出的 NULL;加上更新以包含参数初始化
Swi_Params t_swi_params;
Swi_Params_init (&t_swi_params);
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、NULL、&t_swi_params);
t_swi_params.arg0 =(ARG) buffer_rx_ping;
t_swi_params.arg1 =(ARG) buffer_TX_ping;
Swi_setAttrs (swi_edma_acq_left、NULL、&t_swi_params);
Swi_post (swi_edma_acq_left);
谢谢、
Robert
[quote user="Brad Griffies">感谢您确认诊断不相关。 这让我有点困惑、所以现在这是有道理的。
文档正确。 这就是我用来诊断您的问题的方法。 Swi_getAttrs 的第二个参数应该是 Swi_FuncPtr*类型。 换句话说、它是指向 Swi_FuncPtr 类型的指针。 您需要执行 Todd 所示的操作:
Swi_funcPtr swifxn;
Swi_getAttrs (SWI_EDMA_ACQ_LEFT、&swiFxn、&swi_params_EDMA_ACQ_LEFT);
我想编译器试图向您发出警告、但 getAttrs 调用中存在错误转换。 另一种解决方案(也在文档中注明)是为那些完全避免了该问题的参数传递 NULL。
Brad
[/报价]
说实话、这对我来说似乎毫无意义。 在该上下文中、swifxn 是一些本地函数声明、与任何内容都无关。 在读取它时、我会看到它正在请求一个 Swi_func、我已经声明了这个 Swi 句柄/与它相关联、而这个 Swi 句柄是要放置在这里的那个。 我不能想象我是唯一这样阅读的人(但可能是谁知道)。 通过回顾 DSP-BIOS 实现、attr 调用确实采用了实际的 SWI 函数调用(除非我在那里执行的操作也不正确、并且它恰好能正常工作)、从而进一步导致了这种误解。
Robert
[引用用户="Brad Griffies"]
我想编译器试图向您发出警告、但 getAttrs 调用中存在错误转换。
[/报价]
Robert