int-attach: добавлены опции -m / -p

This commit is contained in:
parent 558b729c13
commit 6c5ce07fdc
3 changed files with 78 additions and 28 deletions

View File

@ -1,28 +1,33 @@
### int-attach
Навесить обработчик прерывания и выводить отладочное сообщение при его возникновении
Навесить обработчик прерывания и выводить отладочное сообщение при его возникновении.
### Синтаксис
```int-attach -i N```
```int-attach -i N -m -p P```
### Опции
- **-i номер_прерывания**
навесить обработчик на указанный номер
-i номер_прерывания Навесить обработчик на указанный номер.
-m Маскировать прерывание в обработчике и размаскировать в основном потоке.
-p период_мс Подсчитывать количество прерываний за указанный период времени (в миллисекундах).
### Описание
Утилита int-attach навешивает минимальный обработчик на заданный номер прерывания и выводит отладочное сообщение при возникновении этого прерывания.
Подключаемый обработчик прерывания содержит минимальный код, увеличивающий счётчик количества перехваченных прерываний и маскирующий прерывание. Размаскирование прерывания выполняется в основном потоке функции main() после вывода отладочного сообщения в консоль.
Подключаемый обработчик прерывания содержит минимальный код, увеличивающий счётчик с количеством полученных прерываний.
При задании опции -m прерывание маскируется в обработчике с помощью InterruptMask() и размаскируется после вывода отладочного сообщения в консоль.
При задании опции -p производится подсчёт поличества прерываний за указанный период времени.
Может использоваться для отладки и проверки того, что указанное прерывание возникает в ожидаемый момент времени, например, при обращении к аппаратуре, отправка сообщения в COM порт, работа с диском и т.п.
Утилита может использоваться для отладки работы прерываний и проверки того, что указанное прерывание возникает в ожидаемый момент времени, например, при работе с аппаратурой, получении данных из COM порта и т.п.
Одновременно можно запустить несколько копий программы с различными номерами прерываний.
### Предостережения
Учтите, что вывод отладочного сообщения достаточно длительная операция и на это время прерывание будет оставаться замаскированным, что значительно увеличит задержку его обработки в основном драйвере/программ и может нарушить их работу.
Учтите, что при задании флага -m и маскировании прерывания может нарушиться работа драйвера или программы, отвечающих за обработку этого прерывания, т.к. вывод отладочного сообщения достаточно длительная операция и на это время прерывание будет оставаться замаскированным.
### Примеры
Навесить обработчик на прерывание 10
```int-attach -i 10 &```
Навесить обработчик на прерывание номер 10
```int-attach -i 10```
Подсчитать количество прерываний за 1 секунду (1000мс)
```int-attach -i 10 -p 1000```

View File

@ -10,21 +10,36 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syspage.h>
#include <inttypes.h>
struct sigevent int_event;
int id = -1;
unsigned long int_n = 1;
volatile unsigned long int_conter = 0;
int id = -1;
int interrupt_n = -1;
int mask_flag = 0;
unsigned period_ns = 0;
volatile unsigned long int_counter = 0;
volatile uint64_t prev_nsec = 0;
const struct sigevent *handler( void *area, int id )
{
InterruptMask( int_n, id );
if ( mask_flag )
InterruptMask( interrupt_n, id );
int_conter++;
int_counter++;
return (&int_event);
if ( !period_ns )
return (&int_event);
else {
if ( (SYSPAGE_ENTRY( qtime )->nsec - prev_nsec) > period_ns )
{
prev_nsec = SYSPAGE_ENTRY( qtime )->nsec;
return (&int_event);
} else
return (NULL);
}
}
@ -41,38 +56,66 @@ int main( int argc, char **argv )
printf( "Interrupt attach program \n" );
while ( (opt = getopt ( argc, argv, "i:" )) != -1 )
while ( (opt = getopt( argc, argv, "i:p:m" )) != -1 )
{
switch ( opt )
{
case 'i':
int_n = strtoul( optarg, NULL, 0 );
interrupt_n = strtoul( optarg, NULL, 0 );
break;
case 'p':
period_ns = strtoul( optarg, NULL, 0 );
period_ns *= 1000 * 1000; // nanoseconds
break;
case 'm':
mask_flag = 1;
break;
default:
printf( "Unsupported option.\n" );
return (-1);
}
}
if( int_n < 0 )
if( interrupt_n < 0 )
{
printf( "Incorrect interrupt number %d \n", interrupt_n );
return (-1);
else
printf( "Attaching handler for interrupt %lu ( 0x%lX ) \n\n", int_n, int_n );
} else
printf( "Attaching handler for interrupt %u ( 0x%X ) \n\n", interrupt_n, interrupt_n );
int_event.sigev_notify = SIGEV_INTR;
// register an interrupt handler
id = InterruptAttach( int_n, &handler, NULL, 0, 0 );
// Attach interrupt handler
id = InterruptAttach( interrupt_n, &handler, NULL, 0, 0 );
if ( id == -1 )
{
perror( " Cannot attach interrupt handler " );
perror( "Cannot attach interrupt handler" );
return (-1);
}
if ( period_ns )
{
printf( "Counting number of interrupts %u ( 0x%X ) per %u milliseconds \n", interrupt_n, interrupt_n, period_ns / 1000000 );
int_counter = 0;
prev_nsec = SYSPAGE_ENTRY( qtime )->nsec;
}
while ( 1 )
{
InterruptWait( 0, NULL );
printf( "Got interrupt %lu ( 0x%lX ) #%4ld\n", int_n, int_n, int_conter );
InterruptUnmask( int_n, id );
if ( int_counter )
printf( "Interrupt %u ( 0x%X ) : %8ld \n", interrupt_n, interrupt_n, int_counter );
if ( period_ns )
int_counter = 0;
if ( mask_flag )
InterruptUnmask( interrupt_n, id );
}
InterruptDetach( id );

View File

@ -1,5 +1,7 @@
%C - interrupt attach
Options:
i <num> - Attach interrupt handler for interrupt <num> (InterruptAttach() is used).
Interrupt is masked in interrupt handler and then unmasked in main thread.
-i interrupt_num Attach interrupt handler for interrupt <num>.
-m Mask interrupt in interrupt handler and then unmask in main thread.
-p period_ms Count number of interrupts for specified period.