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

 
 
> Есть ли жизнь после WFI?, атомарность WFI
Brain13
сообщение Jun 1 2015, 18:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Здравствуйте!
Я тут задумался о такой потенциальной проблеме при использовании инструкции WFI: Предположим, что программа должна дождаться получения байта по UART, логичным был бы код
Код
while(!Uart.DataAvailable()) {
    __WFI();
}
// тут обработка данных

Но проблема в том что искомый байт может придти между Uart.DataAvailable() и __WFI(), вызовется обработчик прерывания, после которого вызовется __WFI() и МК больше никогда не проснется.

Вставка критических секций:
Код
__disable_irq();
// тут что-то
__enable_irq();
__WFI();

не спасет ситуацию, так как между __enable_irq(); и __WFI(); может проскочить нужное прерывание(а может не проскочить).

Поиски вывели меня на вот эту англоязычную тему: http://community.arm.com/message/8927 и доку http://infocenter.arm.com/help/index.jsp?t...a/BIHBFEIB.html
Но я так и не понял, что есть решение проблемы.
Так есть ли в Cortex-M гарантированный способ проснуться после WFI?
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 36)
Golikov A.
сообщение Jun 1 2015, 18:39
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А почему вфи будет не после возврата из прерывания и по новому не проснеться?
Go to the top of the page
 
+Quote Post
Brain13
сообщение Jun 1 2015, 18:54
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Цитата(Golikov A. @ Jun 1 2015, 21:39) *
А почему вфи будет не после возврата из прерывания и по новому не проснеться?

Не уверен, что понял Ваш вопрос, но постараюсь расписать поподробнее.

В крайнем случае имеем код типа
Код
__disable_irq();
// тут проверки на наличие принятого байта
__enable_irq();
__WFI();

Если проверка покажет, что байт еще не пришел, то исполнение дойдет до строчки __enable_irq. Если искомый байт придет вот в этот момент - исполненится прерывание. После возвращения из прерывания исполнится инструкция WFI, которая будет ожидать нового прерывания, соответственно ядро не проснется. (понятное дело, других прерываний в примере нет)

Вопрос: как дождаться прерывания с использованием WFI и гарантированно проснуться?
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jun 1 2015, 19:59
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Таки в обработчике прерывания от UART можно взвести таймер на пару десятков тиков клока, тады и проснётесь...
Go to the top of the page
 
+Quote Post
Brain13
сообщение Jun 1 2015, 20:03
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Кажется, я нашел ответ: http://infocenter.arm.com/help/index.jsp?t...a/BABGGICD.html
Цитата
Some embedded systems might have to execute system restore tasks after the processor wakes up, and before it executes an interrupt handler. To achieve this set the PRIMASK bit to 1 and the FAULTMASK bit to 0. If an interrupt arrives that is enabled and has a higher priority than current exception priority, the processor wakes up but does not execute the interrupt handler until the processor sets PRIMASK to zero.


Т. е. код должен быть примерно таким:
Код
while(1)
{
  __disable_irq();
  if(Uart.DataAvailable()) {
    break;
  }
  __WFI();
  __enable_irq();
  __NOP();
}

Соотетственно если байт придет перед инструкией WFI, то произойдет запрос прерывания, но обработчик не вызовется(прерывания запрещены), потом вызовется WFI, но он не усыпит прессор так как есть запрос на прерывание, потом исполнится enable_irq, после которого(в течение 0-2 инструкций) вызовется обработчик прерывания.

Теперь осталось это проверить.

Цитата(RabidRabbit @ Jun 1 2015, 22:59) *
Таки в обработчике прерывания от UART можно взвести таймер на пару десятков тиков клока, тады и проснётесь...

Во-первых, это - костыль.
Во-вторых, еще не хватает мне таймер на это тратить, они же не бесплатно в МК даются - это ценный ресурс.

Сообщение отредактировал Brain13 - Jun 1 2015, 20:02
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 1 2015, 23:06
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Brain13 @ Jun 1 2015, 23:03) *
Во-вторых, еще не хватает мне таймер на это тратить, они же не бесплатно в МК даются - это ценный ресурс.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 2 2015, 07:06
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Я посмотрел ARM DDI 0403E.b - Architecture Reference Manual - стр. B1-618: TS, эта команда разве в цикле должна вызываться?

Опять же, прерывание для того и существует, чтобы событие его порождающее не ждать.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 2 2015, 07:25
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Соотетственно если байт придет перед инструкией WFI, то произойдет запрос прерывания, но обработчик не вызовется(прерывания запрещены), потом вызовется WFI, но он не усыпит прессор так как есть запрос на прерывание, потом исполнится enable_irq, после которого(в течение 0-2 инструкций) вызовется обработчик прерывания.


Цитата
WFI is a hint instruction that suspends execution until one of the following events occurs:
a non-masked interrupt occurs and is taken
an interrupt masked by PRIMASK becomes pending
a Debug Entry request.


то есть если вы замаскируете прерывание, и вызовите wfi, а размаскирование стоит после нее, то это кирпич?
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Jun 2 2015, 08:50
Сообщение #9


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Предложу взглянуть на статью Use an MCU's low-power modes in foreground/background systems by Miro M. Samek, ESD, September 2007, есть у неё и перевод.
Добавлю, что у Cortex-M можно настроить работу так, что по выходу из обработчика прерывания ядро не будится без дополнительных действий


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
Brain13
сообщение Jun 3 2015, 17:18
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Цитата(zltigo @ Jun 2 2015, 02:06) *
Вы уж определитесь, что Вы делаете - сферического коня в вакууме с одим прерыванием и кучей лишних ресурсов, в том числе и таймеров, или реальную систему в которой будут и другие источники прерываний от тех-же таймеров. Не говоря уже о том, что UART тоже может быть не однм источником прерывания.

Я делаю реальную систему, но если я хочу дождаться прервания по UART причем тут прерывание по таймеру?

Цитата(Obam @ Jun 2 2015, 10:06) *
Я посмотрел ARM DDI 0403E.b - Architecture Reference Manual - стр. B1-618: TS, эта команда разве в цикле должна вызываться?

Опять же, прерывание для того и существует, чтобы событие его порождающее не ждать.

Часто бывают случаи когда нужно дождаться какого либо события и только потом действовать. А while(xxx) {} не сильно хороший вариант, ибо потребление.

Цитата(Golikov A. @ Jun 2 2015, 10:25) *
то есть если вы замаскируете прерывание, и вызовите wfi, а размаскирование стоит после нее, то это кирпич?

Вот именно, что не кирпич, ведь мы запрещаем не само прерывание, а вызов его обработчика. При появлении запроса на прерывание процессор проснется, а вызов обработчика произойдет после __enable_irq();. Я проверил, такой код работает и не виснет(STM32F3DISCOVERY):
CODE
int main(int argc, char* argv[]) {
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

GPIO_InitTypeDef gpio;

gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_Pin = GPIO_Pin_9;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOE, &gpio);
GPIO_ResetBits(GPIOE, GPIO_Pin_9);

gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_Pin = GPIO_Pin_0;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &gpio);

EXTI_InitTypeDef exti;
exti.EXTI_Line = EXTI_Line0;
exti.EXTI_Mode = EXTI_Mode_Interrupt;
exti.EXTI_Trigger = EXTI_Trigger_Rising;
exti.EXTI_LineCmd = ENABLE;

EXTI_Init(&exti);

NVIC_InitTypeDef nvic;

nvic.NVIC_IRQChannel = EXTI0_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 0x0F;
nvic.NVIC_IRQChannelSubPriority = 0x0F;
nvic.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&nvic);

// Infinite loop
while (1)
{
for(;;) {
__disable_irq();
if(flag) break;
__WFI();
__enable_irq();
__NOP();
__NOP();
__NOP();
}
__enable_irq();

if(GPIO_ReadOutputData(GPIOE) & GPIO_Pin_9) {
GPIO_ResetBits(GPIOE, GPIO_Pin_9);
} else {
GPIO_SetBits(GPIOE, GPIO_Pin_9);
}
flag = 0;
}
}

void EXTI0_IRQHandler(void)
{
if((EXTI_GetITStatus(EXTI_Line0) != RESET)) {
flag = 1;
EXTI_ClearITPendingBit(EXTI_Line0);

}
}


Сообщение отредактировал IgorKossak - Jun 3 2015, 17:45
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 3 2015, 17:28
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Brain13 @ Jun 3 2015, 20:08) *
Я делаю реальную систему, но если я хочу дождаться прервания по UART причем тут прерывание по таймеру?

Еще раз, медленно и печально в Вашей "реальной" системе прерывание UART единственное? И вообще никакой другой работы у контроллера НЕТ,
раз Вы только занимаетесь обработкой того, что получили в прерывании. Если да, то тогда Вы просто решаете задачу через анус - делайте просто ВСЮ
"работу" в прерывании и не изобретайте проблемы. Если ответ нет, тогда и проблемы нет с гипотетическим непросыпанием.




--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Brain13
сообщение Jun 3 2015, 18:01
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Цитата(zltigo @ Jun 3 2015, 20:28) *
Еще раз, медленно и печально в Вашей "реальной" системе прерывание UART единственное? И вообще никакой другой работы у контроллера НЕТ,
раз Вы только занимаетесь обработкой того, что получили в прерывании. Если да, то тогда Вы просто решаете задачу через анус - делайте просто ВСЮ
"работу" в прерывании и не изобретайте проблемы. Если ответ нет, тогда и проблемы нет с гипотетическим непросыпанием.

Тема начинается со слов "Предположим, что программа должна дождаться получения байта по UART"
В системе присутствует множество источников прерываний: SPI, UART, SysTick, Таймеры, Внешние прерывания и прочее. Но все это к решению задачи не относится.
Если это так важно, то я делал код для бутлоадера, который при переполнении буфера ждет пока хотябы один байт будет отправлен в UART и тогда в буфере появится место для добавления еще одного байта. Та же самая песня с чтением байта из пустого буфера. И да, в момент когда мы работаем с UARTом другая периферия пока не используется и у МК другой работы нет. Только обьясните как это знание поможет Вам решить проблему с WFI?

Использовать таймер или любую другую периферию для ожидания байта по UART - вот это решение через анус. Понятое дело, что в конечом итоге процессор проснется, но это костыль и надежда на "авось его что-нибудь другое разбудит".
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 3 2015, 19:42
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Вот именно, что не кирпич, ведь мы запрещаем не само прерывание, а вызов его обработчика.

Вы запрещаете вызов вообще любого обработчика __disable/__enable_irq(); - это запрет вообще реакции на прерывание, писать так для NVIC не очень правильно.

Для него обычно маскируют(демаскируют) то прерывание которое не должно мешать, и в этом случае как я понимаю будет кирпичик...

Но в случае входа в сон с проверкой активных прерываний для отмены перехода, наверное пойдет глобальный их запрет. Только так и таймер тоже отключиться, у вас таймера нету? Тики не читаете?
Go to the top of the page
 
+Quote Post
_4afc_
сообщение Jun 3 2015, 20:33
Сообщение #14


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

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Цитата(zltigo @ Jun 3 2015, 21:28) *
Еще раз, медленно и печально в Вашей "реальной" системе прерывание UART единственное? И вообще никакой другой работы у контроллера НЕТ,
раз Вы только занимаетесь обработкой того, что получили в прерывании. Если да, то тогда Вы просто решаете задачу через анус - делайте просто ВСЮ
"работу" в прерывании и не изобретайте проблемы.


Вот я почему-то так и делал в своей системе. Вся обработка в прерывании - результат складывается в буфер с увеличением счетчика. и while WFI
Как может произойти пропуск прерывания за несколько тактов? Неужто UART на 1000МГц?
Сколько мС занимает цикл while и с какой частотой работает UART?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 3 2015, 20:49
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_4afc_ @ Jun 3 2015, 23:33) *
Неужто UART на 1000МГц?

Да хоть 32кГц! Он асинхронный, так что прерывание может сработать между проверкой условия и WFI.

Вообще, не понимаю шума, поднятого отдельными товарищами. ТС озвучил вполне реальную проблему и один из путей её решения.
Так ведь нет, надо свести к частным случаям и доказать, что это никому не нужно.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 4 2015, 00:40
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Brain13 @ Jun 3 2015, 21:01) *
Тема начинается со слов "Предположим, что программа должна дождаться получения байта по UART"
В системе присутствует множество источников прерываний: SPI, UART, SysTick, Таймеры, Внешние прерывания и прочее. Но все это к решению задачи не относится.

К решению какой задачи? Про сферического коня в вакууме в которой специально создаются некие условия, отметается другая постановка задачи и системные решения и начинается решаться "задача"?
QUOTE
Если это так важно, то я делал код для бутлоадера, который

Да, ну очень важная функция бутлоадера засыпать между отправками байтов. Ну, допустим, без экономии жить нельзя...
QUOTE
при переполнении буфера ждет пока хотябы один байт будет отправлен в UART и тогда в буфере появится место для добавления еще одного байта.

DMA, FIFO а так-же, прочие "ценные ресурсы" контролера не должны использоваться, потому, что потому sad.gif....
QUOTE
Использовать таймер или любую другую периферию для ожидания байта по UART - вот это решение через анус. Понятое дело, что в конечом итоге процессор проснется, но это костыль и надежда на "авось его что-нибудь другое разбудит".

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


QUOTE (aaarrr @ Jun 3 2015, 23:49) *
Вообще, не понимаю шума, поднятого отдельными товарищами. ТС озвучил вполне реальную проблему и один из путей её решения.

Не открытие, но за напоминание, безусловно спасибо.
QUOTE
Так ведь нет, надо свести к частным случаям и доказать, что это никому не нужно.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 4 2015, 01:05
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Jun 4 2015, 03:40) *
К частному, вырожденному случаю свел именно Автор.

Человеку, знакомому с проблемой, достаточно прочитать два первых предложения исходного поста, чтобы понять суть вопроса. Вдаваться в приведенные для примера условия ("Предположим...") совсем не обязательно.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 4 2015, 04:00
Сообщение #18


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



А в чем, собственно, проблема? Ставьте WFI после обработки данных (см. код в первом сообщении), а не после приема. Разве не логично?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 4 2015, 06:26
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Проблема понятна, можно даже не брать UART и прочее, гораздо абстрактнее

WFI засыпает до прерывания и если делать

_irq_disable();
.... //какие то проверки возможности уснуть
_irq_enable();
__WFI();

то есть шанс что прерывание произойдет между
_irq_enable();
//вот прямо вот здесь
__WFI();

соответственно оно будет обработано до __WFI, и не будет причиной пробуждения, то есть схема будет спать до следующего.

Поэтому правильно этот кусок кода писать в таком виде

_irq_disable();
.... //какие то проверки возможности уснуть
__WFI();
_irq_enable();

это просто надо запомнить, также как, что прерывания надо сбрасывать через присвоение (=), а не через &=, |=
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 4 2015, 08:07
Сообщение #20


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(Golikov A. @ Jun 4 2015, 10:26) *
Поэтому правильно этот кусок кода писать в таком виде

_irq_disable();
.... //какие то проверки возможности уснуть
__WFI();
_irq_enable();


Прошу пощения, как (чем) при запрещённых прерываниях ядро будет выведено из (цитирую ARM DDI 0403E.cool.gif
"suspend execution and enter a low-power state. It can remain in that
state until the processor detects one of the following WFI wakeup events:
• A reset.
• An asynchronous exception at a priority that, if PRIMASK was set to 0, would preempt any currently active
exceptions.
Note
The processor ignores the value of PRIMASK in determining whether an asynchronous exception is a WFI
wakeup event.
• If debug is enabled, a debug event.
• An IMPLEMENTATION DEFINED WFI wakeup event."? (конец цитаты)

Какое событие из списка позволит исполнить _irq_enable()?


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 4 2015, 08:12
Сообщение #21


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Golikov A. @ Jun 4 2015, 09:26) *
Поэтому правильно этот кусок кода писать в таком виде

_irq_disable();
.... //какие то проверки возможности уснуть
__WFI();
_irq_enable();

это просто надо запомнить, также как, что прерывания надо сбрасывать через присвоение (=), а не через &=, |=

Т.е. уснуть и не проснуться? rolleyes.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 4 2015, 09:30
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



О чем собственно и есть эта тема.

Как я понял __WFI(); - анализирует регистр битиков в векторе NVIC
в то время как
_irq_disable();
_irq_enable();
работает со статусным регистром проца.
потому когда вы делаете
_irq_disable();
вы запрещаете переход проца в обработку, но все механизмы нужные WFI для просыпания оставляете работоспособными. Уверености что это не получилось случайно, и что именно так они и хотели у меня нет, может это баг обращенный в фичу, но тем не менее...

Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 4 2015, 09:50
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Можно применить еще такой вариант:
Код
__SEV();
__WFE();
if(<можно спать>)
    __WFE();

Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 4 2015, 09:57
Сообщение #24


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Всё, согласен. wink.gif
Мир устоял.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 4 2015, 10:12
Сообщение #25


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Golikov A. @ Jun 4 2015, 12:30) *
Как я понял __WFI(); - анализирует регистр битиков в векторе NVIC
в то время как
_irq_disable();
_irq_enable();
работает со статусным регистром проца.
потому когда вы делаете
_irq_disable();
вы запрещаете переход проца в обработку, но все механизмы нужные WFI для просыпания оставляете работоспособными. Уверености что это не получилось случайно, и что именно так они и хотели у меня нет, может это баг обращенный в фичу, но тем не менее...

Где такое написано?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 4 2015, 10:14
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ViKo @ Jun 4 2015, 13:12) *
Где такое написано?

См. Note в цитате из мануала выше.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 4 2015, 10:34
Сообщение #27


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(aaarrr @ Jun 4 2015, 13:14) *
См. Note в цитате из мануала выше.

А что в ней написано? rolleyes.gif
В тех примерах, что я посмотрел, везде разрешаются прерывания перед использованием WFI.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 4 2015, 10:51
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ViKo @ Jun 4 2015, 13:34) *
А что в ней написано? rolleyes.gif

Действительно, что?

Цитата(ViKo @ Jun 4 2015, 13:34) *
В тех примерах, что я посмотрел, везде разрешаются прерывания перед использованием WFI.

Далеко не всегда в запрещении прерываний есть необходимость.
Необходимость возникает, когда WFI выполняется в зависимости от условия, которое может измениться в прерывании.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 4 2015, 11:45
Сообщение #29


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(aaarrr @ Jun 4 2015, 13:51) *
Действительно, что?

Что независимо от запрещенных прерываний (установленного бита в BASEPRI командой _disable_irq) может разбудить процессор:
• событие Debug
• некое IMPLEMENTATION DEFINED WFI.
Это говорит о том, что любое запрещенное прерывание может разбудить процессор?

Неправильно. Примечание относится к пункту 2. Хорошо... будем искать дальше...
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 4 2015, 12:22
Сообщение #30


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(ViKo @ Jun 4 2015, 15:45) *
…(установленного бита в BASEPRI командой _disable_irq)…


Вспомнился старый анекдот: "…Не ебонит!!! Целлюлёид!!!…" sm.gif
PRIMASK


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 4 2015, 12:31
Сообщение #31


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Obam @ Jun 4 2015, 15:22) *
Вспомнился старый анекдот: "…Не ебонит!!! Целлюлёид!!!…" sm.gif
PRIMASK

Описался. rolleyes.gif
Go to the top of the page
 
+Quote Post
Brain13
сообщение Jun 4 2015, 18:22
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Цитата
Это говорит о том, что любое запрещенное прерывание может разбудить процессор?


Нет, запрещенное походу не разбудит...
http://infocenter.arm.com/help/index.jsp?t...a/BABGGICD.html
Цитата
To achieve this set the PRIMASK bit to 1 and the FAULTMASK bit to 0. If an interrupt arrives that is enabled and has a higher priority than current exception priority, the processor wakes up but does not execute the interrupt handler until the processor sets PRIMASK to zero.

То есть разбудит процессор только разрешенное(я так понимаю в NVIC) прерывание с более выским приоритетом.

Сообщение отредактировал Brain13 - Jun 4 2015, 18:23
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 5 2015, 04:38
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А вот и последняя часть пазла

http://infocenter.arm.com/help/index.jsp?t...e/CJAFBCBB.html

Цитата
__disable_irq
Typically, this intrinsic disables IRQ interrupts by setting the I-bit in the CPSR. However, for M-profile it sets the exception mask register (PRIMASK).


и следовательно последовательность

__disable_irq
....
__swi() __WFI()
....
__enable_irq
правильная,


Цитата
the processor wakes up but does not execute the interrupt handler until the processor sets PRIMASK to zero.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Jun 5 2015, 04:46
Сообщение #34


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(Golikov A. @ Jun 5 2015, 08:38) *
и следовательно последовательность

__disable_irq
....
__swi() или __wfi()
....
__enable_irq
правильная,

???
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 5 2015, 05:46
Сообщение #35


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(Golikov A. @ Jun 5 2015, 08:38) *
и следовательно последовательность

__disable_irq
....
__swi()
....
__enable_irq
правильная,


Не в масть! Даже команды такой нет. (Гусары, про UAL молчать!!!)
Тема про WFI!


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 5 2015, 10:58
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Да я о чем-то своем думал, естественно имел ввиду команду WFI, поправил сообщение, простите...

Гусары могут кричать, коль сопоставить 2 факта не в силах....

еще раз для гусар, а то вдруг опять че не поймут

вот так правильно

__disable_irq()
....
__WFI()
....
__enable_irq()
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 6 2015, 07:14
Сообщение #37


Гуру
******

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



Имхо - у ТС изначально неверно построен алгоритм. WFI не нужно смешивать с каким-либо полезным кодом.
Систему с WFI надо строить так, чтобы WFI выполнялось в фоновом процессе (возможно просто бесконечный цикл while (1) WFI();),
а вся полезная работа - в задачах или ISR с приоритетом выше фонового.
Тогда никаких запретов прерывания с WFI не нужно, WFI будет выполняться только когда нет ждущих прерываний.
Если ПО без ОС - вся работа в ISR-ах (разбитых по приоритетам), в фоновой задаче - функция main() заканчивающаяся while (1) WFI();.
Go to the top of the page
 
+Quote Post

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

 


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


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