int-attach: добавлены опции -m / -p
This commit is contained in:
parent
558b729c13
commit
6c5ce07fdc
@ -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```
|
||||
|
@ -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 );
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user