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

 
 
7 страниц V  « < 4 5 6 7 >  
Reply to this topicStart new topic
> Несколько вопросов начинающего
msalov
сообщение May 30 2014, 05:35
Сообщение #76


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(MiklPolikov @ May 27 2014, 16:11) *
Коллеги, ещё один вопрос :

Верно ли я понимаю, что значение, которое возвращает xTaskGetTickCount(); периодически сбрасывается в 0 и начинает расти заново, т.к. переполняется 32х разрядная переменная, которая считает тики , и стало быть, при использовании xTaskGetTickCount(); я должен обрабатывать этот сброс в 0 ?
А все функции операционки которые работают со временем (задержка, взять симофор и т.п. ) , то же обрабатывают сброс счётчика тиков в 0 ?

МП


Если ваша задержка меньше разрядности счётчика, то 0 обрабатывать не нужно. Но если больше - обязательно (или разбивать на части).

Пример: пусть счётчик 16-битный. Начальное значение 2, а задержка - 70000 (0x11170). Если взять просто сумму получим 0x11172, из-за переполнения получим в итоге 0x1172, что даст реальную задержку 4464 вместо 70000. Если промахнуться с разрядностью переменной, с которой будет сравниваться счётчик - можно никогда не выйти из цикла ожидания.
Go to the top of the page
 
+Quote Post
juvf
сообщение May 30 2014, 05:59
Сообщение #77


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(MiklPolikov @ May 30 2014, 14:23) *
У меня вот это работает, только если возвращаемая переменная static . А если нет, то функция возвращает 0. Как я понимаю, это потому что существование переменной прекращаеся чуть раньше чем программа вышла из функции, и возвращать оказывается нечего.

Код
char do_something(void)
{
       chatic char result;

        //.................
  
       return result;
}

нет, не так работает си/с++. если резалт не статик, то при покидании функции переменная резалт удалится из стека, но её значение не потеряется а нормально вернётся. может у вас в одной задаче резальт считается и равен 0, в другой задаче резалт неравен нулю. в итоге, когда статик, то оба резалта не равны нулю, а одному значению. а когда не статик, то один экземпляр равен нулю. ..... вобщем это гадание на кофейной гуще. что то не так у вас. попробуйте запустить только одну задачу и проверит статик и нестатик - результат должен быть одинаковый, потом 1-ую задачу выкл, и включить вторую - проверить.....
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение May 30 2014, 06:43
Сообщение #78


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(juvf @ May 30 2014, 14:09) *
нет, не так работает си/с++. если резалт не статик, то при покидании функции переменная резалт удалится из стека, но её значение не потеряется а нормально вернётся. может у вас в одной задаче резальт считается и равен 0, в другой задаче резалт неравен нулю. в итоге, когда статик, то оба резалта не равны нулю, а одному значению. а когда не статик, то один экземпляр равен нулю. ..... вобщем это гадание на кофейной гуще. что то не так у вас. попробуйте запустить только одну задачу и проверит статик и нестатик - результат должен быть одинаковый, потом 1-ую задачу выкл, и включить вторую - проверить.....


Я даже без ОС в самом простом линейном коде наблюдаю что функция возвращает только 0 если локальная переменная в ней не static.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
Lagman
сообщение May 30 2014, 07:18
Сообщение #79


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(MiklPolikov @ May 30 2014, 14:53) *
Я даже без ОС в самом простом линейном коде наблюдаю что функция возвращает только 0 если локальная переменная в ней не static.

http://electronix.ru/forum/index.php?showt...t&p=1259306
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение May 30 2014, 12:01
Сообщение #80


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(Lagman @ May 30 2014, 13:29) *
эта функция или прототип функции объявлен до вызова?


Это функция.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
Lagman
сообщение May 31 2014, 06:21
Сообщение #81


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



%)
Я знаю что это функция.
Go to the top of the page
 
+Quote Post
juvf
сообщение May 31 2014, 06:38
Сообщение #82


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(MiklPolikov @ May 30 2014, 16:53) *
Я даже без ОС в самом простом линейном коде наблюдаю что функция возвращает только 0 если локальная переменная в ней не static.

даже не чего подсказат. си/с++ не так работает. отправлять вас читать книжки "Учимся писать на СИ" как-то неприлично. может компилятор кривой, может вы что-то путаете.

Как же вообще у вас FreeRTOS работает? например функция создания задач

Код
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )
{
signed  xReturn;
...
return  xReturn;
}
ни каких статиков. и др функции возвращающие не void без всяких статиков.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 31 2014, 08:25
Сообщение #83


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MiklPolikov @ May 30 2014, 14:23) *
У меня вот это работает, только если возвращаемая переменная static . А если нет, то функция возвращает 0. Как я понимаю, это потому что существование переменной прекращаеся чуть раньше чем программа вышла из функции, и возвращать оказывается нечего.
Код
char do_something(void)
{
       chatic char result;

        //.................
  
       return result;
}

Так не бывает. Тем более с переменной типа char. Она помещается в регистр, поэтому не может прекратить своё существование.
Попробуйте убрать статик и назначить переменной какое-то значение по умолчанию, типа
Код
char do_something(void)
{
       char result = 123;

        //.................
  
       return result;
}

И посмотрите, что получится. Если функция будет возвращать 123, значит вы просто забыли присвоить значение переменной result:)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jun 8 2014, 09:16
Сообщение #84


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(AHTOXA @ May 31 2014, 16:35) *
Так не бывает. Тем более с переменной типа char. Она помещается в регистр, поэтому не может прекратить своё существование.


Спасибо. Моя проблема скорее всего была связана с изменением переменных в прерывании, директива static иногда работала как volatile.



--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jul 12 2014, 00:58
Сообщение #85


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Коллеги, доброго времени суток.

Не могу до конца понять как работают программные таймеры.
Что такое "очередь таймера" и в каких случаях она переполняется ?
Вот например, мне нужно, что бы таймер начал считать с 0, а если уже считал то сбросился в 0 и начал с 0.
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xBlockTime );
Делает именно это или что-то другое ?
Что такое xBlockTime , почему про неё сказано , что "это то время, которое задача будет заблокирована, пока команда не запишется в очередь таймера" ? Таймер можно как-нибудь просто сбросить в 0 не блокируя задачу, в которой это делается ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jul 12 2014, 13:32
Сообщение #86


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(MiklPolikov @ Jul 12 2014, 04:58) *
Не могу до конца понять как работают программные таймеры.
Что такое "очередь таймера" и в каких случаях она переполняется ?
Вот например, мне нужно, что бы таймер начал считать с 0, а если уже считал то сбросился в 0 и начал с 0.


Полагаю, что термин "очередь таймера" относится не к аппаратному таймеру, как таковому, а к планировщику задач операционной системы разделенного времени. Т.е. в отсутствие операционной системы у таймеров нет никаких очередей.

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

Изменения в самой очереди, по-видимому, происходят только тогда, когда ставится новая задача или снимается/завершается старая. Т.е. только в этот момент в порядке очередности задач могут произойти какие-то изменения, тогда как задача таймера - чистое переключение.

В общем случае каких-то стандартов тут нет, т.к. авторы операционной системы вольны создать планировщик задач исключительно по своему вкусу, в том числе и вводить для его описания свои термины. Говорят, что когда-то номер/адрес следующего задания хранили прямо в самом таймере, используя его старшие разряды, которые обычно не используются. Но с тех пор и таймеры стали другими, и задачи стали сложнее, а потому нынче задачи обычно переключают по таблице, малость смахивающую на таблицу прерываний. Что-то более определенное сказать не могу, т.к. свою операционную системы вы не назвали. Хотя, судя по названию процедуры BaseType_t xTimerReset, у вас FreeRTOS.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jul 13 2014, 11:16
Сообщение #87


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(Xenia @ Jul 12 2014, 19:32) *
Судя по всему, под очередью понимается та задача/процедура, на которую таймер должен переключиться при выходе из своей процедуры прерывания. Т.е. по сути это чисто программная задача, а не аппаратная. Причем, место следующего возврата должно быть определено еще до запуска таймера, поскольку после того, как произойдет по нему прерывание, будет некогда искать того, кто стоит в очереди первым. В прерывании вообще нельзя долго находиться, а уж тем более выяснять там какие-то вопросы, которые обязаны были быть решены заранее.
мимо laughing.gif
не нужны ни какие места возврата.

Цитата
Не могу до конца понять как работают программные таймеры.
Открываем журнал КиТ №10 2011, страница 93. Читаем....

Цитата
Что такое "очередь таймера" и в каких случаях она переполняется ?

Очередь команд таймеров
Для совершения операций запуска, оста-
нова, сброса, изменения периода и удале-
ния таймеров во FreeRTOS предоставляется
набор API-функций, которые могут вызы-
ваться из задач и обработчиков прерываний,
а также из функций таймеров. Вызов этих
API-функций не воздействует напрямую
на задачу обслуживания таймеров. Вместо
этого он приводит к записи команды в оче-
редь, которую в дальнейшем мы будем на-
зывать очередью команд таймеров. Задача
обслуживания таймеров считывает команды
из очереди и выполняет их.

....
conf igTIMER_QUEUE_LENGTH. Размер
очереди команд — устанавливает макси-
мальное число невыполненных команд,
которые могут храниться в очереди, пре-
жде чем задача обслуживания таймеров их
выполнит.



Цитата
Что такое xBlockTime
смотрим там же...
xBlockTime — определяет время тайм-
аута — максимальное время нахождения
вызывающей xTimerChangePeriod() задачи
в блокированном состоянии, если очередь
команд полностью заполнена и нет воз-
можности поместить в нее команду об из-
менении периода таймера.

У вас очередь 5 команд. вызвали из других задач 5 разных команд. Потом из текущей вызываем xTimerChangePeriod(). Что должно произойти? Функция xTimerChangePeriod должна поместить в очередь таймера новую команду изменения периода, но очередь заполнина. Что делать? Текущая задача переходит в блокированное состояние на время xBlockTime или до тех пор, пока в очереди не появиться свободное место.


Цитата
Вот например, мне нужно, что бы таймер начал считать с 0, а если уже считал то сбросился в 0 и начал с 0.
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xBlockTime );
Делает именно это или что-то другое ?
там же, в ките, всёже на русском и могучем...
Сброс таймера
Сброс таймера осуществляется с помощью
API-функции xTimerReset(). Ее прототип:
portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType
xBlockTime );
...
Операция сброса может применяться как
к активному таймеру, так и к находящему-
ся в пассивном состоянии. В случае если
таймер находился в пассивном состоянии,
вызов xTimerReset() будет эквивалентен вы-
зову xTimerStart(), то есть таймер будет за-
пущен. Если таймер уже отсчитывал время
в момент вызова xTimerReset() (то есть на-
ходился в активном состоянии), то вызов
xTimerReset() приведет к тому, что таймер
заново начнет отсчет времени с момента вы-
зова xTimerReset().



Цитата
Таймер можно как-нибудь просто сбросить в 0 не блокируя задачу, в которой это делается ?

Скорее нельзя. ..... ээээ.... напрямую нет, или да.... вобщем сброс таймера - это запись команды сброса таймера в очередь таймеров. Если у вас 1 таймер... пара мест вызова API для таймера, в которые вы попадаете раз в год и очередь таймера 100 команд, то с вероятностью близкой к 1.0 ваша задача не будет блокирована вызовом xTimerReset(). Если у вас 100 таймеров, 1000 мест вызова API для таймеров... и/или вы ограниченны в длине очереди команд таймера, то можно сделать какойнить финт... типа: сделать задачу сброса таймера. эта задача будет ждать флага/эвента. Основная задача выставляет флаг/запускает эвент сброса таймера и работает дальше, а задача сброса таймера вызывает xTimerReset(). Если очередь таймера полна, то задача сброса таймера блокируется, а основная задача работает. Задача сброса должна быть приоритетом выше.
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jul 17 2014, 13:17
Сообщение #88


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(juvf @ Dec 23 2013, 21:33) *
Про зачистку памяти.....

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

например death.c
Код
void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority )
{
unsigned portBASE_TYPE *puxPriority;

        /* Create the Creator tasks - passing in as a parameter the priority at which
        the suicidal tasks should be created. */
        puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) );
        *puxPriority = uxPriority;

        xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );

        /* Record the number of tasks that are running now so we know if any of the
        suicidal tasks have failed to be killed. */
        uxTasksRunningAtStart = uxTaskGetNumberOfTasks();
}

Если задача vCreateTasks сама себя удалит, или её удалит кто-то другой, то память, веделенная вызовом pvPortMalloc не освободится. Нужно позаботится об её освобождении. Поэтому в задаче vCreateTasks делается ручная зачистка

Код
unsigned portBASE_TYPE uxPriority; //создается новая переменная на стеке
...

        uxPriority = *( unsigned portBASE_TYPE * ) pvParameters; //копируется данные из динамической выделенной памяти pvParameters в uxPriority
        vPortFree( pvParameters ); //удаляется динамически выделенная память.


Помогите пожалуйста разобраться с vPortFree.
Вот допустим, я удаляю задачу.
Что делать дальше ? Нужно передать в vPortFree в качестве параметра хендлер этой задачи, и тогда память, которую занимала задача, освободится ?
А если задача удаляет саму себя, перед этим присваивая значение NULL хэндлеру ?
Можно ли перед этим, прямо внутри задачи, запустить vPortFree ?
И как после этого задача продолжит работать , т.е. выполнит два последних действия
v_Task_Handle=NULL;
vTaskDelete(NULL);
если у задачи уже нет никакой памяти, т.е. в эту память может записаться что угодно ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 17 2014, 16:10
Сообщение #89


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Читаю все это и волосы дыбом. Тем более что и работаю с этим. Почему программист должен думать об освобождении памяти? Почему многопоточность не поддерживается средствами языка? Почему до сих пор все сидят на древних языках вроде С и С++ (он недалеко ушел от С, пусть и поддерживает ООП, но все равно с ним обрушить любую систему на ура можно. Есть ли нормальные реализации Явы или С шарп для контроллеров? Иначе это хождение по граблям будет вечным. 15 лет в теме и все одно и тоже. И памяти то уже достаточно для Явы например, и все равно. От слов «указатель» и «приведение типов» тошнит уже в век, когда объемы флеш и озу - ничто, а время на выпуск - все, это анахронизм какой то
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jul 17 2014, 16:46
Сообщение #90


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(DASM @ Jul 17 2014, 20:10) *
Читаю все это и волосы дыбом. Тем более что и работаю с этим. Почему программист должен думать об освобождении памяти? Почему многопоточность не поддерживается средствами языка? Почему до сих пор все сидят на древних языках вроде С и С++ (он недалеко ушел от С, пусть и поддерживает ООП, но все равно с ним обрушить любую систему на ура можно. Есть ли нормальные реализации Явы или С шарп для контроллеров? Иначе это хождение по граблям будет вечным. 15 лет в теме и все одно и тоже. И памяти то уже достаточно для Явы например, и все равно. От слов «указатель» и «приведение типов» тошнит уже в век, когда объемы флеш и озу - ничто, а время на выпуск - все, это анахронизм какой то


Если бы озу было "ничто", то я бы вообще не делал динамическое создание/удаление задач.
Если Вы знаете как надо, то скажите основные ключевые слова.
Есть проц STM32L151 . Выбран как самый малопотребляющий, т.е. ни на что более мощное перейти нельзя.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post

7 страниц V  « < 4 5 6 7 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


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


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