|
Cortex и гонки при сне |
|
|
|
 |
Ответов
|
Mar 29 2016, 08:22
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Kabdim @ Mar 29 2016, 12:30)  Вчера уткнулся ровно в ту же задачу. Кмк большинство отвечающих слишком привыкли к ртосам. Самому писать кусок с переключением контекстов при отсутсвии ртос - саму написать кусок ртос, непрактично. А что там непрактичного? Всё переключение контекста - пара десятков команд. Да и, если бы Вы внимательнее прочитали мой пост, как я писал - необязательно даже делать переключение контекста, достаточно задачу, обрабатывающую флаг, заключить в обработчик PendSV. Но с переключением контекста - правильнее, так как и стек для задачи будет свой и режим - непривилегированный. Цитата(Kabdim @ Mar 29 2016, 12:30)  1. Основной цикл перенести в SVC Вот это как раз непрактично. Или скорее даже невозможно. Насколько помню - у SVC приоритет выше чем у любого аппаратного прерывания (хотя может путаю), к тому же это - синхронное прерывание. Но самое главное - а что это Вам даст? Вы и WFI внутри SVC будете выполнять? А в чём тогда разница с фоновой задачей? А если Вы собираетесь возбуждать SVC внутри ISR аппаратного прерывания - это невозможно, ибо SVC - синхронное прерывание, это не PendSV, в ISR SVC будет вход сразу же, без ожидания выхода из ISR аппаратного прерывания, и последующие аппаратные прерывания будут заблокированы. Попытаетесь запретить - получите HardFault. Цитата(Kabdim @ Mar 29 2016, 12:30)  2. Пробуждающий обработчик прерываний меняет режим энергосбережения на слип и устанавливает таймер на ~20 тактов вперед. Даже если в это время сработает WFI, то произойдет быстрый выход из сна. Ничего не понял. Если он пробуждающий - почему тогда он sleep устанавливает??? Сами себе противоречите.... Не нравится PendSV по каким-то причинам, вместо него можно использовать программное возбуждение любого аппаратного прерывания с приоритетом ниже любого используемого в ПО аппаратного прерывания. Хотя это ничем не отличается от PendSV, которое как раз для таких целей и сделано.
|
|
|
|
|
Mar 29 2016, 23:31
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(jcxz @ Mar 29 2016, 19:13)  Что там велосипедить?  Запрет прерываний CPSID I - это и есть большой глабля. Подобные грабли есть практически во всех мобильных ОС "реального времени". Но прикол в том что при запрете прерываний - перестаёт создаваться очередь этих самых прерываний согласно приоритетам, то-есть банально теряются прерывания. Шанс маленький, да и поймать его достаточно сложно - но сам факт накладывает ограничения на реальность. В идеале ос должна быть без запретов прерываний, а такой финт можно реализовать только через SVC. Цитата(jcxz @ Mar 29 2016, 15:22)  А если Вы собираетесь возбуждать SVC внутри ISR аппаратного прерывания - это невозможно, ибо SVC - синхронное прерывание, это не PendSV, в ISR SVC будет вход сразу же, без ожидания выхода из ISR аппаратного прерывания, и последующие аппаратные прерывания будут заблокированы. Попытаетесь запретить - получите HardFault. Без запретов прерываний - вызов SVC возможен из любого места, в любом режиме работы ядра. Живая очередь прерываний по приоритетам будет продолжать создаваться в фоне, без какого-либо лага. Собственно моя ос - http://forum.ixbt.com/topic.cgi?id=48:11735репозиторий https://bitbucket.org/AVI-crak/rtos-cortex-m3-gcc/commits/Тот самый кусок кода - который отправляет ядро в сон по условию единственной оставшийся в конвертере нулевой задачи, когда в нулевой нет задач на обработку. То-есть момент когда чип сделал всё что от него требуется, и ожидает внешнего события. Код sTask_nil_re: ldr r5, [r12, #12] // адрес задач на обработку памяти cbnz r5, sTask_nil_nw ldr r0, [r12] ldr r1, [r0] cmp r0, r1 // активная единственная нулевая ittt ne // то ждём физики movne r3, 0x10 svcne 0x0 // __switch 0x10 bne sTask_nil_re wfi b sTask_nil_re sTask_nil_nw: В линейном коде без ос - достаточно языка С. do { __WFI(); } while(флаг);
|
|
|
|
|
Mar 30 2016, 05:32
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AVI-crak @ Mar 30 2016, 05:31)  Но прикол в том что при запрете прерываний - перестаёт создаваться очередь этих самых прерываний согласно приоритетам, то-есть банально теряются прерывания. Шанс маленький, да и поймать его достаточно сложно - но сам факт накладывает ограничения на реальность. Бред!При запрете прерываний они не теряются, а копятся в регистре запросов ожидающих прерываний. Как только прерывания будут разрешены, будет выбрано одно из ожидающих прерываний с наивысшим приоритетом и перейдёт в стадию обслуживания. Любая периферия на МК Cortex_M выдаёт прерывания "по уровню", т.е. - держит запрос пока он не будет обслужен. И все эти страшилки про "грех запрета прерываний" - байки. Конечно запрет прерываний вносит задержку в обслуживание. Но система уже должна проектироваться с учётом этого и устойчивой к задержкам обработки прерываний, это особенности облуживания прерываний в любой системе на любом МК - всегда есть какая-то задержка, больше или меньше. Цитата(AVI-crak @ Mar 30 2016, 05:31)  В идеале ос должна быть без запретов прерываний, а такой финт можно реализовать только через SVC. SVC разработчиками ядра вообще не для этого задумывался. Соотвественно: такое использование его - неоптимально. Цитата(AVI-crak @ Mar 30 2016, 05:31)  Без запретов прерываний - вызов SVC возможен из любого места, в любом режиме работы ядра. Живая очередь прерываний по приоритетам будет продолжать создаваться в фоне, без какого-либо лага. Ну да - как же. Попробуйте вызвать SVC при запрещенных исключениях. Или изнутри ISR с более высоким приоритетом (точно не помню - можно ли перепрограммировать приоритет SVC, но кто-то выше утверждал что можно). Получите HardFault. Так как SVC - синхронное прерывание. А для задачи ТСа нужно асинхронное. Типа PendSV (или любого аппаратного, возбуждаемого программно через регистр запросов NVIC). Цитата(AVI-crak @ Mar 30 2016, 05:31)  В линейном коде без ос - достаточно языка С. do { __WFI(); } while(флаг); Вы даже не поняли исходного вопроса ТС и того, чего он боится. А именно - случаев ухода в сон при установленном флаге требования обработки, когда эта обработка делается в том же процессе, который вызывает WFI. Полностью устранить эту проблему, можно только вынеся обработку флага в отдельный ISR или процесс (также запускаемый по прерыванию). Цитата(AVI-crak @ Mar 30 2016, 09:30)  Именно так. В дополнение - изначально Base priority mask register содержит 8 бит для определения приоритета, хотя в Cortex используется только 4 бита. При новом прерывании с более высоким уровнем внутри уже работающего - выставляется признак вложенного прерывания в Priority mask register. Это для управления возвратом из нового прерывания. При этом сравнение уровня прерывания происходит в момент его события. При запрете прерываний - и возникновении двух и более новых прерываний с разными уровнями - разрулить конечное состояние уже не получится. По этому запоминается первая регистрация нового прерывания, а всё остальное - игнорируется. В доках инфа на эту тему очень смутная. Проще проверить практически. Регистр маски приоритетов очевидно используется для маскирования запросов с более низким приоритетом и влияет только на активацию нового прерывания, но никак не возврат. Для возврата используется регистр LR, который указывает из какого режима CPU был вход в ISR и по какому стеку осуществлять возврат. В доках всё описано кристалльно понятно. Прочитайте их! И про два и более прерываний - там всё есть. Опять-же - RTFM!
|
|
|
|
|
Mar 30 2016, 06:38
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(jcxz @ Mar 30 2016, 12:32)  Бред! При запрете прерываний они не теряются, а копятся в регистре запросов ожидающих прерываний. Как только прерывания будут разрешены, будет выбрано одно из ожидающих прерываний с наивысшим приоритетом и перейдёт в стадию обслуживания. Действительно бред, записать в один регистр сразу кучу прерываний. Вложенность прерываний организованна по подобию стека. Соответственно в один момент может быть доступно всего одно активное прерывание, при запрете оно и регистрируется. В момент регистрации определяется как будет осуществятся возврат из него. Для разных состояний ядра arm - это разные точки восстановления, их всего 4 штуки. Дык вот, в момент действующего прерывания - этот адрес поддержки ядра уже использован. По заложенному сценарию после снятия запрета - можно будет выполнить одно дополнительное вложенное прерывание. Потому-что невозможно прописать адрес возврата для прерывания которое ещё не исполнилось, но имеет иной уровень приоритета. Отсебятина в регистре возврата прерывания в режиме ос - типа 0xFFFFFFFD - это и есть указатель на этот регистр. Это значение lr пишется в стек при вложенном новом прерывании более высокого уровня. Всё пля, стек прерываний закрыт. Напомню - в ос вся система крутится на самом слабом прерывании. Это сделано для того чтобы всё содержимое стека прерываний было выгружено, и состоялся переход на стек потока. Время отведённое для определения приоритета прерывания, а так-же установки адреса для чтения вектора - равно одному такту. Там просто нет возможности сравнивать все 15 уровней. Аппаратная возможность сравнения приоритета работает только в одну сторону - между действующим прерыванием и новым/отложенным более низким. Сравнить отложенное более высокое с новым низким отложенным - просто невозможно.
|
|
|
|
|
Mar 30 2016, 07:41
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AVI-crak @ Mar 30 2016, 12:38)  Действительно бред, записать в один регистр сразу кучу прерываний. В регистре находятся флаги запросов. Что в этом такого сверхъестественного? Каждый запрос - один бит. Что тут невозможного? А приоритеты для этих запросов - в другом регистре. Цитата(AVI-crak @ Mar 30 2016, 12:38)  Время отведённое для определения приоритета прерывания, а так-же установки адреса для чтения вектора - равно одному такту. Там просто нет возможности сравнивать все 15 уровней. Аппаратная возможность сравнения приоритета работает только в одну сторону - между действующим прерыванием и новым/отложенным более низким. Сравнить отложенное более высокое с новым низким отложенным - просто невозможно. Не понимаю - Вы чего доказать-то пытаетесь? Что аппаратно сравнить несколько уровней приоритета невозможно? Откройте любой учебник по цифровой электронике. Никаких проблем в этом нет, хоть за полтакта. Что процессор не сможет из двух ожидающих прерываний выбрать одно с наивысшим приоритетом и обслужить его первым, а затем - второе (если не пришло за это время более приоритетного)? Это противоречит здравому смыслу и докам на ядро, где это описывается. Если бы такое реально происходило, то после первого же запрета прерывания, во время которого успело прийти хотя-бы пару прерываний, происходила потеря прерываний и вообще нормальное функционирование было-бы невозможно. Миллионы устройств на Cortex-M работающих с кучей периферии с прерываниями и множественными запретами оных в коде - говорят об обратном.
|
|
|
|
Сообщений в этой теме
ataradov Cortex и гонки при сне Mar 28 2016, 17:12 jcxz А что собственно смущает? И зачем запрещать прерыв... Mar 28 2016, 17:34 ataradov QUOTE (jcxz @ Mar 28 2016, 10:34) А что с... Mar 28 2016, 17:48  jcxz Цитата(ataradov @ Mar 28 2016, 23:48) Обр... Mar 28 2016, 17:55   ataradov QUOTE (jcxz @ Mar 28 2016, 10:55) А кто д... Mar 28 2016, 18:05    KnightIgor Цитата(ataradov @ Mar 28 2016, 19:05) whi... Mar 28 2016, 19:16     ataradov QUOTE (KnightIgor @ Mar 28 2016, 12:16) К... Mar 28 2016, 19:23      KnightIgor Цитата(ataradov @ Mar 28 2016, 20:23) И п... Mar 28 2016, 19:45       ataradov QUOTE (KnightIgor @ Mar 28 2016, 12:45) П... Mar 28 2016, 19:51 aaarrr Еще можно так:
Код /* Clear event register */
__s... Mar 28 2016, 19:41 AVI-crak Цитата(ataradov @ Mar 29 2016, 00:12) Что... Mar 28 2016, 20:01 ataradov QUOTE (AVI-crak @ Mar 28 2016, 13:01... Mar 28 2016, 20:12  jcxz Цитата(ataradov @ Mar 29 2016, 02:12) Это... Mar 28 2016, 23:48 ataradov QUOTE (Kabdim @ Mar 28 2016, 23:30) А ваш... Mar 29 2016, 06:33  Kabdim Цитата(jcxz @ Mar 29 2016, 11:22) А что т... Mar 29 2016, 11:21   jcxz Цитата(Kabdim @ Mar 29 2016, 17:21) Нрави... Mar 29 2016, 12:13   GetSmart Цитата(AVI-crak @ Mar 30 2016, 03:31... Mar 30 2016, 01:59    AVI-crak Цитата(GetSmart @ Mar 30 2016, 08:59) Что... Mar 30 2016, 03:30    ataradov QUOTE (jcxz @ Mar 29 2016, 22:32) Полност... Mar 30 2016, 07:54     jcxz Цитата(ataradov @ Mar 30 2016, 13:54) Все... Mar 30 2016, 08:19      ataradov QUOTE (jcxz @ Mar 30 2016, 01:19) Вы даже... Mar 30 2016, 08:23       AVI-crak Цитата(ataradov @ Mar 30 2016, 15:23) Раз... Mar 30 2016, 13:02        ataradov QUOTE (AVI-crak @ Mar 30 2016, 06:02... Mar 30 2016, 15:32 Alechek Дейсвтельно мутно. Как оно может ПОТЕРЯТСЯ?
Особен... Mar 30 2016, 04:24 ViKo Не нашел, чтобы кто-то из участников данной дискус... Mar 30 2016, 06:07 jcxz Цитата(ViKo @ Mar 30 2016, 12:07) Не наше... Mar 30 2016, 06:20 Alechek Я тоже не понял, к чему весь этот треп.
Последова... Mar 30 2016, 12:12 ViKo Не имеет значения, как долго тянется прерывание, е... Mar 30 2016, 16:39 jcxz Цитата(ViKo @ Mar 30 2016, 22:39) Не имее... Mar 31 2016, 05:58  ataradov QUOTE (jcxz @ Mar 30 2016, 22:58) Я это у... Mar 31 2016, 06:01   jcxz Цитата(ataradov @ Mar 31 2016, 12:01) Ну ... Mar 31 2016, 06:21
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|