Interrupt package пакет работы с прерываниями


Содержание

Какая разница между interrupted() и isInterrupted()

Вроде, оба метода проверяют флаг, хотел ли прервать какой-то поток, тот поток, в котором метод был вызван. Поправьте, если я не прав. Понятно что isInterrupted() не статический и его надо вызывать на объекте типа Thread , а interrupted() статический и можно написать просто Thread.interrupted() . Но в чем все таки разница? И в каком потоке флаг будет проверятся, если мы применяем Thread.interrupted() , имея в виду что к объекту статические методы не привязаны?

2 ответа 2

Достаточно прочитать javadoc

Thread.interrupted() вдобавок к проверке снимает флаг прерывания. thread.isInterrupted() этого не делает, плюс нестатический доступ позволяет проверять другие треды. Фактически, это еще и ограничивает возможность снять флаг прерывания у других тредов (нельзя «украсть» прерывание другого треда).

Метод interrupted является статическим и проверяет был ли установлен флаг прерывания у текущего потока. При этом флаг прерывания после вызова этого метода сбрасывается.

Метод isInterrupted() позволяет проверить флаг прерывания у потока, для которого этот метод был вызван. При этом сам флаг не сбрасывается.

И в каком потоке флаг будет проверятся, если мы применяем Thread.interrupted(), имея в виду что к объекту статические методы не привязаны?

Будет проверен флаг прерывания у текущего потока, в котором и происходит эта проверка.

Arduino.ru

attachInterrupt(interrupt, function, mode)

Задает функцию обработки внешнего прерывания, то есть функция, которая будет вызвана по внешнему прерыванию. Если до это была задана другая функция, то назначается новая. Большинство контроллеров Arduino умеют обрабатывать до двух внешних прерываний, пронумерованных так: 0 (на цифровом порту 2) и 1 (на цифровом порту 3). Arduino Mega обрабатывает дополнительно еще четыра прерывания: 2 (порт 21), 3 (порт 20), 4 (порт 19) и 5 (порт 18).

Плата int.0 int.1 int.2 int.3 int.4 int.5
UNO, Ethernet 2 3
Mega2560 2 3 21 20 19 18
Leonardo 3 2 1 7

Arduino Due имеет мощные возможности обработки прерываний, что позволяет прикрепить функцию прерывания для всех доступных контактов. Вы можете напрямую указать порт(пин) в attachInterrupt ().

Параметры

interrupt: номер прерывания (int)
или pin: номер цифрового порта (только для Arduino Due)

function: функция, вызваемая прерыванием, функция должна быть без параметров и не возвращать значений. В англоязычной документации употребляется термин interrupt service routine для такой функции.

mode задает режим обработки прерывания. Допустимо использование следующих констанст:

  • LOW вызывает прерывание, когда на порту LOW
  • CHANGE прерывание вызывается при смене значения на порту, с LOW на HIGH и наоборот
  • RISING прерывание вызывается только при смене значения на порту с LOW на HIGH
  • FALLING прерывание вызывается только при смене значения на порту с HIGH на LOW

Возвращаемое значение

Замечание по использованию

Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания. Переменные, изменяемые в функции, должным быть объявлены как volatile.

Использование перерываний

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

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

Электроника для всех

Блог о электронике

ARM. Учебный Курс. Прерывания и NVIC — приоритетный контроллер прерываний

Стандартной плюхой ядра Cortex M3 является NVIC — контроллер приоритетных векторных прерываний. Сейчас я разжую что это такое и с чем это едят.

Прерывания и события
Вообще, если пошерстить мануал, то везде при разборе периферии рассматриваются interrupt/event. Может сложиться ощущение, что это одно и то же. Но это не так.

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

Event — это аппаратное событие. Опустел буфер UART — держи event, натикал таймер — еще один event. Событие может вызвать прерывание, может запустить какую-либо периферию, например пнуть DMA, чтобы оно выгрузило данные. Но событие далеко не всегда может вызвать прерывание. Каждое прерывание вызывается событием, но не каждое событие вызывает прерывание. Вот. Так что надо отличать.

Как и в AVR в STM32 существуют вектора прерываний. Это особые адреса, куда контроллер бросается если происходит прерывание. Они записаны в таблицу и располагаются вначале памяти. Впрочем, система гибкая и переконфигурировав NVIC можно засунуть ее куда угодно. Если вы пишите на Си, то по дефолту, в стартовом файле, вектора прерываний забиты затычками которые ведут в бесконечный цикл. Так что если вызывать прерывание не указав ему обработчик контроллер тупо повиснет. Что является максимизацией ошибки и это хорошо.

Таблицу векторов можно подглядеть для конкретного контроллера в STM32F10x.s файле. Идем туда и глядим на вектора, точнее на их имена. Выглядят они примерно так:

; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler ; External Interrupts DCD WWDG_IRQHandler ; Window Watchdog DCD PVD_IRQHandler ; PVD through EXTI Line detect DCD TAMPER_IRQHandler ; Tamper DCD RTC_IRQHandler ; RTC DCD FLASH_IRQHandler ; Flash DCD RCC_IRQHandler ; RCC DCD EXTI0_IRQHandler ; EXTI Line 0 DCD EXTI1_IRQHandler ; EXTI Line 1 DCD EXTI2_IRQHandler ; EXTI Line 2 DCD EXTI3_IRQHandler ; EXTI Line 3 DCD EXTI4_IRQHandler ; EXTI Line 4 DCD DMAChannel1_IRQHandler ; DMA Channel 1 DCD DMAChannel2_IRQHandler ; DMA Channel 2 DCD DMAChannel3_IRQHandler ; DMA Channel 3 DCD DMAChannel4_IRQHandler ; DMA Channel 4 DCD DMAChannel5_IRQHandler ; DMA Channel 5 DCD DMAChannel6_IRQHandler ; DMA Channel 6 DCD DMAChannel7_IRQHandler ; DMA Channel 7 DCD ADC_IRQHandler ; ADC DCD USB_HP_CAN_TX_IRQHandler ; USB High Priority or CAN TX DCD USB_LP_CAN_RX0_IRQHandler ; USB Low Priority or CAN RX0 DCD CAN_RX1_IRQHandler ; CAN RX1 DCD CAN_SCE_IRQHandler ; CAN SCE DCD EXTI9_5_IRQHandler ; EXTI Line 9..5 DCD TIM1_BRK_IRQHandler ; TIM1 Break DCD TIM1_UP_IRQHandler ; TIM1 Update DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare DCD TIM2_IRQHandler ; TIM2 DCD TIM3_IRQHandler ; TIM3 DCD TIM4_IRQHandler ; TIM4 DCD I2C1_EV_IRQHandler ; I2C1 Event DCD I2C1_ER_IRQHandler ; I2C1 Error DCD I2C2_EV_IRQHandler ; I2C2 Event DCD I2C2_ER_IRQHandler ; I2C2 Error DCD SPI1_IRQHandler ; SPI1 DCD SPI2_IRQHandler ; SPI2 DCD USART1_IRQHandler ; USART1 DCD USART2_IRQHandler ; USART2 DCD USART3_IRQHandler ; USART3 DCD EXTI15_10_IRQHandler ; EXTI Line 15..10 DCD RTCAlarm_IRQHandler ; RTC Alarm through EXTI Line DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend AREA |.text|, CODE, READONLY

Как видно, тут все написано почти человеческим языком и особо пояснять то ничего не требуется. Все итак понятно. Обращу лишь внимание на то, что вначале идут так называемые Fault Interrupt
это

__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler

Прерывания ядра. Которые имеют наивысший приоритет и не подчиняются команде общего запрета/разрешения прерываний:
Для них свой флажок и своя команда:

Обработчик прерывания
Теперь, если нам потребуется создать обработчик прерывания. Допустим для внешнего прерывания по изменению состояния вывода EXTI1 мы должны будем нарисовать в коде вот такую конструкцию:

// Int Vectors void EXTI1_IRQHandler(void)

Собственно обработчик готов, можем писать туда всякую каку.

Разрешение прерываний
Для разрешения прерываний надо сделать три вещи:

  • Разрешить глобальные прерывания
  • Разрешить нужное прерывание в NVIC
  • Настроить и разрешить конкретные прерывания непосредственно в периферии. Т.е. настроить нужные events на прерывания.

А теперь по порядку.

Разрешение глобальных прерываний
Это просто, достаточно всего лишь поставить флажок состояния процессора. В CMSIS за это отвечает крошечная функция

Разрешить прерывания в NVIC
Настройка прерываний в NVIC чуть более сложное дело, но не намного. Описание на NVIC можно найти в файле PM0056 STM32F10xxx Cortex-M3 programming manual. Там описывается только то, что есть в ядре Cortex M3. Можно конечно открыть более общее описание, взятое с сайта ARM. Но там будут небольшие отличия. Например, у STM32 урезана система группировки приоритетов. И другие мелочи. Но в целом все похоже.

За работу с прерываниями в NVIC отвечают несколько регистров. Вот они все указаны в таблице 41

  • ISER — Interrupt Set Enable Register. Запись бита в нужную позицию включает прерывание.
  • ICER — Interrupt Clr Enable Register. Запись сюда наоборот выключает прерывание.

Запись 1 в биты этих регистров запрещает/разрешает прерывания. Запись 0 не делает ничего, а чтение возвращает текущее состояние разрешено/запрещено

  • ISPR — Interrupt Set Pending Register. Поставить прерывание в ожидание.
  • IСPR — Interrupt Clr Pending Register. Сбросить прерывание с ожидания.

Запись 1 в биты этих регистров ставит/снимает прерывания в очередь на исполнение. Запись 0 не делает ничего, а чтение возвращает текущее состояние прерывания. Ждет он обработки или уже нет. Т.е. если в этом регистре где то стоит бит 1, значит это прерывание еще не вызывалось.

  • IABR — Interrupt active bit registers. Регистр показывающий активно ли в данный момент прерывание. Автоматически ставится когда мы попадаем в обработчик и автоматом же снимается когда мы уходим из него. Этот регистр можно только читать.


Да, но тут возникает вопрос. Прерывания то у нас все именные. Таймер там, UART еще что то. А тут какие то номера? Где узнать у какого прерывания какой номер? А все в той же таблице векторов, что я привел в самом начале. Пропускаем FAULT INTERRUPT и начиная с

; External Interrupts DCD WWDG_IRQHandler ; Window Watchdog Номер 0 DCD PVD_IRQHandler ; PVD through EXTI Line detect Номер 1 DCD TAMPER_IRQHandler ; Tamper Номер 2 DCD RTC_IRQHandler ; RTC Номер 3 .

И так далее до конца. Ну, а номер регистра выбираем исходя из того, что в один регистр влазит всего 32 бита. А еще, в составе CMSIS есть удобные функции для руления NVIC контроллером. Они стандартные для всех МК на Cortex M3.

void NVIC_EnableIRQ(IRQn_t IRQn) // Enable IRQn void NVIC_DisableIRQ(IRQn_t IRQn) // Disable IRQn

Одна запрещает, другая разрешает. Все просто :)

NVIC_EnableIRQ (EXTI1_IRQn); // Разрешить прерывание EXTI1 в NVIC

Там же есть функции для остальных ковыряний с NVIC. Вот весь список:

void NVIC_SetPriorityGrouping(uint32_t priority_grouping) // Задать группы/подгруппы приоритетов void NVIC_EnableIRQ(IRQn_t IRQn) // Включить IRQn void NVIC_DisableIRQ(IRQn_t IRQn) // Выключить IRQn uint32_t NVIC_GetPendingIRQ (IRQn_t IRQn) // Вернуть true (точнее IRQ-Number) если IRQn в ожидании void NVIC_SetPendingIRQ (IRQn_t IRQn) // Поставить IRQn в ожидание void NVIC_ClearPendingIRQ (IRQn_tIRQn) // Выкинуть из очереди на ожидание IRQn uint32_t NVIC_GetActive (IRQn_t IRQn) // Функция «Бля, где это я?» Возвращает номер текущего активного прерывания если такое имеется void NVIC_SetPriority (IRQn_t IRQn, uint32_t priority) // Задать приоритет IRQn uint32_t NVIC_GetPriority (IRQn_t IRQn) // Считать приоритет IRQn void NVIC_SystemReset (void) // Reset the system

Настройка прерывания в периферии
Тут надо смотреть конкретную периферию и какие биты за что отвечают. Обычно есть бит события, например, есть у UART бит события TXE, а для включения прерывания на это событие есть бит конфигурации TXEIE. Вообще это характерно, что есть какой то event, а бит разрешения прерывания для него зовется как [чето там]IE.

Для примера далеко ходить не буду и покажу разрешение прерываний для входов внешних прерываний — EXTI. Подробно про EXTI и его настройку я расскажу в следующих статьях.

// Разрешаем прерывания в периферии для выводов 1 и 2. EXTI->IMR |=(EXTI_IMR_MR1 | EXTI_IMR_MR2);

Все, теперь прерывание активно и работает.

Особенности обработки прерываний
При написании обработчика есть ряд тонких моментов. Дело в том, что тут, в отличии от AVR далеко не все флаги событий снимаются аппаратно при переходе по вектору. ОЧЕНЬ часто флаг события надо сбрасывать вручную. Иначе при выходе из прерывания оно тутже сгенерится вновь и мы снова окажемся в обработчике. Причем это НЕ ОТНОСИТСЯ к Pendind флагам NVIC. Сие сбрасывается на периферии и только там.

Для EXTI, после того как я обслужил это прерывание, я делаю сброс флага события в блоке прерываний EXTI:

// Сброс флага события EXTI->PR |= EXTI_PR_PR2;

Конкретно по флагам событий и тому как они сбрасываются надо внимательно читать описания битов в User Manual. Там обычно описано чем бит ставится и чем сбрасывается.

Приоритеты прерываний
NVIC же приоритетный контроллер. Но что то никто на это, как я погляжу, не заморачивается особо. Как лепили одноранговые прерывания на AVR так и тут лепят.

По дефолту более высокий уровень приоритета имеют только группа FIQ. У остальных же он одинаковый. Как на AVR. Т.е. кто раньше встал — того и тапки. Одноранговое прерывание не может перебить другое такое же. А если случилось так, что несколько прерываний встали на ожидание, но не смогли пойти на выполнение (т.к., например, был глобальный запрет, либо выполнялось прерывание), то как только появится возможность первым пойдет то прерывание, чей номер в таблице векторов меньше. Ну как на AVR.

Но все можно изменить! :)

За приоритет отвечает группа регистров IPRx всего их там двадцать (но вообще может быть до 60). В каждом регистре по четыре 8 битных поля, каждое поле отвечает за один вектор. От 0 (помним, что номера считаются от External Interrupt, исключая FIQ группу) до 80. Конечно у STM32 нет 80 векторов, это число взято с запасом. В IRP0 лежат приоритеты с 0 по 3 вектор, в IRP1 с 4 по 7 и так далее до 80го.

Поле приоритета 8ми разрядное. Значит теоретически приоритетов может быть 256 штук. Но это только в теории, это возможности ядра в принципе. А конкретно в STM32F103 реально рулят только старшие 4ре бита. Образуя таким образом 16 уровней приоритетов. Чем меньше номер уровня, тем он главней. После RESET у всех 0000 т.е. полная анархия.

Байт приоритета можно вкатить вручную, засунув его в старшую тетраду нужного поля, но куда наглядней вызвать функцию CMSIS, например так:

//Понижаем приоритет прерыванию EXTI2 NVIC_SetPriority (EXTI2_IRQn, 2);

Прерывания группы FIQ (не все, но многие) тоже позволяют менять приоритет. Но это в другом месте. Ищите в документации на ядро описание System handler priority registers (SHPRx)

Прерывание с большим приоритетом невозбранно может прерывать более стремные прерывания. И таким образом мы имеем 16 цветов штанов. А потом матрешка разворачивается в обратном направлении. Чтобы это наглядно показать я накатал прогу с кнопочками и реагирующими на них прерываниями. В обработчиках яростно дрыгало ногами. Это все я сгрузил на логический анализатор

Вот, парочка примеров:
Два равных прерывания пришли с перехлестом:

А вот более важное перебивает низкоприоритетное:

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

Приоритет группы определяет то может ли одно прерывание перебивать другое. Скажем прерывания группы 0 легко забирают управление у прерываний группы 1. А группа 1 так сделать не может ибо лох.

А в каждой группе возникают подгруппы приоритетов. Они уже решают кто пойдет первым если одновременно придут на исполнение два прерывания из одной группы. Но перебивать друг друга прерывания из одной подгруппы уже не могут. А если одновременно придут два прерывания из одной группы и одной подгруппы, то вызов пойдет по порядку их описания в таблице векторов.

Т.е. число в PRIGROUP определят как бы положение десятичной точки, которое разделяет поле IRP на биты разделяющие группу и подгруппу. 0 — точка перед нулевым битом, 128 групп и 2 подгруппы. 1 — точка стоит перед первым битом, имеем 6 бит на группы и два на подгруппы. Т.е. 64 группы и 4 подгруппы. И так далее.

Но У STM32 поле IPR всего 4 разрядное, только старшие биты. Потому PRIGROUP имеет смысл только с 3 до 7.

Выбрав, например, PRIGROUP = 5 мы получим, что у поля IPR старшая тетрада, что отвечает за приоритет, разобьется еще на два поля. Старшие два бита будут определять группу, а младшие подгруппу. Чем меньше номер группы тем она главней.

Слайды давай! Слайды!
А теперь пример. Простенький такой.
Создадим такую программу:

  • Фоновая задача моргает диодом LED3
  • Прерывание EXTI2 имеет приоритет 2 и моргает диодом LED1
  • Прерывание EXTI1 имеет приоритет 0 моргает диодом LED0

Двумя кнопками мы замыкаем выводы B00 и B01 на землю, вызывая срабатывания прерываний по изменению уровня и пыримся на светодиоды, наблюдая как оно работает. В обработчики прерываний я запихал здоровенные циклы с задержками. Это термоядерный быдлокод. Так делать нельзя, прерывания должны отрабатываться как можно быстрей, но иначе по простому не увидеть как это все работает.

#include «stm32f10x.h» #define F_CPU 72000000UL vo >BSRR = GPIO_BSRR_BS0; // Сбросили бит. Delay(55560); GPIOB->BSRR = GPIO_BSRR_BR0; // Установили бит. Delay(55560); > // Сбрасываем флаг прерывания EXTI->PR |= EXTI_PR_PR1; > // Обработчик EXTI 2 vo >BSRR = GPIO_BSRR_BS1; // Сбросили бит. Delay(55560); GPIOB->BSRR = GPIO_BSRR_BR1; // Установили бит. Delay(55560); > // Сбрасываем флаг прерывания EXTI->PR |= EXTI_PR_PR2; > int main(void) < // Запускаем конфигуратор тактовой частоты из CMSIS SystemInit(); RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN; // Подаем тактирование на порт А и В // Настройка выходных портов. Те, что на светодиоды. // Конфигурируем CRL регистры. // Сбрасываем биты CNF для битов 3,4,5. Режим 00 — Push-Pull GPIOB->CRL &=

(GPIO_CRL_CNF5 | GPIO_CRL_CNF1 | GPIO_CRL_CNF0); // Выставляем режим для 0,1,5 пина. Режим MODE 01 = Max Speed 10MHz Ставим нулевой бит MODE GPIOB->CRL &=

(GPIO_CRL_MODE5 | GPIO_CRL_MODE1 | GPIO_CRL_MODE0); // Занулим заранее GPIOB->CRL |= GPIO_CRL_MODE5_0 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE0_0; // Выставим бит 0 // Настройка входных портов. Те что на кнопки. // Конфигурируем CRL регистры. // Выставляем режим порта в CNF для битов 1,2 Режим 10 = PullUp(Down) Ставим первый бит CRL GPIOA->CRL &=

(GPIO_CRL_CNF1 | GPIO_CRL_CNF2); // Занулим заранее GPIOA->CRL |= GPIO_CRL_CNF1_1 | GPIO_CRL_CNF2_1; // Выставим бит 1 // Выставляем режим для 1,2 пина. Режим MODE_00 = Input GPIOA->CRL &=

(GPIO_CRL_MODE1 | GPIO_CRL_MODE2); // Установили бит 1,2 в ODR включив PULL UP. GPIOA->BSRR = GPIO_BSRR_BS2 | GPIO_BSRR_BS1; // Настраиваем EXTI1 и EXTI2 на выводы порта А AFIO->EXTICR[1] |= AFIO_EXTICR1_EXTI1_PA | AFIO_EXTICR1_EXTI2_PA ; // Прерывание по падению уровня на ноге 1 и 2 порта привязанного к EXTI EXTI->FTSR |=(EXTI_FTSR_TR1 | EXTI_FTSR_TR2); // Функции CMSIS разрешающие прерывания в NVIC NVIC_EnableIRQ (EXTI1_IRQn); NVIC_EnableIRQ (EXTI2_IRQn); //Расставляем приоритеты (опционально, можно закомментить и тогда приоритеты будут равны) NVIC_SetPriority (EXTI2_IRQn, 2); // Разрешаем прерывания в периферии EXTI->IMR |=(EXTI_IMR_MR1 | EXTI_IMR_MR2); // Разрешаем глобальные прерывания __enable_irq (); //Фоновая программа while(1) < GPIOB->BSRR = GPIO_BSRR_BR5; // Сбросили бит. Delay(55560); GPIOB->BSRR = GPIO_BSRR_BS5; // Установили бит. Delay(55560); > > /* Тупая задержка */ vo , file, line) */ /* Infinite loop */ while (1) < >> #endif

Схема включения простая. На порты B03, B00 и B01 вешаем диоды. На порты A01 и A02 кнопки. На демоплате Pinboard все видно наглядно. Главное правильно сконфигурировать кнопочную матрицу.

Ну и киношка того как это работает в реале.

Почему на компьютере запущен процесс System Interrupts – как отключить

Если вы когда-либо заходили в диспетчер задач, вероятно, замечали процесс под названием «System Interrupts». Если Вам интересно, зачем он использует ваш процессор, то мы готовы дать Вам ответ.

Что такое процесс System Interrupts

System Interrupts является официальной частью Windows, и, хотя он отображается в списке процессов Диспетчера задач, это не совсем процесс в традиционном смысле. Скорее, это заполнитель, используемый для отображения системных ресурсов, используемых всеми аппаратными прерываниями, происходящими на вашем ПК.

Хотя «аппаратное прерывание» звучит грубо – это стандартная система связи между вашим оборудованием (и сопряженным программным обеспечением) и вашим процессором.

Скажем, вы начинаете печатать что-то на клавиатуре. Вместо того, чтобы отдавать целый процесс на отслеживание сигналов от клавиатуры, материнская плата, которая обрабатывает такого рода сигналы, действует по-другому. Когда она «замечает» что другое устройство нуждается во внимании процессора, то передает сигнал прерывания к процессору. Если это прерывание с высоким приоритетом (как это обычно бывает с пользовательским вводом), процессор приостанавливает любой другой процесс, над которым работает, обрабатывает прерывание, а затем возобновляет свой предыдущий процесс.

Всё это происходит молниеносно. Но, Вы даже можете увидеть этот процесс в действии. Запустите Диспетчер задач и прокрутите вниз, пока не увидите «System Interrupts». Теперь откройте блокнот и начните печатать. Вы увидите всплески потребления ресурсов процессора, как правило, на десятую часть процентного пункта или около того.

Во время обычных операций вы можете увидеть, что использование ЦП «System interrupts» ненадолго поднимается до 10%.

Почему System interrupts использует много ресурсов

Если вы видите, что System interrupts использует процессор более чем на 20% и – это главное – остаётся на таком уровне постоянно, то у вас проблемы. Так как стабильно высокая загрузка центрального процессора означает, что часть оборудования или связанный с ним драйвер «плохо себя ведёт».

Как устранить проблему с оборудованием? Это и есть сложная часть.

Первым шагом должна быть перезагрузка компьютера. Мы знаем, что вы слышали это миллион раз, но этот совет всё ещё самый актуальный. Перезапуск компьютер может исправить большинство проблем с работой оборудования, и это достаточно легкий шаг, чтобы его выполнить.


Если перезагрузка компьютера не устранит проблему использования ЦП, следующий шаг – проверить актуальность установленных обновлений на компьютере. Пусть Центр обновления Windows сделает своё дело, так Вы будете уверены, что получили все последние обновления Windows и драйверов (по крайней мере, драйверов, которыми управляет Windows).

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

Начните с отключения внешних устройств по одному, таких как клавиатура, мышь, веб-камера и микрофон. Просто отключите их по одному и посмотреть, как это влияет на работу System interrupts.

Затем перейдите к внутренним устройствам. Очевидно, это немного сложнее, так как не всегда их можно просто отключить. Но вы можете отключить их через диспетчер устройств. Однако, нужно быть осторожными, чтобы не отключить устройства, критически важные для поддержания работы вашей системы, такие как жесткие диски или адаптеры дисплея. Кроме того, не отключайте ничего из перечисленного в категориях компьютер, процессоры или системные устройства. Сосредоточьтесь на сетевых адаптерах, звуковых картах и других дополнительных картах. Они является наиболее вероятными виновниками проблем.

Неотключаемое оборудование также может вызывать проблемы, но можно проверить другим путём. Сбой питания (или проблемы батареи ноутбука) может вызвать всплеск использования центрального процессора, как и отказ жесткого диска. Вы можете проверить свои жесткие диски встроенным инструментом Windows или хорошей сторонней S.M.A.R.T. утилитой. К сожалению, единственный способ проверить источник питания – заменить его.

Если вы определили устройство, которое вызывает проблемы, следующий шаг – выяснить, вызывает ли проблему само устройство или драйвер оборудования.

Опять же, это немного сложно понять и потребует некоторых проб и ошибок, но у нас есть некоторые рекомендации:

  • Попробуйте использовать внешние устройства на другом компьютере.
  • Если Вы абсолютно уверены в самом устройстве, то попробуйте откат драйвера к более ранней версии.
  • Воспользуйтесь поиском или зайдите на веб-сайт производителя оборудования и посмотрите, имеют ли другие люди имеют аналогичные проблемы.
  • Рассмотрите возможность обновление BIOS – это иногда помогает решить проблему.

Можно ли отключить System interrupts

Нет, System interrupts отключать нельзя. И тому нет никаких веских причин. Это жизненно важный компонент для производительности вашего компьютера, так как он используется для обработки аппаратных прерываний. Windows не позволит даже временно завершить задачу.

Может ли System interrupts быть вирусом

System interrupts является официальным компонентом Windows. Это почти наверняка не вирус. Поскольку это даже не процесс, System interrupts не имеет связанного .EXE или .DLL файла.

Тем не менее, возможно, что вирус вмешивается в конкретный драйвер оборудования, который, в свою очередь, может повлиять на System interrupts.

Сетевые адаптеры настройки производительности Performance Tuning Network Adapters

Относится к: Windows Server (Semi-Annual Channel), Windows Server 2020 Applies to: Windows Server (Semi-Annual Channel), Windows Server 2020

Этот раздел можно использовать для настройки производительности сетевых адаптеров, установленных на компьютерах под управлением Windows Server 2020. You can use this topic to performance tune network adapters that are installed in computers that are running Windows Server 2020.

Определение правильных настроек для сетевого адаптера зависит от следующих факторов: Determining the correct tuning settings for your network adapter depend on the following variables:

сетевой адаптер и набор его функций; The network adapter and its feature set

тип рабочей нагрузки, выполняемой сервером; The type of workload performed by the server

аппаратные и программные ресурсы сервера; The server hardware and software resources

задачи настройки сервера. Your performance goals for the server

Если сетевой адаптер предоставляет возможности настройки, то на основании приведенных выше факторов можно оптимизировать пропускную способность сети и использование ресурсов. If your network adapter provides tuning options, you can optimize network throughput and resource usage to achieve optimum throughput based on the parameters described above.

В следующих разделах описывается ряд параметров настройки производительности. The following sections describe some of your performance tuning options.

Включение функций разгрузки Enabling Offload Features

Включение функций разгрузки на сетевом адаптере обычно имеет положительный эффект. Turning on network adapter offload features is usually beneficial. Однако иногда сетевой адаптер недостаточно производителен, чтобы осуществлять функции разгрузки с высокой пропускной способностью. Sometimes, however, the network adapter is not powerful enough to handle the offload capabilities with high throughput.

Не используйте разгрузку задач IPSec функции разгрузки или разгрузку TCP Chimney. Do not use the offload features IPsec Task Offload or TCP Chimney Offload. Эти технологии являются устаревшими в Windows Server 2020 и могут негативно сказаться на производительности сервера и сети. These technologies are deprecated in Windows Server 2020, and might adversely affect server and networking performance. Кроме того, эти технологии могут не поддерживаться корпорацией Майкрософт в будущем. In addition, these technologies might not be supported by Microsoft in the future.

Например, включение разгрузки сегментации может снизить максимальную устойчивую пропускную способность некоторых сетевых адаптеров из-за ограниченности аппаратных ресурсов. For example, enabling segmentation offload can reduce the maximum sustainable throughput on some network adapters because of limited hardware resources. Однако если снижение пропускной способности не будет ограничением, функции разгрузки рекомендуется включать даже для подобных сетевых адаптеров. However, if the reduced throughput is not expected to be a limitation, you should enable offload capabilities, even for this type of network adapter.

В некоторых сетевых адаптерах функции разгрузки нужно включать по отдельности для пути отправки и приема. Some network adapters require offload features to be independently enabled for send and receive paths.

Включение масштабирования на стороне приема (RSS) для веб-серверов Enabling Receive Side Scaling (RSS) for Web Servers

RSS способно повысить веб-масштабируемость и производительность, когда число сетевых адаптеров меньше количества логических процессоров на сервере. RSS can improve web scalability and performance when there are fewer network adapters than logical processors on the server. Когда весь веб-трафик проходит через сетевые адаптеры с поддержкой RSS, входящие веб-запросы из разных соединений могут одновременно обрабатываться разными ЦП. When all the web traffic is going through the RSS-capable network adapters, incoming web requests from different connections can be simultaneously processed across different CPUs.

Важно отметить, что из-за логики в протоколе (RSS и HTTP) для распределения нагрузки производительность может быть значительно снижена, если сетевой адаптер, не поддерживающий RSS, принимает веб-трафик на сервере, который имеет один или другие сетевые адаптеры с поддержкой RSS. It is important to note that due to the logic in RSS and Hypertext Transfer Protocol (HTTP) for load distribution, performance might be severely degraded if a non-RSS-capable network adapter accepts web traffic on a server that has one or more RSS-capable network adapters. В этом случае необходимо использовать сетевые адаптеры, поддерживающие RSS, или отключить RSS на вкладке Дополнительные свойства в свойствах сетевого адаптера. Чтобы определить, поддерживает ли сетевой адаптер RSS, можно просмотреть сведения RSS на вкладке Дополнительные свойства в свойствах сетевого адаптера. In this circumstance, you should use RSS-capable network adapters or disable RSS on the network adapter properties Advanced Properties tab. To determine whether a network adapter is RSS-capable, you can view the RSS information on the network adapter properties Advanced Properties tab.

Профили RSS и очереди RSS RSS Profiles and RSS Queues

Стандартный профиль RSS по умолчанию — NUMA static, который изменяет поведение по умолчанию из предыдущих версий операционной системы. The default RSS predefined profile is NUMA Static, which changes the default behavior from previous versions of the operating system. Чтобы приступить к работе с профилями RSS, можно ознакомиться с доступными профилями, чтобы понять, когда они будут полезны и как их можно применять к своей сети или оборудованию. To get started with RSS Profiles, you can review the available profiles to understand when they are beneficial and how they apply to your network environment and hardware.

Например, откройте диспетчер задач и просмотрите логические процессоры на сервере. Если они недостаточно загружены приемом трафика, можно попробовать увеличить число очередей RSS со значения 2 (по умолчанию) до максимального, которое поддерживается сетевым адаптером. For example, if you open Task Manager and review the logical processors on your server, and they seem to be underutilized for receive traffic, you can try increasing the number of RSS queues from the default of 2 to the maximum that is supported by your network adapter. В используемом сетевом адаптере могут быть параметры для изменения числа очередей RSS в драйвере. Your network adapter might have options to change the number of RSS queues as part of the driver.

Увеличение ресурсов сетевого адаптера Increasing Network Adapter Resources

Для сетевых адаптеров, которые позволяют вручную настраивать ресурсы, например буферы приема и передачи, следует увеличить выделение ресурсов. For network adapters that allow manual configuration of resources, such as receive and send buffers, you should increase the allocated resources.

В некоторых сетевых адаптерах устанавливаются небольшие буферы приема для экономии выделенной памяти от узла. Some network adapters set their receive buffers low to conserve allocated memory from the host. Это ведет к потере пакетов и снижению производительности. The low value results in dropped packets and decreased performance. Поэтому для сценариев с интенсивным приемом рекомендуется увеличить буфер приема до максимума. Therefore, for receive-intensive scenarios, we recommend that you increase the receive buffer value to the maximum.

Если сетевой адаптер не позволяет настраивать ресурсы вручную, он либо настраивает их динамически, либо параметры ресурсов являются фиксированными. If a network adapter does not expose manual resource configuration, it either dynamically configures the resources, or the resources are set to a fixed value that cannot be changed.

Включение управления прерываниями Enabling Interrupt Moderation

Для прерываний в некоторых сетевых адаптерах предлагаются различные уровни управления прерываниями, параметры объединения буферов (иногда отдельно для буфера приема и передачи) или оба варианта. To control interrupt moderation, some network adapters expose different interrupt moderation levels, buffer coalescing parameters (sometimes separately for send and receive buffers), or both.

Управление прерываниями имеет смысл применять для рабочих нагрузок, связанных с ЦП, также следует учитывать баланс между экономией процессорных ресурсов узла и задержкой и увеличением экономии процессорных ресурсов узла за счет большего числа прерываний и снижения задержки. You should consider interrupt moderation for CPU-bound workloads, and consider the trade-off between the host CPU savings and latency versus the increased host CPU savings because of more interrupts and less latency. Если сетевой адаптер не ведет управление прерываниями, но позволяет объединять буферы, то увеличение числа объединенных буферов для приема и передачи повышает общую производительность. If the network adapter does not perform interrupt moderation, but it does expose buffer coalescing, increasing the number of coalesced buffers allows more buffers per send or receive, which improves performance.

Настройка производительности для обработки пакетов с низкой задержкой Performance Tuning for Low Latency Packet Processing

Многие сетевые адаптеры позволяют настраивать параметры для оптимизации системной задержки. Many network adapters provide options to optimize operating system-induced latency. Задержка — это время между обработкой входящего пакета сетевым драйвером и отправкой этого пакета обратно. Latency is the elapsed time between the network driver processing an incoming packet and the network driver sending the packet back. Обычно это время измеряется в микросекундах. This time is usually measured in microseconds. Для сравнения, время передачи для передачи пакетов на больших расстояниях обычно измеряется в миллисекундах (в порядке увеличения.) For comparison, the transmission time for packet transmissions over long distances is usually measured in milliseconds (an order of magnitude larger). Эта настройка не сокращает время прохождения пакета. This tuning will not reduce the time a packet spends in transit.

Ниже приведены некоторые советы по настройке производительности для загруженных сетей, в которых на счету каждая микросекунда. Following are some performance tuning suggestions for microsecond-sensitive networks.

В BIOS компьютера установите значение High Performance (Высокая производительность) и отключите C-состояния. Set the computer BIOS to High Performance, with C-states disabled. Однако имейте в виду, что это зависит от системы и BIOS, и некоторые системы обеспечивают большую производительность, если операционная система управляет электропитанием. However, note that this is system and BIOS dependent, and some systems will provide higher performance if the operating system controls power management. Проверить и настроить параметры управления питанием можно на странице Параметры или с помощью команды powercfg . You can check and adjust your power management settings from Settings or by using the powercfg command. Дополнительные сведения см. в разделе Параметры командной строки Powercfg . For more information, see Powercfg Command-Line Options

Установите в операционной системе профиль управления электропитанием Высокая производительность. Set the operating system power management profile to High Performance System. Имейте в виду, что он не будет работать надлежащим образом, если в BIOS компьютера отключен контроль операционной системы над управлением электропитанием. Note that this will not work properly if the system BIOS has been set to disable operating system control of power management.

Включите статические разгрузки, например контрольные суммы UDP, контрольные суммы TCP и разгрузки большой отправки (LSO). Enable Static Offloads, for example, UDP Checksums, TCP Checksums, and Send Large Offload (LSO).

Включите RSS, если трафик передается несколькими потоками, например при масштабной многоадресной рассылке. Enable RSS if the traffic is multi-streamed, such as high-volume multicast receive.

Отключите Управление прерываниями в драйверах сетевых адаптеров, которым требуется самая низкая задержка. Disable the Interrupt Moderation setting for network card drivers that require the lowest possible latency. Помните, что оно может привести к увеличению загрузки процессора, таким образом это решение является компромиссом. Remember, this can use more CPU time and it represents a tradeoff.

Обрабатывайте прерывания сетевого адаптера и DPC на основном процессоре, который совместно использует процессорный кэш с ядром, которое используется программой (пользовательским потоком), обрабатывающей пакет. Handle network adapter interrupts and DPCs on a core processor that shares CPU cache with the core that is being used by the program (user thread) that is handling the packet. Для передачи процесса конкретным логическим процессорам можно использовать настройку фиксации ЦП вместе с настройкой RSS. CPU affinity tuning can be used to direct a process to certain logical processors in conjunction with RSS configuration to accomplish this. Использование одного ядра для прерываний, DPC и пользовательского потока ведет к снижению производительности из-за увеличения нагрузки, поскольку ISR, DPC и поток будут конкурировать за ядро. Using the same core for the interrupt, DPC, and user mode thread exhibits worse performance as load increases because the ISR, DPC, and thread contend for the use of the core.

Прерывания управления системой System Management Interrupts

(Многие аппаратные системы используют прерывания SMI) для различных функций обслуживания, включая отчеты об ошибках кода (коррекции ошибок ECC) , устаревшие совместимость с USB, Вентилятор Управление питанием и управляемой BIOS. Many hardware systems use System Management Interrupts (SMI) for a variety of maintenance functions, including reporting of error correction code (ECC) memory errors, legacy USB compatibility, fan control, and BIOS controlled power management.

Прерывание SMI имеет наивысший приоритет в системе и переводит ЦП в режим управления, который блокирует все другие действия, пока выполняется процедура служебного прерывания, обычно находящаяся в BIOS. The SMI is the highest priority interrupt on the system and places the CPU in a management mode, which preempts all other activity while it runs an interrupt service routine, typically contained in BIOS.

К сожалению, это может приводить к скачкообразному росту задержки до 100 микросекунд и выше. Unfortunately, this can result in latency spikes of 100 microseconds or more.

Когда необходимо обеспечить минимальную задержку, следует запросить у поставщика оборудования версию BIOS, в которой прерывания SMI имеют наименьший возможный приоритет. If you need to achieve the lowest latency, you should request a BIOS version from your hardware provider that reduces SMIs to the lowest degree possible. Обычно их называют «BIOS низкой задержки» или «BIOS без SMI». These are frequently referred to as “low latency BIOS” or “SMI free BIOS.” В некоторых случаях аппаратная платформа не может полностью устранить операции SMI, поскольку они используются для управления важными функциями (например для вентиляторов). In some cases, it is not possible for a hardware platform to eliminate SMI activity altogether because it is used to control essential functions (for example, cooling fans).

Операционная система не имеет контроля над SMI, потому что логический процессор работает в особом служебном режиме, который блокирует вмешательство операционной системы. The operating system can exert no control over SMIs because the logical processor is running in a special maintenance mode, which prevents operating system intervention.


Настройка производительности TCP Performance Tuning TCP

Настройку производительности TCP можно проводить с помощью следующих элементов. You can performance tune TCP using the following items.

Автоматическая настройка окна приема TCP TCP Receive Window Auto-Tuning

До выхода Windows Server 2008 в сетевом стеке использовалось окно приема фиксированного размера (65 535 байт), которое ограничивает общую возможную пропускную способность для подключений. Prior to Windows Server 2008, the network stack used a fixed-size receive-side window (65,535 bytes) that limited the overall potential throughput for connections. Одним из самых существенных изменений в реализации стека TCP стало появление автонастройки окна получения TCP. One of the most significant changes to the TCP stack is TCP receive window auto-tuning.

При использовании окна приема TCP фиксированного размера можно вычислить общую пропускную способность отдельного соединения: You can calculate the total throughput of a single connection when you use a fixed size TCP receive window as:

Общая пропускная способность в байтах = размер окна приема TCP * в байтах (1/задержка подключения в секундах) Total achievable throughput in bytes = TCP receive window size in bytes * (1 / connection latency in seconds)

Например, общая доступная пропускная способность составляет всего 51 Мбит/с при подключении с 10 (МС по разумному значению для большой корпоративной)сетевой инфраструктуры. For example, the total achievable throughput is only 51 Mbps on a connection with 10 ms latency (a reasonable value for a large corporate network infrastructure).

Однако при автонастройке окно получения регулируется и может вырастать в соответствии с требованиями отправителя. With auto-tuning, however, the receive-side window is adjustable, and it can grow to meet the demands of the sender. Подключение может обеспечить полную скорость линии для подключения 1 Гбит/с. It is possible for a connection to achieve a full line rate of a 1 Gbps connection. Сценарии использования сети, которые в прошлом могли быть ограничены общей достижимой пропускной способностью TCP-соединений, теперь могут использовать сеть в полной мере. Network usage scenarios that might have been limited in the past by the total achievable throughput of TCP connections can now fully use the network.

Устаревшие параметры TCP Deprecated TCP parameters

Следующие параметры реестра из Windows Server 2003 больше не поддерживаются и не учитываются в более поздних версиях. The following registry settings from Windows Server 2003 are no longer supported, and are ignored in later versions.

Все эти параметры имеют следующее расположение реестра: All of these settings had the following registry location:

Платформа фильтрации Windows Windows Filtering Platform

Платформа фильтрации Windows (WFP), появившаяся в Windows Vista и Windows Server 2008, предоставляет API независимым поставщикам программного обеспечения (ISV) для создания фильтров обработки пакетов. The Windows Filtering Platform (WFP) that was introduced in Windows Vista and Windows Server 2008 provides APIs to non-Microsoft independent software vendors (ISVs) to create packet processing filters. Например, для брандмауэров и антивирусного ПО. Examples include firewall and antivirus software.

Плохо написанный фильтр WFP может значительно снизить производительность сети сервера. A poorly written WFP filter can significantly decrease a server’s networking performance. Дополнительные сведения см. в разделе Перенос драйверов и приложений для обработки пакетов в WFP в центре разработки для Windows. For more information, see Porting Packet-Processing Drivers and Apps to WFP in the Windows Dev Center.

Ссылки на все разделы данного руководства см. в разделе Настройка производительности сетевой подсистемы. For links to all topics in this guide, see Network Subsystem Performance Tuning.

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 18. Система прерываний STM32. Организация и управление прерываниями.

В уроке изучим систему прерываний микроконтроллеров STM32. Разберемся, как управлять ей, как организовывать обработку аппаратных прерываний.

Не получается рассказывать дальше про таймеры STM32 без знаний о том, как организовывать и использовать прерывания. Поэтому я на один урок прерву представление информации о работе с таймерами и расскажу об организации прерываний в системе STM32.

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

Аппаратные прерывания и события.

Аппаратное прерывание это сигнал, сообщающий о каком-то событии. По его приходу выполнение программы приостанавливается, и управление переходит на функцию обработки прерывания (обработчик прерывания). После отработки функции управление возвращается в прерванный код программы.

С точки зрения программы прерывание это вызов функции по внешнему, не связанному напрямую с программным кодом, событию.

При определении понятия “прерывание” я употребил слово “событие” в общепринятом значении. Т.е. происшествие, нечто случившееся. Но в системе STM32 наряду с прерыванием (interrupt) существует еще одно строгое понятие – аппаратное событие (event).

Событие – это нечто происшедшее с аппаратным узлом микроконтроллера. Например, переполнился таймер, в порт UART пришло данное, на внешнем входе изменился уровень сигнала и т.п.

Аппаратное событие – это то, что вызывает прерывание. Вернее может вызвать прерывание.

  • Без события прерывание невозможно. Именно аппаратное событие инициирует прерывание.
  • События без прерываний могут происходить.

И дело не только в том, что прерывания можно запретить и игнорировать события. В системе STM32 возможно использование событий для управления периферийными устройствами микроконтроллера. Например, прием байта портом UART вызывает событие, которое в свою очередь запускает контроллер прямого доступа к памяти (DMA) для пересылки этого байта в память. Получается, что происходит обработка события без прерывания программы.

Контроллер прерываний STM32.

Обработка и управление прерываниями производятся аппаратным узлом микроконтроллера – контроллером приоритетных векторных прерываний (NVIC). При возникновении разрешенного события контроллер прерывает выполнение программы, сохраняет в стеке необходимые данные и передает управление по адресу функции обработки прерывания. После выхода из функции-обработчика управление возвращается на адрес, по которому была прервана основная программа.

С точки зрения программного управления контроллер прерывания не особо сложное устройство. Я бы выделил следующее.

  • Контроллер приоритетный. Т.е. обработка прерывания может быть прервана другим прерыванием с более высоким приоритетом. Прерывания с таким же или более низким приоритетом будут ожидать окончания обработки активного прерывания. Приоритеты можно разбивать на группы и подгруппы.
  • Как следствие предыдущего пункта для каждого прерывания может быть задан приоритет. Это число от 0 до 15. 0 — самый высокий приоритет. Для установки приоритетов существует специальный блок регистров. На каждое прерывание в нем отведен один байт.
  • Могут быть запрещены сразу все прерывания – глобальный запрет.
  • Могут быть запрещены или разрешены отдельные прерывания. Для этого существует регистр разрешения или маски прерываний. Его отдельные биты определяют разрешение для каждого прерывания.
  • Существует блок регистров ожидания обработки прерываний, каждый бит которых соответствует конкретному прерыванию и показывает, ожидает ли оно обработки. Биты регистров могут быть установлены, для принудительного перевода прерываний в состояние ожидания или сброшены для удаления.
  • Есть регистры действующих прерываний, которые показывают, находятся ли прерывания в стадии обработки.
  • Любое прерывание может быть вызвано программно. Для этого существует регистр программного вызова прерываний. Прерывание вызывается записью в него соответствующего номера.
  • Каждому из прерываний соответствует свой фиксированный адрес-вектор, по которому передается управление для обработки прерывания.

Формально обработкой и управлением прерываниями занимается контроллер прерываний. Но для возникновения прерывания необходимо выполнение нескольких условий связанных как с контроллером прерываний, так и с периферийными устройствами микроконтроллера. Поэтому будем рассматривать задачу в комплексе.

Программное управление прерываниями STM32.

Для работы с аппаратными прерываниями необходимо:

  • Разрешить нужное прерывание в контроллере прерываний. Если необходимо, то задать для него приоритет.
  • Разрешить глобальные прерывания микроконтроллера.
  • Настроить устройство, в нашем случае таймер, на формирование запроса прерывания – события.
  • Создать функцию обработки прерывания.

Разрешение и запрет прерываний.

Для этого существуют функции библиотеки CMSIS.

void NVIC_EnableIRQ(IRQn_Type IRQn) – разрешение прерывания с номером IRQn.

void NVIC_DisableIRQ(IRQn_Type IRQn) – запрет прерывания с номером IRQn.

В файле stm32f103xb.h есть символьные имена, соответствующие номерам прерываний. Они описаны в структуре IRQn_Type . Я ее значительно сократил.

typedef enum <
. . . . . . . . . . . . . . . . . . . . . . . .
TIM1_BRK_IRQn = 24, /*!
TIM1_UP_IRQn = 25, /*!
TIM1_TRG_COM_IRQn = 26, /*!
TIM1_CC_IRQn = 27, /*!
TIM2_IRQn = 28, /*!
TIM3_IRQn = 29, /*!
TIM4_IRQn = 30, /*!
> IRQn_Type;

Команда разрешения прерывания перезагрузки таймера TIM1 будет выглядеть так.

Установка приоритетов прерываний.

По состоянию сброса для всех прерываний устанавливается самый высокий приоритет (0). Для его изменения существует функция библиотеки CMSIS.

void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

  • IRQn – номер прерывания , можно в символьном виде типа IRQn_Type ;
  • priority – приоритет (0 … 15), 0 – наивысший.

Например, если мы хотим для таймера TIM1 установить самый низкий приоритет, то необходимо выполнить команду.

Глобальные разрешение и запрет прерываний.

В программе бывают отрезки, которые недопустимо прерывать по самым разным соображениям. А аппаратные прерывания совершенно непредсказуемы. В этом случае можно запретить все прерывания, используя функцию глобального запрета.

__disable_irq (); // запретить прерывания


По окончанию непрерываемого блока надо разрешить прерывания специальной функцией.

__enable_irq (); // разрешить прерывания

Настройка устройства на формирование события и прерывания.

Это действие касается настройки конкретного периферийного устройства и индивидуально для каждого из них. Будем рассматривать для каждого устройства отдельно. В следующем уроке настроим таймер.

Функции обработки прерываний STM32.

В предыдущих уроках мы уже использовали функцию обработки прерывания таймера. Она была создана конфигуратором STM32CubeMX. Сейчас разберемся, откуда она появилась.

В микроконтроллерах STM32 поддерживается до 68 аппаратных прерываний. Каждому из них соответствует свой адрес – вектор. По этому адресу передается управление программы при возникновении прерывания.

Конкретные адреса для каждого источника можно посмотреть в документации на микроконтроллер. Выглядит это примерно так.

Из таблицы видно, что наш таймер TIM1 при перезагрузке формирует прерывания по адресу 00A4.

В файле startup\startup_stm32f103xb.s таблица векторов преобразуется в символьные имена функций обработки прерываний.

.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler

Для нашего таймера это TIM1_UP_IRQHandler .

Необходимо создать функцию с таким именем и разместить в ее теле обработчик прерывания.

void TIM1_UP_IRQHandler(void) <

// код обработки прерывания

// код или функция завершения прерывания

В начале файла c/cpp или h надо объявить функцию, разместить прототип.

void TIM1_UP_IRQHandler(void);

При выходе из функции, еще необходимо выполнить определенные действия для завершения прерывания. Как правило, это сброс флага прерывания.

Иначе может произойти следующее. Устройство сформировало событие. Как следствие стал активным флаг прерывания. Произошло, и было обработано прерывание. Программа вернулась к месту, на котором была прервана. А флаг прерывания остался активным. Произойдет новое прерывание, вызванное ошибкой алгоритма. Перед возвратом надо сбросить флаг. Об этом подробно в следующем уроке.

Думаю, что информации этого урока достаточно, чтобы в полной мере использовать прерывания STM32.

В следующем уроке будем настраивать таймеры.

Работа с InterruptedException

Вы его перехватили, что же теперь с ним делать?

Серия контента:

Этот контент является частью # из серии # статей: Теория и практика Java

Этот контент является частью серии: Теория и практика Java

Следите за выходом новых статей этой серии.

Эта история, наверное, вам знакома: вы пишете тестовую программу, и вам нужна на некоторое время пауза, поэтому вы вызываете Thread.sleep() . Но тут компилятор или IDE отклоняет это, заявляя, что вы не отреагировали на отмеченное InterruptedException . Что такое InterruptedException , и почему вам приходится с ним иметь дело?

Наиболее типичной реакцией на InterruptedException является его игнорирование, когда вы перехватываете его и ничего с ним не делаете (или, возможно, регистрируете его, что вряд ли намного лучше) — как мы увидим позднее в Листинге 4. К сожалению, этот подход отбрасывает важную информацию о том, что произошло прерывание, что может подвергнуть риску способность приложения отменять функции или своевременно прекратить работу.

Методы блокирования

Когда метод выдает InterruptedException , мы фактически получаем сразу несколько сообщений, в дополнение к тому, что он может сгенерировать отмеченное исключение. Он говорит вам о том, что это метод блокирования, и что он предпримет попытку разблокироваться и вернуться на более ранний этап — если вы хорошо попросите.

Метод блокирования отличается от обычного метода, которому требуется много времени для запуска. Завершение обычного метода зависит только от того, как много работы вы на него возложили, и имеются ли в наличии соответствующие компьютерные ресурсы (циклы центрального процессора и память). Завершение метода блокирования, с другой стороны, также зависит от некоего внешнего события, такого как прекращение действия таймера, завершение ввода-вывода, или действие другого потока (снимающего блокировочный замок, устанавливающего метку или ставящего в очередь задачу). Обычные методы завершаются, как только их работа выполнена, но методы блокирования менее предсказуемы, поскольку они зависят от внешних событий. Методы блокирования снижают время реакции, поскольку бывает трудно предсказать, когда они завершатся.

Поскольку методы блокирования потенциально могут занять сколь угодно много времени, если ожидаемое ими событие никогда не произойдет, то зачастую очень полезно для операций блокирования быть отменяемыми (cancelable). (Зачастую для долго работающих неблокирующих методов также полезно быть отменяемыми.) Отменяемой операцией является та, которая может быть извне доведена до завершения прежде, чем она самостоятельно завершится обычным путем. Механизм прерывания, обеспечиваемый Thread и поддерживаемый Thread.sleep() и Object.wait() , является механизмом отмены; он позволяет одному потоку запрашивать, чтобы другой поток прекратил выполнение того, что он делал ранее. Когда метод выдает InterruptedException , то он говорит вам, что если поток, выполняющий метод, прерван, то он предпримет попытку прекратить то, что он делает, вернуться на ранний этап, и указать его досрочный возврат путем выдачи InterruptedException . Рабочие методы библиотек блокирования должны реагировать на прерывание и выдавать InterruptedException , так, чтобы их можно было использовать в отменяемых функциях без риска для ответной реакции.

Прерывание потока

Каждый поток имеет связанное с ним булево свойство, которое отображает его статус прерывания. Статус прерывания изначально имеет значение false; когда поток прерывается каким-либо другим потоком путем вызова Thread.interrupt() , то происходит одно из двух. Если другой поток выполняет прерываемый метод блокирования низкого уровня, такой как Thread.sleep() , Thread.join() или Object.wait() , то он разблокируется и выдает InterruptedException . Иначе, interrupt() просто устанавливает статус прерывания потока. Код, действующий в прерванном потоке, может позднее обратиться к статусу прерывания, чтобы посмотреть, был ли запрос на прекращение выполняемого действия; статус прерывания может быть прочитан с помощью Thread.isInterrupted() , и может быть прочитан и сброшен за одну операцию при помощи неудачно названного Thread.interrupted() .

Прерывание является коллективным механизмом взаимодействия (cooperative mechanism). Когда один поток прерывает другой, прерванный поток не обязательно немедленно прекратит делать то, что он делал. Напротив, прерывание является вежливым способом, чтобы попросить другой поток прекратить то, что он делает, если он не против, когда ему это будет удобно. Некоторые методы, например, Thread.sleep() , серьезно относятся к такой просьбе, но методы не обязаны обращать внимание на прерывание. Неблокирующие методы, выполнение которых занимает много времени, могут положительно отнестись к просьбам о прерывании, путем опроса статуса прерывания, и в случае прерывания вернуться к более раннему этапу. Вы можете проигнорировать запрос о прерывании, но это может нанести ущерб ответной реакции.

Одним из преимуществ коллективной природы прерывания является то, что оно обеспечивает большую гибкость для безопасного построения отменяемых функций. Редко требуется немедленно остановить какую-либо функцию; структуры программных данных могут находиться в противоречивом состоянии, если функции были отменены во время обновления. Прерывание позволяет отменяемой функции завершить любую производящуюся работу, восстановить инварианты, уведомить другие функции об отмене, а затем прекратить работу.

Работа с InterruptedException

Если выдача InterruptedException означает, что метод является блокирующим, то вызов метода блокирования означает, что ваш метод также является блокирующим, и у вас должна быть стратегия для работы с InterruptedException . Зачастую наиболее простой стратегией является генерирование собственного InterruptedException , как показано в методах putTask() и getTask() в Листинге 1. Выполняя это, вы также делаете ваш метод восприимчивым к прерыванию, и это для этого требуется всего-навсего добавить InterruptedException в вашу конструкцию throws.

Листинг 1. Распространение InterruptedException на вызывающие операторы без его перехвата

Иногда необходимо произвести некоторую очистку, прежде чем распространить исключение. В этом случае вы можете перехватить InterruptedException , выполнить очистку, а затем повторно сгенерировать исключение. В Листинге 2, механизме подбора игроков в онлайновом игровом портале, показана именно такая технология. Метод matchPlayers() ожидает прибытия двух игроков, а затем начинает новую игру. Если она прервана после того, как появился один игрок, но до появления второго, то он ставит игрока в конец очереди, прежде чем повторно выдать InterruptedException , так, чтобы запрос игрока не был утерян.

Листинг 2. Выполнение специализированной (task-specific) очистки перед повторной выдачей InterruptedException

Не поглощайте прерывания

Иногда генерирование InterruptedException не является опцией, как в случае задачи, определяемой Runnable , которая вызывает прерываемый метод. В этом случае вы не можете повторно выдать InterruptedException , но вообще ничего не делать нельзя. Когда метод блокирования обнаруживает прерывание и выдает InterruptedException , то он очищает статус прерывания. Если вы перехватили InterruptedException , но не можете повторно его сгенерировать, то вы должны сохранить подтверждение того, что прерывание произошло так, чтобы вышестоящий в стеке вызовов код мог узнать о прерывании и среагировать на него, если он хочет это сделать. Эта задача выполняется с помощью вызова interrupt() , чтобы «повторно прервать» текущий поток, как показано в Листинге 3. По крайней мере, когда бы вы ни перехватили InterruptedException и не выдали его повторно, еще раз прервите текущий поток перед возвратом.

Листинг 3. Восстановление статуса прерывания после перехвата InterruptedException

Худшее, что вы можете сделать с InterruptedException — это его поглощение — перехват без повторной его выдачи и без переподтверждения статуса прерывания потока. Стандартный подход к работе с незапланированной ошибкой — перехватить ее и зарегистрировать — также расценивается как поглощение (swallowing) прерывания, поскольку вышестоящий в стеке вызовов код не сможет узнать об этом. (Регистрирование InterruptedException также просто бессмысленно, потому что к тому времени, когда человек прочитает журнал, будет слишком поздно что-либо предпринимать.) В Листинге 4 показан слишком типичный шаблон поглощения прерывания:

Листинг 4. Поглощение прерывания — не делайте этого

Если вы не можете повторно выдать InterruptedException , независимо от того, планируете ли вы работать с запросом прерывания, вам все-таки нужно повторно прервать текущий поток, поскольку единичный запрос прерывания может иметь множество «получателей.» Стандартная реализация рабочего потока пула потоков ( ThreadPoolExecutor ) реагирует на прерывание, следовательно, прерывание задачи, выполняющейся в пуле потока, может влиять как на отмену задачи, так и на уведомление работающего потока о том, что пул потока завершает работу. Если задачей было поглотить запрос прерывания, рабочий поток может не узнать, что было запрошено прерывание, а это может отложить завершение работы приложения или службы.

Реализация отменяемых задач

В спецификации языка не дается какой-либо конкретной семантики прерывания, но в больших программах сложно получить какую-нибудь иную семантику прерывания, кроме отмены. В зависимости от функции, пользователь может запросить отмену через GUI или через сетевой механизм, например JMX или Web-сервисы. Она также может запрашиваться логикой программы. Например, Web crawler (поисковый агент) может автоматически прекратить свою работу в случае обнаружения переполнения диска, или параллельный алгоритм может запустить множество потоков для поиска в различных областях пространства решения и отменить их, как только один из них его найдет.

То, что задача является отменяемой, не означает, что ей нужно немедленно среагировать на запрос прерывания. Для задач, выполняющих код в цикле, проверка на прерывание один раз за итерацию цикла является обычной. В зависимости от того, как долго выполняется цикл, это может занять некоторое время, прежде чем код задачи заметит, что поток был прерван (либо с помощью обращения к статусу прерывания с Thread.isInterrupted() или с помощью вызова метода блокирования). Если необходимо, чтобы задача была более «отзывчивой» (responsive), то она может чаще делать обращения к статусу прерывания. Методы блокирования обычно опрашивают статус прерывания немедленно при входе, генерируя InterruptedException , если оно настроено на улучшение «отзывчивости».

Единственный раз, когда допустимо поглотить прерывание, это когда вы знаете, что поток должен вот-вот завершить работу. Этот сценарий имеет место только когда класс, вызывающий прерываемый метод, является частью Thread , а не Runnable или универсального библиотечного кода, как показано в Листинге 5. Он создает поток, который перечисляет простые числа до тех пор, пока он не будет прерван, и позволяет потоку завершить работу после прерывания. Ищущий простые числа цикл проверяет наличие прерывания в двух местах: один раз, опрашивая метод isInterrupted() в заголовке цикла с проверкой условия, и еще раз — при вызове метода блокирования BlockingQueue.put() .

Листинг 5. Сообщения interrupt можно поглощать, если вы знаете, что поток скоро завершит работу

Непрерываемое блокирование

Не все методы блокирования выдают InterruptedException . Классы входных и выходных потоков могут блокировать ожидание ввода-вывода для завершения, но они не выдают InterruptedException , а также не возвращаются на ранний этап, если их прервать. Тем не менее, в случае сокета I/O, если поток закрывает сокет, блокирование операции ввода-вывода данного сокета в других потоках завершится раньше с исключением SocketException . Неблокирующие I/O-классы в java.nio также не поддерживают прерываемый ввод-вывод, но операции блокирования можно отменить сходным образом, закрыв канала или запросив активацию в Selector . Аналогично, попытка получить внутреннюю блокировку (вводом блока synchronized ) не может быть прервана, но ReentrantLock поддерживает прерываемый режим захвата.


Неотменяемые задачи

Некоторые задачи просто отказываются быть прерванными, что делает их неотменяемыми. Однако даже неотменяемые задачи должны попытаться сохранить статус прерывания на случай, если вышестоящий в стеке вызовов код захочет воздействовать на прерывание после завершения неотменяемой задачи. В Листинге 6 показан метод, ожидающий в очереди блокировок до тех пор, пока элемент не станет доступным, не обращая внимания на то, был ли он прерван. Как сознательный гражданин, он восстанавливает статус прерывания в финальном блоке после его завершения, так чтобы не лишить вызывающие операторы запроса прерывания. (Он не мог восстановить статус прерывания ранее, поскольку это привело бы к бесконечному циклу — BlockingQueue.take() могло бы опросить статус прерывания немедленно при входе и выдать InterruptedException , если он обнаружит установку статуса прерывания.)

Листинг 6. Неотменяемая задача, восстанавливающая статус прерывания перед возвратом

Резюме

Вы можете использовать коллективный механизм прерывания, обеспечиваемый платформой Java для конструирования гибких алгоритмов отмены. Функции (activities) могут решать, являются ли они отменяемыми или нет, насколько им следует быть восприимчивыми к прерыванию, и они могут задержать прерывание для выполнения специализированной очистки, если немедленный возврат подвергнет риску целостность приложения. Даже если вы захотите полностью проигнорировать прерывание в вашем коде, убедитесь в восстановлении статуса прерывания, если вы перехватили InterruptedException , и не генерируйте его повторно, чтобы вызывающий его код не был лишен информации о том, что произошло прерывание.

Методы опроса и прерывания для пакетной обработки в многоядерном процессоре

Этот запрос связан с обработкой пакетов в многоядерных процессорах. Обработка пакетов может быть либо в Linux, либо в чистом datapath. Верно ли, что если приложение для обработки пакетов находится в Linux, то это должно быть связано с обработкой пакетов на основе пакетов для высокой производительности, но если обработка пакетов выполняется в чистом datapath (без linux), то для получения более высокой производительности следует использовать опрос? Если да, то почему/как?

Опрос
Мы уже на месте? Мы уже на месте? Мы уже на месте? Мы уже на месте? Мы уже на месте.

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

Таким образом, прерывания позволяют процессору выполнять другую работу, в то время как опрос позволяет избежать накладных расходов прерываний (значительно, если вы прерываете десятки тысяч раз в секунду). Различные виды высокой производительности.

Обратите внимание, что есть гибридные aproaches, т.е. опрос после прерываний в течение нескольких мс, прежде чем возвращаться к прерываниям.

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

Если вы используете встроенную систему без использования ОС без ОС, вы должен иметь возможность получить максимальную пропускную способность, используя опрос, поскольку процессор могут тратить все свое время на проверку новых пакетов или обработку в качестве результат получения пакетов. Это минимизирует задержку и выделяет максимум циклов для обработки пакетов. Вызов прерывания обработчик циклов отходов и вводит дополнительную сложность в этом случае; поскольку на процессоре ничего не работает, любой цикл, который вы принимаете, — это цикл не используется в отношении пути данных.

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

Я не уверен, что такое «многоядерный» аспект этого вопроса, но может иметь смысл выделить ЦП для опроса ввода-вывода, чтобы получить минимальный задержка во встроенной многоядерной системе, хотя это тоже было бы особенно для приложений.

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

Прерывания STM32.

У STM32 прерываниями управляет контроллер прерываний NVIC — Nested vectored interrupt controller.

Давайте рассмотрим его возможности:

  • обслуживание до 81 прерывания, в зависимости от модели МК
  • программируемый уровень приоритета от 0 до 15 для каждого прерывания, самым приоритетным считается прерывание с уровнем 0
  • динамическое изменение приоритета
  • разделение прерываний на группы, а внутри группы на подгруппы с разным уровнем приоритета

Сразу хотелось бы обратить внимание на то, что в основе любого прерывания лежит событие, принял байт по uart — событие, переполнился таймер— событие. При возникновении события и установленных флагах, разрешающих прерывание, программа прыгнет в обработчик прерывания.

Для настройки NVIC, в CMSIS предназначены массивы, состоящие из 3 элементов.

Рассмотрим как включить/выключить в NVIC прерывание от usart1, его номер 37, в таблице векторов прерываний RM0008.

Откуда взялась цифра 5? Шестое прерывание из-за того, что счёт начинается с нуля будет иметь номер 5. Так как в нулевом элементе массива расположены прерывания с номерами от до 31, шестое прерывание из первого элемента массива будет иметь номер 37, 6 + 31 = 37.

Но для того, чтобы программа перешла в обработчик прерывания этого недостаточно, у STM32 надо разрешить его в 3-х местах:

  • разрешить прерывания глобально
  • разрешить прерывание в NVIC
  • разрешить прерывание непосредственно в самой периферии

Глобальное управление прерываниями , производится с помощью следующих команд:

Разрешить прерывание по завершению передачи и приему кадра по usart1, можно следующим образом:

Название обработчиков прерываний можно найти в файле startup_stm32f10x_hd.s

Следует отметить, что по завершении передачи и приёму нового кадра по uart1 возникает одно и то же прерывание и для того, чтобы определить какое событие вызвало это прерывание, нужно воспользоваться флагами. Если прерывание произошло по приёму выставиться флаг USART_SR_RXNE, по завершении передачи — USART_SR_TC, кстати, флаги надо сбрасывать вручную.

Каждому прерыванию, при сброшенных битах AIRCR[10:8], может быть назначен приоритет от 0 до 15, после сброса все прерывания имеют высший приоритет — 0.

Обслуживаются они по следующим правилам:

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

Для задания приоритетов выделены старшие 4 бита в регистрах IPRx[7:4], в CMSIS они представлены массивом IP[x].

Для создания групп приоритетов необходимо установить биты в регистре AIRCR[10:8] согласно таблице.

x — определяет количество групп приоритетов, y — количество подгрупп приоритетов.

То есть если мы хотим задать 16 групп приоритетов надо записать в AIRCR[10:8] число 3, а записанное число в регистр IPRx[7:4] будет определять группу, если хотим 8 групп и 2 подгруппы надо записать в AIRCR[10:8] число 4, тогда старшие 3 бита регистра IPRx[7:4] будут определять группу, а младший бит старшей тетрады — подгруппу и так далее.

Но если разрешать/запрешать прерывания, выставлять приоритет, удобно, выставляя соответствующие биты, то для создания групп приоритетов удобнее пользоваться функциями CMSIS, хотя кому-то может быть удобно всегда использовать функции CMSIS.

  • приоритет группы определяет может ли одно прерывание перебивать другое, то есть группа с приоритетом 1 легко перебьет любое прерывание из группы с приоритетом 5
  • номер подгруппы определяет какое прерывание выполнится первым, в случае одновременного возникновения двух прерываний из одной группы, также надо сказать, что прерывания из одной группы не могут перебивать друг друга
  • в случае одновременного возникновения двух прерываний из одной группы с одинаковыми подгруппами, первым выполнится прерывание с меньшим номером

Interrupt package пакет работы с прерываниями

Создано 22.11.2020 11:53

Опубликовано 22.11.2020 11:53

Узкие места сетевой подсистемы Linux. Тюнинг сети в Linux. Настройка производительности сети в модели NAPI и с прерываниями.

Кольцевой буфер

Кольцевые буферы, совместно используются драйвером устройства и сетевой картой. TX – есть передача данных, а RX – получение данных в кольцевом буфере. Как следует из названия, переполнение буфера просто перезаписывает существующие данные. Есть два способа переместить данные от сетевой карты до ядра: аппаратные прерывания и программные прерывания, названные SoftIRQs.

Кольцевой буфер RX используется, чтобы сохранить входящие пакеты, пока они не могут быть обработаны драйвером устройства. Драйвер устройства опустошает буфер RX, обычно через SoftIRQs, который помещает входящие пакеты в структуру данных ядра, названную sk_buff или «skb», чтобы начать свой путь через ядро и до приложения, которому принадлежит соответствующий сокет. Кольцевой буфер TX используется для хранения исходящих пакетов, которые предназначенные для отправки по проводам.

Эти кольцевые буферы находятся у основания стека и являются критическим моментом, в который может произойти удаление (drop) пакетов, что негативно влияет на производительность сети.

Прерывания и обработчики прерываний

Прерывания от аппаратных средств известны как прерывания «top-half».

Сетевые карты, как правило, работают с кольцевыми буферами (DMA ring buffer) организованными в памяти, разделяемой с процессором. Каждый входящий пакет размещается в следующем доступном буфере кольца. (DMA — Direct Memory Access (Прямой доступ к памяти) — режим обмена данными между устройствами или же между устройством и основной памятью, в котором центральный процессор (ЦП) не участвует). После этого требуется сообщить системе о появлении нового пакета и передать данные дальше, в специально выделенный буфер (Linux выделяет такие буферы для каждого пакета). Для этой цели в Linux используется механизм прерываний: прерывание генерируется всякий раз, когда новый пакет поступает в систему. Чаще используется отложенные прерывания (см. в статье Linux, принципы работы с сетевой подсистемой ). В ядро Linux начиная с версии ядра 2.6 был добавлен так называемый NAPI (New API), в котором метод прерываний сочетается с методом опроса. Сначала сетевая карта работает в режиме прерываний, но как только пакет поступает на сетевой интерфейс, она регистрирует себя в poll-списке и отключает прерывания. Система периодически проверяет список на наличие новых устройств и забирает пакеты для дальнейшей обработки. Как только пакеты обработаны, карта будет удалена из списка, а прерывания включатся снова.

Жесткие прерывания можно увидеть в /proc/interrupts, где у каждой очереди есть vector прерывания в 1-м столбце. Каждой очереди RX и TX присвоен уникальный vector, который сообщает обработчику прерываний, относительно какого NIC/queue пришло прерывание. Столбцы представляют количество входящих прерываний:

#egrep «CPU0|eth1» /proc/interrupts

CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7

45: 28324194 0 0 0 0 0 0 0 PCI-MSI-edge eth1

SoftIRQs

Иизвестны как прерывания «bottom-half», запросы программного прерывания (SoftIRQs), являются подпрограммами ядра, которые планируется запустить в то время, когда другие задачи не должны быть прерваны. Цель SoftIRQ состоит в извлечении данных из кольцевых буферов. Эти подпрограммы, выполненные в форме процессов ksoftirqd/cpu-number и, вызывают специфичные для драйвера функции кода.

После перемещения данных от драйвера к ядру, трафик двигатется вверх к сокету приложения.

SoftIRQs можно контролировать следующим образом. Каждый столбец есть ЦП:

# watch -n1 grep RX /proc/softirqs


# watch -n1 grep TX /proc/softirqs

NAPI Polling

Поиск узкого места

Отбрасывание пакетов и переполнени границ (packet drops и overruns) обычно происходит, когда буфер RX сетевой карты не может достаточно быстро опустошиться ядром. Когда скорость, с которой данные поступают из сети превышает скорость, с которой ядро забирает на обработку пакеты, сетевая карта начинает отбрасывать входящие пакеты, т.к. буфер NIC (сетевой карты) полон, и увеличивает счетчик удаления.Соответствующий счетчик можно увидеть в ethtool статистике. Основные критерии здесь — прерывания и SoftIRQs.

Для примера вывод статистики ethtool:

Существуют различные инструменты, доступные для поиска проблемной области. Следует исследовать:

• Уровень встроенного ПО адаптера

— Следим за статистикой ethtool -S ethX

• Уровень драйвера адаптера

• Ядро Linux, IRQs или SoftIRQs

— Проверяем /proc/interrupts и /proc/net/softnet_stat

• Уровни протокола IP, TCP, UDP

— Используем netstat -s и смотрим счетчики ошибок

Вот некоторые типичные примеры узких мест:

  • Прерывания (IRQs) неправильно сбалансированы. В некоторых случаях служба irqbalance может работать неправильно или не работает вообще. Проверьте /proc/interrupts и удостоверьтесь, что прерывания распределены на разные ядра ЦП. Обратитесь к irqbalance руководству, или вручную сбалансируйте IRQs. В следующем примере прерывания становятся обработанными только одним процессором:

# egrep “CPU0|eth2” /proc/interrupts

CPU0 CPU1 CPU2 CPU3 CPU4 CPU5

105: 1430000 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-0

106: 1200000 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-1

107: 1399999 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-2

108: 1350000 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-3

109: 80000 0 0 0 0 0 IR-PCI-MSI-edge eth2-tx

  • Посмотрите, увеличивается ли какая-либо из колонок помимо 1-й колонки в /proc/net/softnet_stat. В следующем примере счетчик большой для CPU0, и budget должен быть увеличен:
  • Увеличение приемного буфера сокета приложения или использование буфера автоподстройки.
  • Использование большого/малого TCP или UDP размера пакетов.

Настройка производительности

SoftIRQ

Если выполнение программных прерываний не выполняются достаточно долго, то темп роста входящих данных может превысить возможность ядра опустошить буфер. В результате буферы NIC переполнятся, и трафик будет потерян. Иногда, необходимо увеличить длительность работы SoftIRQs (программных прерываний) с CPU. За это отвечает netdev_budget. Значение по умолчанию 300. Параметр заставит процесс SoftIRQ обработать 300 пакетов от NIC перед тем как отпустить CPU:

Это значение может быть удвоено, если 3-й столбец в /proc/net/softnet_stat увеличивается, что указывает, на то, что SoftIRQ не получил достаточно процессорного времени. Маленькие инкременты нормальны и не требуют настройки.

0073d76b 00000000 000049ae 00000000 00000000 00000000 00000000 00000000 00000000 00000000

000000d2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

0000015c 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

0000002a 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

IRQ Balance

Балансировщик прерываний — это сервис, который может автоматически сбалансировать прерывания между ядрами процессора, основанного на реальном времени состояния системы.

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

Чтобы это сделать нужно выполнить команду echo N > /proc/irq/X/smp_affinity, где N — маска процессора (определяет какому процессору достанется прерывание), а X — номер прерывания, виден в первом столбце вывода /proc/interrupts. Чтобы определить маску процессора, нужно возвести 2 в степень cpu_N (номер процессора) и перевести в шестнадцатиричную систему. При помощи bc вычисляется так: echo «obase=16; $[2 ** $cpu_N]» | bc. Например:

#CPU0
echo 1 > /proc/irq/57/smp_affinity
echo 1 > /proc/irq/66/smp_affinity

#CPU1
echo 2 > /proc/irq/58/smp_affinity
echo 2 > /proc/irq/67/smp_affinity

#CPU2
echo 4 > /proc/irq/59/smp_affinity
echo 4 > /proc/irq/68/smp_affinity

#CPU3
echo 8 > /proc/irq/60/smp_affinity
echo 8 > /proc/irq/69/smp_affinity

Для того, чтобы при старте системы прерывания сами настраивались, можно сделать скрипт и настроить его запуск /etc/rc.d/rc.local.

Ethernet flow control

Паузы фреймов — управление потоком уровня Ethernet между адаптером и портом коммутатора. Адаптер передаст “кадры паузы”, когда RX или буферы TX станут полными. Коммутатор остановит поток данных в течение определенного промежутка времени в порядке миллисекунд. Этого времени обычно достаточно, чтобы позволить ядру опустошить интерфейсные буферы, таким образом предотвращая переполнение буфера и последующие пакетные отбрасывания или переполнения. В идеале, коммутатор буферизует входящие данные в течение такой паузы.

Однако, важно понимать, что этот уровень контроля потока только между коммутатором и адаптером. Если пакеты отброшены, более высокие уровни, такие как TCP или приложение в случае UDP и/или многоадресно переданы, должен инициировать восстановление.

Важно! Фреймы паузы и flow control (управление потоком) должны быть включены и на NIC и на порте коммутатора.

Pause parameters for eth3:


# ethtool -A eth3 rx on

# ethtool -A eth3 tx on

Pause parameters for eth3:

Interrupt Coalescence (отложенные прерывания)

Отложенные прерывания рассказывают нам о количестве трафика, который будет получать сетевой интерфейс, или времи, которое проходит после приема трафика, перед выдачей жесткого прерывания. Слишком ранние прерывания или слишком частые приводят к снижению производительности системы, так как ядро останавливается (или «перебивает») запущенное задание для обработки запроса прерывания от аппаратного обеспечения. Слишком поздее прерывание может привести к тому, что пакеты достаточно долго не будут обработаны ядром с сетевой карты. Большие объемы трафика могут переписать предыдущие пакеты трафика, т.е. потеря пакетов.

Самые современные NIC и драйверы поддерживают IC, и многие позволяют драйверу автоматически модерировать количество прерываний, сгенерированных аппаратными средствами. Настройки IC обычно включают два основных компонента, время и количество пакетов. Время в мкс — сколько NIC будет ожидать прежде, чем прервать ядро, а число пакетов – сколько пакетов будет ждать в приемном буфере прежде чем сработает прерывание. Отложенные прерывания NIC можно посмотреть, используя команду ethtool -c ethX и настроить через ethtool -C ethX. Адаптивный режим позволяет карте автомодерировать IC. В адаптивном режиме, драйвер инспектирует трафик и ядро настраивает прерывания на лету, предотвращая потерю пакетов.

Coalesce parameters for eth3:

Adaptive RX: on TX: off

Следующая команда выключает адаптивный IC, и говорит адаптеру о прерывании ядра

сразу после приема любого трафика:

# ethtool -C eth3 adaptive-rx off rx-usecs 0 rx-frames 0

Очередь адаптера (The Adapter Queue)

Netdev_max_backlog — очередь в ядре Linux, где трафик хранится после получения от сетевого адаптера, но перед обработкой с помощью стеков протоколов (IP, TCP, и т.д.). Для каждого ядра процессора существует одна очередь. Очередь может расти автоматически до максимального значения, указанного в netdev_max_backlog. Функция ядра netif_receive_skb () находит соответствующий ЦП для пакета и ставит пакеты в очереди того ЦП. Если очередь для этого процессора будет полна и уже в максимальном размере, пакеты будут отброшены. Для того, чтобы тюнить это место необходимо убедиться что оно реально нужно. В /proc/net/softnet_stat в втором столбце есть счетчик, который увеличивается когда очередь переполняется. Каждая строка файла softnet_stat представляет собой ядро процессора, начиная с CPU0.

1-й столбец — количество кадров, полученных с помощью обработчика прерывания.

2-й столбец — количество фреймов, отброшенных из-за превышения netdev_max_backlog..

3-й столбец — число раз ksoftirqd исчерпал netdev_budget или процессорное время, когда нужно было еще поработать.

0073d76b 00000000 000049ae 00000000 00000000 00000000 00000000 00000000 00000000 00000000

000000d2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

0000015c 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

0000002a 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

В текущем выводе netdev_max_backlog не нуждается в тюнинге, т.к. очередь не переполняется и нет потерь соответственно. Если же наблюдаются приащения в второй колонке, тогде увеличиваем значение очереди и снова смотрим в этот файл. Если увеличения этого значения мы видим что скорость приращений в втором столбце уменьшается то можно еще увеличить значение backlog. Повторяем этот процесс пока перестанет расти цифры в столбце 2.

Backlog изменить можно такой командой:

# ip link set dev em1 txqueuelen 2000

TCP Window Scaling (масштабирование окна TCP)

Размер TCP окна (TCP Window Size) – количество октетов (начиная с номера подтверждения), которое принимающая сторона готова принять в настоящий момент без подтверждения. На стадии установления соединения рабочая станция и сервер обмениваются значениями максимального размера TCP окна (TCP Window Size), которые присутствуют в пакете. Например, если размер окна получателя равен 16384 байта, то отправитель может отправить 16384 байта без остановки. Принимая во внимание, что максимальная длина сегмента (MSS) может быть 1460 байт, то отправитель сможет передать данный объем в 12 фреймах, и затем будет ждать подтверждение доставки от получателя и информации по обновлению размера окна. Если процесс прошел без ошибок, то размер окна может быть увеличен. Таким образом, реализуется размер скользящего окна в стеке протокола TCP. В современных версиях операционных систем можно увеличить размер окна TCP Window Size и включить динамическое изменение окна в зависимости от состояния канала связи. Динамическое увеличение и уменьшение размера окна является непрерывным процессом в TCP и определяет оптимальный размер окна для каждого сеанса. В очень эффективных сетях размеры окна могут стать очень большими, потому что данные не теряются.

Масштабирование Окна TCP включено по умолчанию:

Илон Маск рекомендует:  Что такое код odbc_statistics
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL