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

 
 
> М3/М4 - как сделать трюк с прерываниями?
Allregia
сообщение Oct 23 2012, 11:30
Сообщение #1


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

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Подкажите решение:
1) есть проограмма, сейчас на М3 (lpc1768) но вообще будет на М4 (stm32f4), без ОС.
в ней выполняются фоновые задачи, в т.ч и пересылка DMA, и есть циклы типа while()
2) есть довольно высокочастотное прерывание (неважно от чего) INT1 с регулярной частотой (периодом - T1)
3) после каждых N должна выполниться подпрограмма SUB1, время выполнения SUB1 - T2
Естественно, T2< N*T1,
но - T2>T1.
Т.е. во время выплонения SUB1 обязательно произойдет прерывание INT1.
4) пропустить INT нельзя, как нельзя пропустить и SUB1.

Первой что пришло в голову - крутить в INT1 счетчик, когда он досчитал до N - выставлять флаг.
В SUB1 его проверять, но при в основной программе во всех циклах вставлять вызов SUB1
Код
#define N 10
u8 IntFlag=0;
//-----
void INT1(void){
static cnt=0;
    .........
   if(++cnt>N){
      cnt=0;
      IntFlag=1;
   }
}
//-----
void SUB1(void){
   if(IntFlag){
      IntFlag=0;
      ...........
   }
}
//
int main(void){
    .......
   while(xxxx){
      .....
      SUB1();
   }

    ........
}


Проблемы:
1) не пропустить бы какой-то while/for, это надо из все просматривать во всей программе, е везде вставлять вызов SUB1
2) на многочисленные вызовы SUB1 тратиться довольно много времени, так например скорость записи в SD-флешку (по DMA!) падает процентов на 20-30 (хотя и огстается в пределат требуемогодля моей задачи).

Может кто подскажет более элегантное решение ?
Может оформить SUB1 как прерывание более низкого уровня чем INT1 и вместо установки флага, как-то его иничиировать в конце N-ного INT1 ? но как это сделать ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Allregia
сообщение Oct 23 2012, 15:46
Сообщение #2


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

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Я пока с NVIC до конца не разобрался.
Не очень вьехал чем отличается PreemptionPriority от SubPriority?

У меня в программе 4 прерывания, в порядке приоритета:
1) SPI
2) мое программное, инициируемое в прерывании SPI
3) UART
4) SysTick

и делать надо так:

Код
...
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
                        // Setup SysTick Timer for 1 msec interrupts, lowest priority
      if (SysTick_Config(SystemCoreClock / 1000)) { while (1);} // Capture error
        NVIC_SetPriority(SysTick_IRQn,  4);  //    SysTick priority=4
       ..

      // uart
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
      ...
     // sw interrupt
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
     ...
     // SPI, highest priority
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    ...


Или можно просто после всех инициализаций, которые у меня есть сейчас, написать:
Код
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_SetPriority(SPI2_IRQn,                1);  //    SPI priority=1
        NVIC_SetPriority(EXTI15_10_IRQn,       2);  //    SW interrupt priority=2
        NVIC_SetPriority(USART3_IRQn_IRQn,  3);  //    UART=3
        NVIC_SetPriority(SysTick_IRQn,            4);  //    SysTick priority=4
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 23 2012, 20:31
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Allregia @ Oct 23 2012, 18:46) *
Или можно просто после всех инициализаций, которые у меня есть сейчас, написать:
Код
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_SetPriority(SPI2_IRQn,                1);  //    SPI priority=1
        NVIC_SetPriority(EXTI15_10_IRQn,       2);  //    SW interrupt priority=2
        NVIC_SetPriority(USART3_IRQn_IRQn,  3);  //    UART=3
        NVIC_SetPriority(SysTick_IRQn,            4);  //    SysTick priority=4

Можно так и написать.
Странно что приоритеты не от 0 задаёте (0 - умолчание), а от 1.

Нужно вызвать NVIC_PriorityGroupConfig с соответствующим параметром (например 0 - отмена групп).


Цитата(Allregia @ Oct 23 2012, 23:18) *
Т.е. если я хочу чтобы прерывание с более высоким приоритетом прерывало прерывание с более низким, они обязательно долдны быть в разных группах?


А если они из одной группы, и выполняется прерывание с бОльшим номером подгруппы (т.е. менее приоритетное), то прерывание той-же группы с меньшим номером (по идее более приоритетное) его не прервет?

Прерывания одного приритета друг друга не могут прервать. исполняемое прерывание может быть прервано только более приоритетным.


Цитата(Allregia @ Oct 23 2012, 23:18) *
Т.е. если в момент выполнения высокоприоритетного прерывания возникает другое, менее приоритетное, то оно подождет и будет выполнено после

Подождёт.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 23 2012, 20:32
Сообщение #4


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

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



Есть ещё удобная функция
Код
uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)


Я обычно делаю так:
где-то в начале задаю группировку:
Код
NVIC_SetPriorityGrouping(5); // 2 bit preemption (0..3), 2 bit of subprio (0..3)


И по месту, при настройке нужного прерывания:
Код
NVIC_SetPriority(SPI2_IRQn,
    NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 1, 2));

- задаёт приоритет с preemtion priority = 1 и subpriority = 2.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Allregia   М3/М4 - как сделать трюк с прерываниями?   Oct 23 2012, 11:30
- - _Артём_   Цитата(Allregia @ Oct 23 2012, 14:30) Мож...   Oct 23 2012, 11:38
|- - Allregia   Цитата(_Артём_ @ Oct 23 2012, 13:38) Код ...   Oct 23 2012, 12:32
|- - _Артём_   Цитата(Allregia @ Oct 23 2012, 15:32) Я в...   Oct 23 2012, 13:00
- - Flexz   Если высокочастотное прерывание идет от внешнего и...   Oct 23 2012, 12:00
- - Flexz   Цитата(Allregia @ Oct 23 2012, 16:32) EXT...   Oct 23 2012, 12:50
- - Allregia   Т.е как я понял. проще всего через EXTI: Код//выс...   Oct 23 2012, 14:04
|- - _Артём_   Цитата(Allregia @ Oct 23 2012, 17:04) Т.е...   Oct 23 2012, 14:27
- - esaulenka   ЦитатаНе очень вьехал чем отличается PreemptionPri...   Oct 23 2012, 16:54
|- - Allregia   Цитата(esaulenka @ Oct 23 2012, 18:54) Пе...   Oct 23 2012, 18:23
|- - _Артём_   Цитата(Allregia @ Oct 23 2012, 21:23) Это...   Oct 23 2012, 19:06
||- - Allregia   Цитата(_Артём_ @ Oct 23 2012, 21:06) Появ...   Oct 23 2012, 20:00
|- - ReAl   Цитата(Allregia @ Oct 23 2012, 21:23) Т.е...   Oct 23 2012, 20:05
|- - Allregia   Цитата(ReAl @ Oct 23 2012, 22:05) Тем, чт...   Oct 23 2012, 20:18
- - Allregia   Понятно, вначале я включаю приоритеты вызовом NVIC...   Oct 23 2012, 20:47
- - _Артём_   Цитата(Allregia @ Oct 23 2012, 23:47) Пон...   Oct 23 2012, 20:55
- - SSerge   Цитата(_Артём_ @ Oct 24 2012, 03:55) Это ...   Oct 24 2012, 07:30
- - demiurg_spb   Цитата(_Артём_ @ Oct 24 2012, 00:55) Стра...   Oct 24 2012, 12:05


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

 


RSS Текстовая версия Сейчас: 25th August 2025 - 07:46
Рейтинг@Mail.ru


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