реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Reentrant функция, Keil, RTX
toweroff
сообщение Dec 20 2012, 10:14
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Добрый день!

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

Идея-то давно витала - сделать одну reentrant функцию, в которую в качестве параметра будет валиться только OS_TID, из которой ее вызвали. Но как это грамотно сделать - пока не разбирался, да и смущает еще такой момент. В этой функции активно используются ожидания таймаута или событий. Как эти функции RTX будут вести себя в reentrant-функциях?
Вообще Keil RTX поддерживает такие вещи?

UPD
С кейлом вроде как порядок. (тыц)

Теперь остается узнать, как правильно писать reentrant функции? sm.gif
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Dec 21 2012, 04:06
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



1. Не используйте статические, глобальные и иные переменные, которые могут повлиять на выполнение кода в другом потоке
2. Локальные переменные д.б. размещены в стеке (выполняется почти всегда по умолчанию)
3. Функция не должна возвращать к-либо глобальные указатели/объекты
4. И вообще, в функцию необходимо передавать только указатель на объект/структуру с данным объектом, в котором должны быть все данные, необходимые для работы, и там же необходимо сохранять все результаты работы функции над данным объектом
5. Если используете объекты синхронизации (мьютексы, семафоры и т.д.) - то необходимо детально проработать их использование - иначе деадлок

Как-то так, если своими словами.

Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Dec 21 2012, 08:13
Сообщение #3


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(alexeyv @ Dec 21 2012, 06:06) *
1. Не используйте статические, глобальные и иные переменные, которые могут повлиять на выполнение кода в другом потоке
2. Локальные переменные д.б. размещены в стеке (выполняется почти всегда по умолчанию)
3. Функция не должна возвращать к-либо глобальные указатели/объекты
4. И вообще, в функцию необходимо передавать только указатель на объект/структуру с данным объектом, в котором должны быть все данные, необходимые для работы, и там же необходимо сохранять все результаты работы функции над данным объектом
5. Если используете объекты синхронизации (мьютексы, семафоры и т.д.) - то необходимо детально проработать их использование - иначе деадлок

Как-то так, если своими словами.


Вы здесь описали какое-то чудо, но не реентерабельные функции.
Можно в эти функции и глобальные переменные передавать, можно и глобальные переменные возвращать.
Зато внутри них не должно быть статических переменных.
Обращение к глобальным переменным просто надо защитить.
А вот уже чем защитить есть некоторый нюанс.
Простой запретить прерываний будет плохо отражаться на риалтайме.
Если использовать семафоры, то если функция работает под разными задачами и над разными глобальными переменными, то и семафоры должны быть разные.
И тогда функции надо передать эти семафоры.
Я делаю так. Я семафоры включаю в структуру задачи. Функции же всегда могут определить идентификатор задачи в которой они выполняются. И по этому идентификатору найти свои семафоры. Тоже относится и к очередям и к мьютексам и проч.
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 21 2012, 08:26
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(AlexandrY @ Dec 21 2012, 12:13) *
Зато внутри них не должно быть статических переменных.


Это еще с какого перепуга? Просто их тоже надо защитить как и глобальные, если, конечно, они сами не "средство защиты" (например семафор доступа к ресурсу, с которым работает ф-ция).
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Dec 21 2012, 09:13
Сообщение #5


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(SM @ Dec 21 2012, 10:26) *
Это еще с какого перепуга? Просто их тоже надо защитить как и глобальные, если, конечно, они сами не "средство защиты" (например семафор доступа к ресурсу, с которым работает ф-ция).


Т.е. защитить!? Какой тогда в них смысл?
Как у одной и той же функции выполняющейся в разных задачах будет свой экземпляр статической переменной, т.е. такой которая сохраняется не в стеке?
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 21 2012, 10:29
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(AlexandrY @ Dec 21 2012, 13:13) *
Как у одной и той же функции выполняющейся в разных задачах будет свой экземпляр статической переменной, т.е. такой которая сохраняется не в стеке?


Зачем свой? В том и суть, что он, экземпляр такой переменной, один для всех задач. Допустим функция работает с неким аппаратным ресурсом, осуществляя полное им управление, а другие функции с ним не работают. Функция захватывает владение ресурсом, используя семафор, (как вариант - находящийся в статической переменной внутри ф-ции, так как в принципе он никому кроме этой ф-ции не нужен), и затем может свободно распоряжаться остальными статическими переменными, связанными с работой с этим ресурсом, после чего освобождает семафор. Глобальная видимость этим переменным совершенно не нужна, раз кроме как в этой ф-ции, они нигде не используются, поэтому использование статических переменных, определенных внутри ф-ции, будет одним из оптимальных решений, и при этом с реентерабельностью (они защищены вместе с аппататным ресурсом семафором). И, заодно, будет защита от случайных ошибок, если по неосторожности будет написан код, обращающийся к этим переменным откуда то не оттуда.

Или, самый элементарный пример - нужно знать, какой это экземпляр по счету из одновременно запущенных функций - статическая переменная, интерлокед инкремент при входе в ф-цию, и такой же декремент при выходе. И этому данному тоже не надо иметь видимость где либо вне ф-ции.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Dec 21 2012, 11:30
Сообщение #7


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(SM @ Dec 21 2012, 12:29) *
Или, самый элементарный пример - нужно знать, какой это экземпляр по счету из одновременно запущенных функций - статическая переменная, интерлокед инкремент при входе в ф-цию, и такой же декремент при выходе. И этому данному тоже не надо иметь видимость где либо вне ф-ции.


Мда, в принципе возразить трудно.
Но тогда не остается ни одного формального отличительно признака реентерабельной функции! wacko.gif biggrin.gif
Все зависит от контекста?

Go to the top of the page
 
+Quote Post
toweroff
сообщение Dec 21 2012, 11:42
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(AlexandrY @ Dec 21 2012, 15:30) *
Все зависит от контекста?

я вот тоже к этому склоняюсь sm.gif
если сферический конь, то таки да, статические переменные в подобных функциях неприемлемы. А вот если их использование (да вообще использование всего) четко оговорено, то почему бы и нет?
У меня пяток локальных переменных, да вызовы (помимо функций RTX) пары моих функций, у которых также только локали и в качестве параметра - канал SSP (SSP0 или SSP1) и пяток байт, так что копии друг другу не помешают
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 21 2012, 12:42
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(AlexandrY @ Dec 21 2012, 15:30) *
Но тогда не остается ни одного формального отличительно признака реентерабельной функции! wacko.gif biggrin.gif
Все зависит от контекста?


Формального и нету. Она лишь должна корректно работать при одновременном вызове из некоторых различных тредов/процессов/прерываний/т.п., а как это реализовано - хоть данные на стеке, хоть в десяти разных местах с выбором указателя на место в зависимости от ID треда (или например текущей глубины вложения вызова), хоть еще как - это лишь от удобства реализации и фантазии программиста зависит.



Кстати, автору... А какой процессор то? Кейл кейлом, а вот если речь о 51 например - то там придется десять раз подумать, так как локальные переменные там не в стеке, и придется делать свою реализацию раздельных мест хранения локальных данных.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Dec 22 2012, 07:58
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(SM @ Dec 21 2012, 16:42) *
Кстати, автору... А какой процессор то? Кейл кейлом, а вот если речь о 51 например - то там придется десять раз подумать, так как локальные переменные там не в стеке, и придется делать свою реализацию раздельных мест хранения локальных данных.

и то правда, забыл... CortexM3
с Cx51 проще, там было такое
Код
void func(void) reentrant
{
}

почему убрали из CARM - не понять локомотива прогресса
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 22 2012, 14:04
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(toweroff @ Dec 22 2012, 11:58) *
почему убрали из CARM - не понять локомотива прогресса


потому что там все на стеке, а стека завались. Не актуально, оно всегда "reentrant" c тем ABI, что там. Нереентерабельность можно разве что самому написать при неосторожным обращении с глобальными и статическими ресурсами/переменными
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.01431 секунд с 7
ELECTRONIX ©2004-2016