печать стека задачи в FreeRTOS

Я работаю над платой обнаружения STM32F4, я установил FreeRTOS на плату и смог запустить две задачи, созданные основной функцией. Теперь я хочу, чтобы задача 1 обращалась к локальным переменным задачи 2 при любой передаче переменной по ссылке или по значению. Я подумал, что было бы хорошо распечатать содержимое стека задачи 2, а затем найти локальные переменные и использовать их в задаче 1.

Может ли кто-нибудь помочь мне с этим? Я пытался напечатать адрес каждой переменной и пытался использовать в задаче1, но моя программа не компилировалась и возвращала -1.


person y11    schedule 04.06.2015    source источник


Ответы (2)


Мне непонятно, чего вы пытаетесь достичь, или что вы имеете в виду, говоря, что программа возвращает -1, потому что она не скомпилировалась, но для одной задачи было бы ненормально обращаться к переменной стека другой задачи.

Каждая задача имеет свой собственный стек, и стек является частным для задачи. Однако существует множество способов, которыми задачи могут взаимодействовать друг с другом без необходимости доступа к стеку друг друга. Самый простой способ — просто сделать переменную глобальной, хотя глобальные переменные редко бывают хорошими. Помимо этого, вы можете отправить значение из одной задачи в другую в очереди (http://www.freertos.org/Inter-Task-Communication.html), или даже используя уведомление о задаче в качестве почтового ящика (http://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html).

person Richard    schedule 05.06.2015
comment
Может ли кто-нибудь сказать мне, как найти значение указателя фрейма для каждой задачи и указателя стека? - person y11; 05.06.2015
comment
Спасибо за ваш ответ. Я хочу, чтобы задача 1 получила доступ к переменным задачи 2, зная стек задачи 2 (я имею в виду адрес всех переменных, pc fp, все эти значения, которые я хочу знать, а затем написать алгоритм, чтобы просто получить доступ к элементам путем вычисления адреса с использованием фп). Я уже использовал глобальные переменные и получил адреса. Моя цель - увидеть, как я могу получить доступ к переменным стека без какого-либо перехода между Task1 и Task2. - person y11; 06.06.2015

Во-первых, предостережение: то, что вы пытаетесь сделать — получить доступ к локальным переменным одной задачи из другой — может быть подвержено ошибкам. В частности, если локальный объект объявлен в Задаче А и выходит за рамки до того, как Задача Б получит к нему доступ. Поскольку память стека может повторно использоваться для разных переменных в разных функциях, задача 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)++;
  }
}
person Cliff L. Biffle    schedule 01.07.2015