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.

[参考译文] LAUNCHXL-F28027:循环列表地址在迭代后中断

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/589213/launchxl-f28027-circular-list-address-breaks-after-an-iteration

器件型号:LAUNCHXL-F28027

您好!

我在头文件中定义了一个结构、如下所示:

typedef struct CommutationStep
{
uint16_t index;
uint16_t hall_val;
struct Commutstep * nutstep;
struct CommutStep * prev_step;
}Commutstep; 


在包含 main()的文件中,我有一个其他结构:

typedef struct MotorInfo
{
CommutationStep * comm_table;
uint16_t hall_raw; 
uint16_t prev_hall;
bool 被去除回弹; //其他未使用的字段 } MotorInfo;

在主代码中、我初始化名为"motor"的 MotorInfo 结构 。 *comm_table 还正确指向6元素循环数组的第一个元素。 (调试器已验证、到目前为止循环列表还不错)

接下来、我的主函数有无限循环:

while (1)
{
如果(!motor.debounced)
{
SET_SAVE_STEP (MOTOR.HALL_RAW);
}

Motor.HALL_RAW = get_HALL_val ();
去抖霍尔(&motor);
} 

和去抖霍尔函数:

void debounce_hall (MotorInfo *电机)
{
//检查如果
(debounce_level < 1 || debounce_level > 5)//(此处有错误)
{
电机->debounced = false;
返回
;}

如果(去抖电平= 1)
{
IF (MOTOR->HALL_RAW!= MOTOR->PRV_HALL)
{
//将 comm_table 指向与原始霍尔 val 匹配的步骤
while (motion->comm_table->next step->hall_val!= motion->hall_raw)
{
电机->comm_table =电机->comm_table->next _step;
}
电机->comm_table =电机->comm_table->next _step;
MOTOR->prev_hall = MOTOR->HALL_RAW;
电机->debounced = false;
}
其他
{
电机->debounced = true;
}
return;
}
else
{
//其他代码,不感兴趣
}
} 

现在我的问题是:COMM_TABLE 指向六个地址中的一个0x00000410-420-430-450-460。 MotorInfo 电机地址为0x00000404。 我逐步手动调试、每次都将 HALL_RAW 设置为下一步。 当 comm_table 指向第六步时、地址正确为0x00000460、next _step 为410、之前的450。 检查调试器上的 NEW_STEP、它仍然正确地指向下一个和 PRV 地址。 现在、我处于第二次旋转的开始位置、我正确设置 HALL_RAW 以匹配第一步。 调用 debounce_hall (&motor)、并且仍然每个单个地址指向预期的步骤。 在函数的第1行(此处为注释//错误)、地址0x00000410处的结构(第一步)突然得到修改的字段:NEW_STEP 现在不是指向0x00000420而是指向0x00000404。 (电机结构地址)。  

这可能是什么原因?
提前感谢您!

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

    那么,你是否说,如果你在对 debounce_hall()的调用中放置一个断点,一切看起来都很好,但是一旦你进入 debounce_hall()(在第二次旋转时),你就会看到发生了变化?

    我认为我们的默认 cmd 文件将堆栈放置在0x400。 你移动了吗?

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

    我使用的默认 cmd 文件(RAM +非 BIOS 头文件)未更改。

    在评估该行时、地址实际上会发生变化:

    如果(去抖电平< 1 ||去抖电平> 5) 

    更新了:我进行了编辑、自行分配 MOTOR.HALL_RAW 值以模拟工作条件、现在调用 debounce_hall 时 motor.comm_table 地址会中断

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否使用 #pragma 将结构放置在特定位置或其他某种方法? 在我看来、如果堆栈位于0x400、结构位于0x404-0x460、那么它们最终将相互覆盖...?

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

    不、我不在特定位置编写它们、我必须这样做吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不、您不必这么做。 我只是想知道它们最终是如何在一个应该为堆栈保留的位置-就我所能说的那样。

    您如何声明各种结构? 您如何初始化其中的指针? 如果您不介意分享更多相关代码、这可能会帮助我找出问题所在。

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

    在主文件中:

    int main (void)
    {
    MotorInfo Motor ={NULL、// comm_table
    0、 // HALL_RAW
    0、 // prev_hall
    false、//被消抖
    };
    motor.comm_table = comm_clist_init();
    ...
    } 

    在其他文件中:

    CommutationStep * comm_clist_init (void)
    {
    // TODO:malloc (* cs)不起作用,请检查
    CommutationStep cs ={0、 //索引
    HALL_Vals[0]、 // HALL_val
    null、 //*下一步
    null //* prev_step
    };
    CommutationStep * CSP =&C;
    cs.next 步骤= create_comm_step (1、CSP、CSP);
    返回 CSP;
    }
    
    CommutStep * create_comm_step (uint16_t step、CommutStep *头部、
    CommutationStep * prev)
    {
    CommutationStep cs ={step、 //索引
    HALL_Vals[STEP]、// HALL_val
    null、 //*下一步
    上一个 //* prev_step
    };
    CommutationStep * CSP =&C;
    
    if (step =(CBIST_LEN - 1))//如果是最后一个霍尔步骤,下一步是 HEAD
    {
    cs.next =头;
    head->prev_step = CSP;
    }
    否则
    {
    cs.next _step = create_comm_step (++step、head、CSP);
    }
    
    返回 CSP;
    } 

    我尝试像这样进行初始化:

    CommutationStep *CSP;
    if ((csp=malloc (sizeof (*csp))!= NULL)
    {
    //此处初始化逻辑
    }
    

    但失败的原因是内存不足。

    如果您需要其他信息、请告诉我!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、我认为这解释了奇怪的行为。 在 comm_clist_init()中,您将创建一个局部变量 cs (存储在栈上),对其进行初始化,并返回一个指向它的指针。 但是、当函数返回时、存储该局部变量的存储器在用于其他函数的栈时可以自由覆盖。

    您需要确保已在返回到 main()时仍然可用的位置创建了 CommutationStep 对象。 malloc()会起作用,因为这会将它放置在堆上。 如果所需的对象数已知(是否只需要6个?),则可以在 main()或全局声明它们,具体取决于所需的范围。

    如果您想使用 malloc(),请告诉我您遇到了什么错误,我们将看到我们是否可以解决这些错误。

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

    谢谢、这是一个大开眼界的地方! 我可能会在 main()中声明它们,因为它们的编号是已知的,我不希望使用大量的栈内存,但我也希望对 malloc()问题进行排序。

    这是我得到的错误:

    http://processors.wiki.ti.com/index.php/Compiler/diagnostic_messages/10099 -程序不能放入可用内存中。 对于".stack"大小为0x300的第1页、运行对齐/分块放置失败。 可用内存范围:28027_RAM_lnk.cmd /orca-ECU 线路149 C/C++ Problem

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

    要解决该问题、您需要对堆栈和堆的大小进行一些调整(Project > Properties > C2000 Linker > Basic Options)、或更改.cmd 文件以为这些段分配更多空间。 或两者兼而有之。 默认情况下、链接器使用的堆大小为0x400。 这是整个 RAMM1、应根据默认的.cmd 文件与其他几个段共享-因此出现错误。

    如果您想尝试编辑.cmd :processors.wiki.ti.com/.../C28x_Compiler_-_Understanding_Linking、我们有一个有关链接主题的 wiki 页面

    惠特尼

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