Перейти к содержанию
    

Псевдомногозадачность в IAR

Уважаемые!

Кто знает, как в IAR EWAVR грамотно реализовать следующий сценарий->

1. После сброса контроллера пользователь выбирает из предложенного списка одну из задач на выполнение.

2. Выхода из выбранной задачи обратно или в другую задачу нет.

3. Задача забирает ВСЕ ресурсы контроллера.

 

Собственно, вопрос в том, как объяснить линкеру, что разные задачи размещают свои переменные по совпадающим/пересекающимся адресам в RAM, как если бы других задач не существовало?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Легко. 1+N прошивок: первая (загрузчик) - это выбор задачи, а остальные - собственно сами задачи. Яр тут ни при чём - это везде так делается. Надо распределить прошивки по памяти и проработать механизм перехода их загрузчика в задачу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно, вопрос в том, как объяснить линкеру, что разные задачи размещают свои переменные по совпадающим/пересекающимся адресам в RAM, как если бы других задач не существовало?

Не пользуйтесь статическими переменными и ничего объяснять не придётся.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Легко. 1+N прошивок: первая (загрузчик) - это выбор задачи, а остальные - собственно сами задачи. Яр тут ни при чём - это везде так делается. Надо распределить прошивки по памяти и проработать механизм перехода их загрузчика в задачу.

Это получается нерациональное расходование flash-памяти. А как быть, если эти задачи должны использовать общую библиотеку или функции друг из друга? Вообще, больше волнует вопрос общего использования ОЗУ.

 

Не пользуйтесь статическими переменными и ничего объяснять не придётся.

Если переменная не статическая, она просто не видна в другой задаче или вроде того, но место в ОЗУ занимает всё равно. А нужно, чтобы каждая задача владела ОЗУ полностью. Т.е., как я понимаю, начальный адрес размещения переменных в ОЗУ для всех задач должен быть одинаковый.

 

Легко. 1+N прошивок: первая (загрузчик) - это выбор задачи, а остальные - собственно сами задачи. Яр тут ни при чём - это везде так делается. Надо распределить прошивки по памяти и проработать механизм перехода их загрузчика в задачу.

Потом, в случае доработки, опять же собирать по частям сложно, по-моему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как быть, если эти задачи должны использовать общую библиотеку или функции друг из друга?

Если переменная не статическая, она просто не видна в другой задаче или вроде того, но место в ОЗУ занимает всё равно.

Сами себе противоречите: то задачи изолированные, то вызывают код друг из друга.

Если переменная не статическая и не глобальная - она лежит в стеке задачи вплоть до завершения задачи. Если задача не вызывается, переменная никогда не попадет в стек, соответственно памяти не займет.

 

Про загрузчик вам правильно все рассказали.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну а кто вам мешает сделать чтото типа среды.

Среда общая - низкоуровневые функции, таймеры, ввод-вывод, буферы прийома передачи.

А конкретные задачи реализовывать по древовидному принципу. Из общей среды выбираются по какому то триггеру задача, в которой уже используются только локальные переменные/стэк.

Вроде как всё тривиально :) Поставить джампер - по нему разделить на 2 задачи. Два джампера - на четыре задачи. Три джампера....)))))))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если переменная не статическая, она просто не видна в другой задаче или вроде того, но место в ОЗУ занимает всё равно. А нужно, чтобы каждая задача владела ОЗУ полностью.

Если переменная не статическая(не глобальная), то память для нее выделяет компилятор исключительно на время работы использующего ее кода. В остальное время эту-же память/регистры компилятор использует для других не статических переменных. Аналогично с динамически выделяемой памятью из кучи - пока не выполнится malloc (или аналогичное) она физически не распределена и ее место может быть использовано на что угодно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если переменная не статическая(не глобальная), то память для нее выделяет компилятор исключительно на время работы использующего ее кода. В остальное время эту-же память/регистры компилятор использует для других не статических переменных. Аналогично с динамически выделяемой памятью из кучи - пока не выполнится malloc (или аналогичное) она физически не распределена и ее место может быть использовано на что угодно.

Как я понимаю, переменные, о которых вы говорите, объявляются внутри использующих их функции. Т.е.

void procedure task_number_0(void)
{
    unsigned char a,b,c;
    unsigned char d[1000];
    ...
}

Правильно?

В этом случае место для них выделяется во временной области, доступ к которой происходит не по абсолютным адресам, а по ссылке. Но, по-моему, в этом случае, если переменных много и не удаётся эффективно разместить их по регистрам, резко возрастает размер и время выполнения кода. Кроме того, не получается сослаться на эти переменные в процедурах, написанных на ассемблере.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правильно?

В этом случае место для них выделяется во временной области, доступ к которой происходит не по абсолютным адресам, а по ссылке. Но, по-моему, в этом случае, если переменных много и не удаётся эффективно разместить их по регистрам, резко возрастает размер и время выполнения кода.

Правильно. Вот только всё с точностью до наоборот. Такие переменные компилятор размещает обычно с наибольшей эффективностью. Вплоть до оптимального размещения в регистрах(выкинув оттуда временно не нужные значения в стек) если так быстрее/меньше код. И естественно работа как с обычной памятью, а не по ссылкам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще, больше волнует вопрос общего использования ОЗУ.
man union

вообще то что вы описали, на многозадачность никак не тянет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не пользуйтесь статическими переменными и ничего объяснять не придётся.

Интересно только как тогда взаимодействовать с ISR-ами? Или как быть если в задачах нужно использовать ОС?

А вообще - вроде в IAR-е можно объявить секции, занимающие общее место в памяти. Точно не помню ключевых слов. Смотреть нужно мануал на линкер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

больше волнует вопрос общего использования ОЗУ

если только ОЗУ может быть так?

uint8_t var;
#define var1 var
#define var2 var

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотя такая задача уже отпала, но кое-что я всё-таки нашёл для такого случая в "IAR Linker and Library Tools Reference Guide".

Директива линкера, которая позволяет перекрывать сегменты данных, и вместо "Error" линкер пишет "Warning".

 

-z

Syntax -z[a][o][p]

Parameters

Description Use this option to reduce segment overlap errors to warnings, making it possible to

produce cross-reference maps, etc.

-za suppresses overlap errors between absolute entries. This is useful if you, for

example, have several absolutely placed variables on the same address. Note that -za

only ignores overlaps where both entries are absolutely placed.

All overlaps are reported by default. You can specify -zb and -zs to ignore overlaps to

the bit and SFR area respectively.

For the 8051 processor, only overlaps that do not involve bit segments or SFRs are

reported. You can specify -zo and -zp to report overlaps.

Using the -zs option requires that the used processor has a dedicated SFR area that

XLINK has been made aware of. The only processor that has a dedicated SFR area for

these purposes is the 8051. Using the -zs option for any other processor will generate

warning 68 but otherwise have no effect.

Use -zb to suppress error 24 (segment overlap) for segment overlaps where at least one

of the involved segments is a bit segment.

This option is identical to the Segment overlap warnings option in the linker category

in the IAR Embedded Workbench IDE.

 

По-моему мнению, в использовании статических/глобальных переменных нет ничего страшного. Доступ к ним прост и быстр: LDS, STS, LD, ST. Лично у меня, только небольшое количество переменных, используемых в процедурах, локальные, чтобы не перегружать стек.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...