Сергей Борщ
Aug 28 2013, 09:22
QUOTE (сарматъ @ Aug 28 2013, 09:55)

подскажите а ТMutex.lock() запрещает прерывания или только блокирует переключение задач и запрет прерываний нужно делать отдельно?
Он не делает ни того ни другого. Он просто переводит этот TMutex в такое состояние, что задача, выполняющая следующий lock() будет поставлена на ожидание до тех пор, пока первая не сделает unlock(). Это описано в документации, с примерами.
сарматъ
Aug 28 2013, 10:37
а вот эта функция
static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }
запретит переключение задач?
AHTOXA
Aug 28 2013, 11:01
Да, запретит.
Но удобнее для этого пользоваться TCritSect:
Код
void foo(){
TCritSect cs;
... // всё отсюда до выхода из функции будет выполняться при запрещённых прерываниях.
}
сарматъ
Aug 28 2013, 11:22
спасибо, сейчас почитаю что это
вот что нашел
http://embedders.org/blog/teap0t/miro-same...u.html?page=0,7 кому интересно, позже будут вопросы в связи с прочитанным, там в седьмой статье описывается как грамотно запрещать прерывания в арм7 - как понимаю для порта на кортекс это актуально (хотя могу и ошибаться)
mdmitry
Aug 28 2013, 11:55
А не проще ли почитать документацию на scmRTOS
отсюда?
сарматъ
Aug 28 2013, 12:01
наверное проще и этот файл у меня открыт, вот только вхождений "критическая секция" в нем 2 штуки
SYS_TIMER_CRIT_SECT - 3 штуки, или куда именно предлагаете глазом упереться?
ах 2.3.3. вот сюда;-)
mdmitry
Aug 28 2013, 12:15
Цитата(сарматъ @ Aug 28 2013, 16:01)

наверное проще и этот файл у меня открыт, вот только вхождений "критическая секция" в нем 2 штуки
SYS_TIMER_CRIT_SECT - 3 штуки, или куда именно предлагаете глазом упереться?
Так ведь есть же исходные тексты. Файл OS_Target.h в помощь и
AHTOXA код привел.
сарматъ
Aug 28 2013, 12:28
мдмитрий и опять вы правы
антоха, снова я уперся в незнание асемблера, я правильно понимаю, что конструктор этого класса запоминает были ли запрещены прерывания на момент его вызова, а в момент вызова деструктора прерывания остаются запрещенными если на момент вызова конструктора они были запрещены?
еще раз перечитал 2.3.3. вроде именно это там и написано(смущающийся колобок)
новый вопрос, антоха, а в функции PendSVC_ISR() не происходит сохранения состояния статуса разрешения\запрещения прерываний до их запрещения?
AHTOXA
Aug 28 2013, 14:33
Цитата(сарматъ @ Aug 28 2013, 18:28)

а в функции PendSVC_ISR() не происходит сохранения состояния статуса разрешения\запрещения прерываний до их запрещения?
Нет, потому что PendSVC_ISR() - это прерывание, и оно может выполниться только при разрешённых прерываниях
сарматъ
Aug 28 2013, 15:13
аааааа.... вот как раз по поводу этого я ссылку выше и приводил
там касаемо ситуации возникновения прерывания во время выполнения инструкции запрещения прерывания
то есть выполняется где либо инструкция запрещения прерывания и во времяя этого возникает прерывание PendSVC_ISR() оно исполняется и разрешает прерывания и вываливается обратно в место где прерывания должны быть запрещены но по факту с разрешенными прерываниями
или я что то путаю?
вот еще одна ссылка
http://infocenter.arm.com/help/index.jsp?t....faqs/3677.html
AHTOXA
Aug 28 2013, 16:30
Ссылки про ARM7TDMI, это не то. У Кортексов всё это сделано значительно прямее.
сарматъ
Aug 28 2013, 20:20
дааа.... пока все это далеко от моего понимания, потому нашел временную альтернативу запрету прерываний, может кому пригодится
http://we.easyelectronics.ru/STM32/atomarn...-cortex-m3.htmlи да вопрос: будет ли конструкция
uint32_t oldValue, newValue;
do
{
oldValue = __LDREXW(ptr);
newValue = oldValue + value;
}while(__STREXW(newValue, ptr));
корректно работать с ОС?
AHTOXA
Aug 28 2013, 22:11
А чего там понимать? Вы читали не про тот контроллер

В Cortex-M4, если инструкция запрета прерываний прошла, то прерывание не возникнет.
Конструкция работать будет, без проблем.
Есть ещё
GCC Atomic-Builtins, делают то же самое, но несколько более универсальны. Вроде бы (точно не помню) тоже используют LDREX/STREX.
сарматъ
Aug 29 2013, 06:12
а если подобные конструкции будут в паралельных задачах они друг друга путать не будут?
и все же полностью без запрета прерываний не получается,
Цитата(AHTOXA @ Aug 29 2013, 01:11)

В Cortex-M4, если инструкция запрета прерываний прошла, то прерывание не возникнет.
где об этом можно прочитать? у меня макетка неделю работала потом повисла - ищу все потенциальные места где могло это произойти
AHTOXA
Aug 29 2013, 11:21
Цитата(сарматъ @ Aug 29 2013, 12:12)

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

Цитата(сарматъ @ Aug 29 2013, 12:12)

где об этом можно прочитать?
Вот тут. Более развёрнутое объяснение от Joseph Yiu (
отсюда) :
Цитата
On some processors, the disable interrupt function might take sometime to take effect. This is because the masking is done via control register accesses through the bus. (there could be wait state on the bus and the write operation could be buffered, and the interrupt controller might need a cycle to update to the new setting).
On Cortex-M3, the interrupt mask registers are inside the processors (e.g. FAULTMASK, PRIMASK). As soon as PRIMASK/FAULTMASK/BASEPRI is set, the effect come immediately. So if you set the PRIMASK and the interrupt arrived at the same time, the interrupt will have to wait until the mask is cleared. To do this, the interrupt mask registers are accessible by CPS, MSR and MRS instructions only
Короче, виснет не из-за этого.
сарматъ
Aug 30 2013, 21:50
#define disable_interrupts() __asm__ __volatile__ ("cpsid i\n cpsid i")
если так сделать ось не сломается?
или так надо? #define disable_interrupts() __asm__ __volatile__ ("cpsid i\n"" cpsid i")
AHTOXA
Aug 31 2013, 07:04
Варианты равнозначны. Ось не сломается.
Но два раза - маловато, лучше три, для верности
сарматъ
Aug 31 2013, 07:56
сарматъ
Sep 1 2013, 17:45
антоха, я вот нашел что происходит когда во время обработки прерывания возникают более и менее приоритетные прерывания, а как поступает кортекс когда возникает прерывание одинакового приоритета? текущее прерывание обрабатывается до конца и только потом начинает обрабатываться новое или вначале обрабатывается новое а потом дообрабатывается текущее? (то есть вопрос можно сформулировать так: новое прерывание ведет себя как прерывание с более низким или более высоким приоритетом?)
Прерывание с тем же приоритетом, что и текущее -- ждёт завершения текущего прерывания.
Советую почитать
хорошую книжку про кортекс-м3.
сарматъ
Sep 1 2013, 20:31
спасибо
сарматъ
Sep 2 2013, 14:14
а в порте для см4 обработка прерываний происходит как на рис 7.17 из этой книжки?
Нет. У нас прерывание системного таймера имеет самый низкий приоритет в системе, и не может прервать никакое другое прерывание.
То же касается и прерывания PendSV.
сарматъ
Sep 3 2013, 09:46
а что более ресурсоемко TEventFlag.wait() или sleep()?
Сергей Борщ
Sep 3 2013, 11:09
QUOTE (сарматъ @ Sep 3 2013, 11:46)

а что более ресурсоемко TEventFlag.wait() или sleep()?
Вот интересно, а что мешает заглянуть в исходники ОСи?
сарматъ
Sep 3 2013, 11:38
отсутствие необходимой квалификации как минимум
Сергей Борщ
Sep 3 2013, 13:28
QUOTE (сарматъ @ Sep 3 2013, 13:38)

отсутствие необходимой квалификации как минимум
Сравнить текст двух функций? В одной четыре строки кода, во второй - десять. Даже не смешно.
сарматъ
Sep 3 2013, 14:10
во первых я не ставил целью кого то рассмешить
во вторых, как я понимаю вы являетесь одним из разработчиков системы?, в таком случае спешу вам сообщить, что ваше описание системы, вероятно, имеет смыл доработать, в частности самый конец пункта 3.2.7
"В связи с этим, в большинстве случаев не возникает необходимости размещать код обработки событий на уровне прерываний даже при наличии такого аппаратного контроллера, а использовать прерывания только как источники событий, поместив их обработку на уровень процессов. Это рекомендуемый стиль построения программы." по крайней мере нуждается в существенных оговорках, рекомендуемый вами стиль построения программы при частоте поступления прерываний 10кГц дает потерю обработки около 50% событий, при размещении же обработчика целиком в теле прерывания потери составляют около 10%
сарматъ
Sep 4 2013, 08:04
измерил время выполнения sleep и wait таким образом
volatile uint32_t hgth;
hgth=DWT_CYCCNT;
sleep(10);
res_table.uregs[55]=DWT_CYCCNT-hgth;
volatile uint32_t hgth;
hgth=DWT_CYCCNT;
OneSecFlag.wait();
res_table.uregs[56]=DWT_CYCCNT-hgth;
получилось в первом случае 41000 тактов, во втором - 31000...
антоха это действительно эти функции выполнятся такое время или у меня что-то не так в программе?
кто-либо измерял аналогичные задержки в фриртос или иных системах?
похоже я что то не то измеряю
Цитата(сарматъ @ Sep 3 2013, 20:10)

рекомендуемый вами стиль построения программы при частоте поступления прерываний 10кГц дает потерю обработки около 50% событий, при размещении же обработчика целиком в теле прерывания потери составляют около 10%
Я думаю, что здесь проблема не в стиле, а в программе

Я на 72МГц STM32F103 спокойно декодирую 100КГц манчестер. С потерями 0% событий. А тут у вас 168МГц и 10КГц. Это совсем небольшая нагрузка.
Цитата(сарматъ @ Sep 4 2013, 14:04)

измерил время выполнения sleep и wait таким образом
Функция sleep() приостанавливает выполнение потока на заданное число тиков системного таймера. То есть, если таймер тикает раз в миллисекунду, то sleep(10) будет длиться от 9 до 10 мс. При частоте 168МГц это будет 168000*[9..10] тиков DWT. Ваши же числа совсем маленькие для 10 мс. С какой частотой у вас тикает системный таймер? С какой частотой взводится OneSecFlag?
сарматъ
Sep 4 2013, 08:46
да у меня ошибочная методика измерения времени, с малым значением разобрался - регистры у меня 16 разрядные соотв сохраняется не все 32 разр слово а только его хвост, короче те цифры что я привел выше ни о чем
а в вашей задачке на 100кгц сложная логика обработки событий? манчестер это протокол передачи данных типа модбас? у меня - прием и ответ на небольшой eth пакет размером в 100 байт (типа ответ на пинг)
Цитата(сарматъ @ Sep 4 2013, 14:46)

а в вашей задачке на 100кгц сложная логика обработки событий?
В прерывании - минимальная обработка, вычисляю длительность принятого импульса и кладу его в буфер (OS::channel).
А собственно анализ - достаточно сложный, но он выполняется в отдельном процессе. Собственно, всё сделано в точности так, как рекомендует документация
сарматъ
Sep 4 2013, 10:02
а приоритет этого процесса наивысший? и этот обработчик вызывается 100 раз за мс?
у меня было так
template <>
OS_PROCESS void TProc5::exec()
{
Eth_Slave();
}
OS::TEventFlag RxFlag;
OS_PROCESS void Eth_Slave(void){
for(;;){
RxFlag.wait();
for(;(DMARxDescToGet->StatusÐ_DMARxDesc_OWN) == (uint32_t)RESET;){
формирование отклика на прерывание - 5us;
}
}
}
extern "C" void ETH_IRQHandler(void)
{
ETH_DMAClearITPendingBit(ETH_DMA_IT_R | ETH_DMA_IT_T);
RxFlag.signal_isr();
}
вообще возможность послать сигнал в процесс из прерывания оч красива
Цитата(сарматъ @ Sep 4 2013, 16:02)

а приоритет этого процесса наивысший? и этот обработчик вызывается 100 раз за мс?
Нет, приоритет средний. Были более приоритетные задачи. И вызываться(просыпаться) он мог реже, чем 100 раз за мс. События копятся в очереди, и обрабатываются асинхронно, когда есть для этого время.
Цитата(сарматъ @ Sep 4 2013, 16:02)

extern "C" void ETH_IRQHandler(void)
{
ETH_DMAClearITPendingBit(ETH_DMA_IT_R | ETH_DMA_IT_T);
RxFlag.signal_isr();
}
У вас не хватает обязательной строчки в начале обработчика прерывания:
Код
OS::TISRW ISRW;
Сергей Борщ
Sep 4 2013, 12:44
Вы забыли:
а) тег [ code ]
б) в начале обработчика прерывания завести объект типа TISRW. Поэтому реальная перепланировка и получение сигнала у вас происходили при вызове перепланировки из какого либо процесса (при вызове функции какого-либо сервиса ОС) или же после прерывания ситемного таймера. Видимо поэтому часть сигналов и была потеряна.
сарматъ
Sep 4 2013, 12:50
спасибо, не помню ставил ли я эту строчку... в другом прерывании она есть а тут не помню, сейчас еще раз попробую этот вариант
да действительно мой косяк сейчас сделал все работает так же как и с полной обработкой в теле прерывания, еще раз спасибо
почитал про OS::channel да создатели молодцы очень красивая система
сарматъ
Sep 19 2013, 08:10
антоха а в планах не стоит для ф417 контроллера порт сделать? это тот который с периферией для aes
AHTOXA
Sep 19 2013, 09:38
А какая разница с точки зрения порта?
сарматъ
Sep 19 2013, 09:53
сейчас вот подумал может действительно никакой, просто там доп регистры есть для поддержки шифрования, но ведь скажем регистры управления какой нить spi тоже же не сохраняются, похоже меня просто в виртуализацию устройств занесло
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.