int-attach: добавлены опции -m / -p
Этот коммит содержится в:
родитель
558b729c13
Коммит
6c5ce07fdc
@ -1,28 +1,33 @@
|
|||||||
### int-attach
|
### int-attach
|
||||||
|
|
||||||
Навесить обработчик прерывания и выводить отладочное сообщение при его возникновении
|
Навесить обработчик прерывания и выводить отладочное сообщение при его возникновении.
|
||||||
|
|
||||||
### Синтаксис
|
### Синтаксис
|
||||||
```int-attach -i N```
|
```int-attach -i N -m -p P```
|
||||||
|
|
||||||
### Опции
|
### Опции
|
||||||
- **-i номер_прерывания**
|
-i номер_прерывания Навесить обработчик на указанный номер.
|
||||||
|
-m Маскировать прерывание в обработчике и размаскировать в основном потоке.
|
||||||
навесить обработчик на указанный номер
|
-p период_мс Подсчитывать количество прерываний за указанный период времени (в миллисекундах).
|
||||||
|
|
||||||
### Описание
|
### Описание
|
||||||
|
|
||||||
Утилита int-attach навешивает минимальный обработчик на заданный номер прерывания и выводит отладочное сообщение при возникновении этого прерывания.
|
Утилита int-attach навешивает минимальный обработчик на заданный номер прерывания и выводит отладочное сообщение при возникновении этого прерывания.
|
||||||
Подключаемый обработчик прерывания содержит минимальный код, увеличивающий счётчик количества перехваченных прерываний и маскирующий прерывание. Размаскирование прерывания выполняется в основном потоке функции main() после вывода отладочного сообщения в консоль.
|
Подключаемый обработчик прерывания содержит минимальный код, увеличивающий счётчик с количеством полученных прерываний.
|
||||||
|
При задании опции -m прерывание маскируется в обработчике с помощью InterruptMask() и размаскируется после вывода отладочного сообщения в консоль.
|
||||||
|
При задании опции -p производится подсчёт поличества прерываний за указанный период времени.
|
||||||
|
|
||||||
Может использоваться для отладки и проверки того, что указанное прерывание возникает в ожидаемый момент времени, например, при обращении к аппаратуре, отправка сообщения в COM порт, работа с диском и т.п.
|
Утилита может использоваться для отладки работы прерываний и проверки того, что указанное прерывание возникает в ожидаемый момент времени, например, при работе с аппаратурой, получении данных из COM порта и т.п.
|
||||||
Одновременно можно запустить несколько копий программы с различными номерами прерываний.
|
Одновременно можно запустить несколько копий программы с различными номерами прерываний.
|
||||||
|
|
||||||
### Предостережения
|
### Предостережения
|
||||||
|
|
||||||
Учтите, что вывод отладочного сообщения достаточно длительная операция и на это время прерывание будет оставаться замаскированным, что значительно увеличит задержку его обработки в основном драйвере/программ и может нарушить их работу.
|
Учтите, что при задании флага -m и маскировании прерывания может нарушиться работа драйвера или программы, отвечающих за обработку этого прерывания, т.к. вывод отладочного сообщения достаточно длительная операция и на это время прерывание будет оставаться замаскированным.
|
||||||
|
|
||||||
### Примеры
|
### Примеры
|
||||||
|
|
||||||
Навесить обработчик на прерывание 10
|
Навесить обработчик на прерывание номер 10
|
||||||
```int-attach -i 10 &```
|
```int-attach -i 10```
|
||||||
|
|
||||||
|
Подсчитать количество прерываний за 1 секунду (1000мс)
|
||||||
|
```int-attach -i 10 -p 1000```
|
||||||
|
@ -10,21 +10,36 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/syspage.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
||||||
struct sigevent int_event;
|
struct sigevent int_event;
|
||||||
int id = -1;
|
int id = -1;
|
||||||
unsigned long int_n = 1;
|
int interrupt_n = -1;
|
||||||
volatile unsigned long int_conter = 0;
|
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 )
|
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" );
|
printf( "Interrupt attach program \n" );
|
||||||
|
|
||||||
while ( (opt = getopt ( argc, argv, "i:" )) != -1 )
|
while ( (opt = getopt( argc, argv, "i:p:m" )) != -1 )
|
||||||
{
|
{
|
||||||
switch ( opt )
|
switch ( opt )
|
||||||
{
|
{
|
||||||
case 'i':
|
case 'i':
|
||||||
int_n = strtoul( optarg, NULL, 0 );
|
interrupt_n = strtoul( optarg, NULL, 0 );
|
||||||
break;
|
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);
|
return (-1);
|
||||||
else
|
} else
|
||||||
printf( "Attaching handler for interrupt %lu ( 0x%lX ) \n\n", int_n, int_n );
|
printf( "Attaching handler for interrupt %u ( 0x%X ) \n\n", interrupt_n, interrupt_n );
|
||||||
|
|
||||||
int_event.sigev_notify = SIGEV_INTR;
|
int_event.sigev_notify = SIGEV_INTR;
|
||||||
|
|
||||||
// register an interrupt handler
|
// Attach interrupt handler
|
||||||
id = InterruptAttach( int_n, &handler, NULL, 0, 0 );
|
id = InterruptAttach( interrupt_n, &handler, NULL, 0, 0 );
|
||||||
|
|
||||||
if ( id == -1 )
|
if ( id == -1 )
|
||||||
{
|
{
|
||||||
perror( " Cannot attach interrupt handler " );
|
perror( "Cannot attach interrupt handler" );
|
||||||
return (-1);
|
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 )
|
while ( 1 )
|
||||||
{
|
{
|
||||||
InterruptWait( 0, NULL );
|
InterruptWait( 0, NULL );
|
||||||
|
|
||||||
printf( "Got interrupt %lu ( 0x%lX ) #%4ld\n", int_n, int_n, int_conter );
|
if ( int_counter )
|
||||||
InterruptUnmask( int_n, id );
|
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 );
|
InterruptDetach( id );
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
%C - interrupt attach
|
%C - interrupt attach
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
i <num> - Attach interrupt handler for interrupt <num> (InterruptAttach() is used).
|
-i interrupt_num Attach interrupt handler for interrupt <num>.
|
||||||
Interrupt is masked in interrupt handler and then unmasked in main thread.
|
-m Mask interrupt in interrupt handler and then unmask in main thread.
|
||||||
|
-p period_ms Count number of interrupts for specified period.
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user