【问题标题】:FreeRTOS task stack overflow issueFreeRTOS 任务堆栈溢出问题
【发布时间】:2017-05-02 16:28:42
【问题描述】:

我正在使用 microblaze 的 freertos 端口,并且我有一些简单的代码可以在任务中闪烁灯,并且我收到“任务溢出其堆栈调用”。请注意,错误消息实际上并没有打印出任务名称,但考虑到我只有一项任务,我认为那里可能有问题。

我也确实每次收到一个字符时都会触发一个 uart 中断,但这很好用。在我附加的链接器脚本中,我将堆栈和堆大小增加到非常大,但我仍然遇到这个问题。如果我禁用 main_task 我不会得到堆栈溢出,这意味着它可能与任务有关吗?我还应该说它可以正常工作,但是如果我继续在将发出中断的 uart 中按 enter,我最终会收到此错误。

任何帮助都会非常有帮助,因为我已经不知所措了。提前致谢。

void
main_task()
{
   int counter = 0;
   while( 1 )
   {
      if ( (counter++%2) == 0 )
      {
         *(volatile unsigned int*)0x40000000 &= ~0x1;
      }
      else
      {
         *(volatile unsigned int*)0x40000000 |= 0x1;
      }
      vTaskDelay(200);
   }
}

int main()
{
   xTaskCreate( (void(*)(void*)) main_task, "main_task", 4096, NULL, 3, &xCreatedTask );
   vTaskStartScheduler();
}

这是我正在使用的链接器脚本:

STARTUP(crt0.o)
ENTRY(_start)

_STACK_SIZE = 0x4000;
_HEAP_SIZE = 0x4000;

MEMORY
{
   mig_7series_0 : ORIGIN = 0x80000000, LENGTH = 0x10000000
}

SECTIONS
{
.vectors.reset 0x0 : {
   KEEP (*(.vectors.reset))
} 

.vectors.sw_exception 0x8 : {
   KEEP (*(.vectors.sw_exception))
} 

.vectors.interrupt 0x10 : {
   KEEP (*(.vectors.interrupt))
} 

.vectors.hw_exception 0x20 : {
   KEEP (*(.vectors.hw_exception))
} 

.text : {
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t.*)
} > mig_7series_0

.rodata : {
   __rodata_start = .;
   *(.rodata)
   *(.rodata.*)
   *(.gnu.linkonce.r.*)
   __rodata_end = .;
} > mig_7series_0

.sdata2 : {
   . = ALIGN(8);
   __sdata2_start = .;
   *(.sdata2)
   *(.sdata2.*)
   *(.gnu.linkonce.s2.*)
   . = ALIGN(8);
   __sdata2_end = .;
} > mig_7series_0

.sbss2 : {
   __sbss2_start = .;
   *(.sbss2)
   *(.sbss2.*)
   *(.gnu.linkonce.sb2.*)
   __sbss2_end = .;
} > mig_7series_0

.data : {
   . = ALIGN(4);
   __data_start = .;
   *(.data)
   *(.data.*)
   *(.gnu.linkonce.d.*)
   __data_end = .;
} > mig_7series_0

.sdata : {
   . = ALIGN(8);
   __sdata_start = .;
   *(.sdata)
   *(.sdata.*)
   *(.gnu.linkonce.s.*)
   __sdata_end = .;
} > mig_7series_0

.sbss (NOLOAD) : {
   . = ALIGN(4);
   __sbss_start = .;
   *(.sbss)
   *(.sbss.*)
   *(.gnu.linkonce.sb.*)
   . = ALIGN(8);
   __sbss_end = .;
} > mig_7series_0

.tdata : {
   __tdata_start = .;
   *(.tdata)
   *(.tdata.*)
   *(.gnu.linkonce.td.*)
   __tdata_end = .;
} > mig_7series_0

.tbss : {
   __tbss_start = .;
   *(.tbss)
   *(.tbss.*)
   *(.gnu.linkonce.tb.*)
   __tbss_end = .;
} > mig_7series_0

.bss (NOLOAD) : {
   . = ALIGN(4);
   __bss_start = .;
   *(.bss)
   *(.bss.*)
   *(.gnu.linkonce.b.*)
   *(COMMON)
   . = ALIGN(4);
   __bss_end = .;
} > mig_7series_0

_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );

_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );

/* Generate Stack and Heap definitions */

.heap (NOLOAD) : {
   . = ALIGN(8);
   _heap = .;
   _heap_start = .;
   . += _HEAP_SIZE;
   _heap_end = .;
} > mig_7series_0

.stack (NOLOAD) : {
   _stack_end = .;
   . += _STACK_SIZE;
   . = ALIGN(8);
   _stack = .;
   __stack = _stack;
} > mig_7series_0

_end = .;
}

【问题讨论】:

  • 你想通过写地址 (volatile unsigned int)0x40000000 &= ~0x1; 来达到什么目的?

标签: c freertos


【解决方案1】:

您将configCHECK_FOR_STACK_OVERFLOW 设置为1 还是2?如果为 2,则堆栈溢出检查通过检查任务堆栈的末尾来工作,以查看在创建任务时写入那里的模式是否已被覆盖。因此,它实际上可能不是覆盖该内存的任务堆栈,而是其他东西通过覆盖它来破坏该内存。您描述的 uart 中断在重负载(按住键)下的问题可能是中断服务程序中存在问题的线索。

您是否定义了configASSERT()

【讨论】:

  • 是的,它设置为 2。我目前没有使用 configASSERT()。我从中断中删除了所有代码,所以我所做的就是触发中断并发生相同的错误......我在 microblaze 中将 uart 启用为 fast_interrupt。那会有什么不同吗?没有任何意义,因为没有代码所以没有堆栈使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2014-12-03
  • 2010-10-15
  • 1970-01-01
  • 2019-09-23
  • 2019-05-18
  • 1970-01-01
相关资源
最近更新 更多