在FreeRTOS中打印任务的堆栈

时间:2015-06-04 12:48:58

标签: freertos stm32f4discovery

我正在研究STM32F4发现板,我在板上安装了FreeRTOS,并能够运行由main函数创建的两个任务。 现在我希望任务1通过引用或值传递任何变量来访问任务2的局部变量。 我认为打印任务2的堆栈内容然后找到局部变量并在task1中使用它会很好

有人可以指导我吗? 我试图打印每个变量的地址并尝试在task1中使用,但我的程序没有编译并返回-1。

2 个答案:

答案 0 :(得分:1)

我不清楚你想要实现什么,或者你的程序返回-1是什么意思,因为它没有编译,但是一个任务访问另一个任务的堆栈变量是不正常的

每个任务都有自己的堆栈,堆栈对任务是私有的。但是,任务可以通过很多方式相互通信,而无需访问彼此的堆栈。最简单的方法就是使变量成为全局变量,尽管全局变量很少是好事。除此之外,您可以将值从一个任务发送到队列中的任务(http://www.freertos.org/Inter-Task-Communication.html),甚至可以将任务通知用作邮箱(http://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html)。

答案 1 :(得分:1)

首先,警告:你要做的是什么 - 从另一个任务访问一个任务的局部变量 - 可能容易出错。特别是如果在任务A中声明本地并且在任务B访问它之前超出范围。由于堆栈内存可以重用于不同函数中的不同变量,因此任务B可能正在访问其他一些变量。

但我实际上在实践中使用了这种模式 - 具体来说,允许一个任务堆栈 - 为另一个任务提供服务的通信分配缓冲区。 所以我假设你知道你在做什么。 : - )

很难提前计算局部变量的地址。如果您今天派生它,如果您更改代码或编译器版本,它可能会更改。您可能想要做的是在运行时捕获其地址,并以某种方式使其可用于其他任务。然而,这可能很棘手:其他任务可能会在您的任务启动之前尝试使用本地,并且没有任何事情阻止其他任务进入它。

稍微更简洁的方法是通过两个任务通过队列分片为其他任务提供地址。

QueueHandle_t shared_queue;

void common_startup() {
  // This code might go in main, or wherever you initialize things.
  shared_queue = xQueueCreate(1, sizeof(unsigned *));
}    

void task_a() {
  // This task wants to share the address of 'local' with task_b.
  unsigned local;

  // Stuff the address of our local in the queue.  We use a
  // non-blocking send here because the queue will be empty (nobody
  // else puts things in it).  In real code you'd probably do some
  // error checking!
  unsigned * ptr = &local;
  xQueueSend(shared_queue, &ptr, 0);

  while (1) {
    do_stuff();
  }
}

void task_b() {
  // This task wants to use task_a's 'local'.
  // Real code would do error checking!
  unsigned * ptr;
  xQueueReceive(shared_queue, &ptr, portMAX_DELAY);

  while (1) {
    // Just increment the shared variable
    (*ptr)++;
  }
}