📄 timer_interrupts.c
字号:
/*++
*
* Copyright (c) 1998-2005 Ardence, Inc. All rights reserved.
*
* Nodule Name:
*
* Timer_Interrupts.c
*
* Abstract:
*
* Sample RTX application that uses a PCIDIO96 interrupt cards.
* This sample shows the used of AttachInterruptVector.
*
*
* Environment:
*
* RTX application
*
--*/
#include <windows.h>
#include <rtapi.h>
#include "pcidio96registeraddressmap.h"
#define MAX_INT_STAT 10
BOOLEAN RTAPI respond(PVOID); // Interrupt service thread
RTFCNDCL fast_respond(PVOID); // Interrupt service routine
void initialize_board(void);
ULONG start_counter(ULONG);
void stop_counter(void);
ULONG is_my_interrupt(void);
void clear_interrupt(void);
ULONG pass_interrupt_to_next(void);
int append_interrupt_stat(int, PULONG);
int print_interrupt_stat(void);
HANDLE alloc_shared_memory(PVOID *);
void initialize_shared_mem(PVOID);
typedef struct counter_stat
{
LARGE_INTEGER time;
ULONG status[10];
int status_num;
} COUNTER_STAT;
COUNTER_STAT int_stat[MAX_INT_STAT+20];
int int_stat_num=0;
LARGE_INTEGER init_time, current_time;
typedef struct board_init_structure
{
LARGE_INTEGER init_time;
LARGE_INTEGER previous_time;
ULONG initialized;
ULONG TimerDelay;
ULONG int_input;
ULONG int_serviced;
ULONG busy;
} BOARD_INIT_STRUCT;
#define MAX_ACTIVE_BOARDS 16
typedef struct shared_boards_info_structure
{
ULONG active_num;
BOARD_INIT_STRUCT boards[MAX_ACTIVE_BOARDS];
} SHARED_BOARDS_INFO;
BOARD_INIT_STRUCT *shared_board_data;
int board_is_initialized(int, BOARD_INIT_STRUCT *);
int board_is_cleared(int number);
// Variables used for this specific test
LPCTSTR lpName = "SharedInterrupMutex";
ULONG IntCountTotal = 0; // total int count
ULONG MineIntCountTotal = 0; // total int count
BOOLEAN IntDone = FALSE; // when we are done
PCHAR _base_addr; // defined in pcidio96registeraddressmap.h
INT cardNumber = 1; // PCI card to detect
INT IsrUsage=0;
INT initialized;
INT IntPass=0;
ULONG pass_interrupt=2;
// Variables used for attaching tests interrupt
ULONG Priority = 126;
ULONG IrqLevel; // interrupt level
BOOLEAN Shared = TRUE;
ULONG TimerDelay=32000;
HANDLE ShMemMutex;
HANDLE shared_mem_all;
LPCTSTR shared_mem_all_name = "PCI_DIO_96_SharedMemAll";
PVOID pSharedMem;
BOARD_INIT_STRUCT board;
void
main( int argc, PCHAR *argv )
{
// Variables used to find and initialize the card.
PVOID isr_func;
PVOID ihr; // interrupt handler
ULONG IntBusNumber; // Interrupt bus number
ULONG IrqVectr; // interrupt vector
UCHAR buffer[PCI_COMMON_HDR_LENGTH];
PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG) buffer;
PCI_SLOT_NUMBER SlotNumber;
ULONG sl_time=0, max_repeat;
INT Clean = 1; // If 1 the test will call RtReleaseInterrupt before exiting
// If 2 the test will use RtPrintf and sleep to allow tester to
// use Windows NT Diagnostict to verify resource use
//
// accessing command-line arguments
//
if ((argc != 1))
{
if ((argc == 7))
{
cardNumber = atoi(argv[1]);
Shared = atoi(argv[2]);
Priority = atoi(argv[3]);
Clean = atoi(argv[4]);
IsrUsage = atoi(argv[5]);
TimerDelay = atoi(argv[6]);
}
else
{
RtPrintf("CardNumber: integer specifying which card to use\n");
RtPrintf("Shared: integer, 1 = shared interrupt mode, 0 = nonshared interrupt mode\n");
RtPrintf("Priority: integer, the priority for the interrupt\n");
RtPrintf("Clean: integer, setting exit option\n");
RtPrintf(" 0: exit after collecting and printing statistics or 10 seconds\n");
RtPrintf(" 1: exit after collecting and printing 1 statistic\n");
RtPrintf(" 2: exit after collecting and printing 1 statistic, but before calls RtPrintf and sleep to\n");
RtPrintf(" allow tester to use Windows NT Diagnostics to verify resource usage\n");
RtPrintf(" >2: exit after collecting and printing 1 statistics or (Clean) seconds\n");
RtPrintf("IsrUsage: integer, specifies ISR and IST usage\n");
RtPrintf(" If >10 - will pass interrupt to next shared application for this board\n");
RtPrintf(" IsrUsage%10 :\n");
RtPrintf(" 0: IST only, clears interrupt after delay\n");
RtPrintf(" 1: ISR and IST, IST clears interrupt after delay\n");
RtPrintf(" 2: ISR and IST, ISR clears interrupt without delay\n");
RtPrintf(" 3: ISR only, clears interrupt after delay\n");
RtPrintf(" >=4: ISR only, clears interrupt without delay\n");
RtPrintf("TimerDelay: integer, timer delay in mks\n");
RtPrintf("\nDefault: PciDio96_test1 1 1 126 10 0 32000\n\n");
ExitProcess(1);
}
}
RtPrintf("cardNumber=%d Shared=%d Priority=%d Clean=%d IsrUsage=%d, TimerDelay=%d\n",
cardNumber, Shared, Priority, Clean, IsrUsage, TimerDelay);
if (IsrUsage >= 10)
{
IsrUsage = IsrUsage%10;
IntPass = 1;
}
else
IntPass = 0;
//
// Search for the PCI-DIO-96 cards ,
//
if((IntBusNumber = PciDio96_Search(cardNumber, &SlotNumber, PciData))== -1) // not found
PciDio96_Fail("WARNING: No PCI-DIO-96 card was found in this machine.");
//
// Our device is found, initialize it
//
if(( _base_addr = PciDio96_Init(IntBusNumber, &SlotNumber, PciData)) == NULL)
{
PciDio96_Cleanup(NULL, Clean);
PciDio96_Fail("PCI-DIO-96 card initialization failed.");
}
if( !(ShMemMutex = RtCreateMutex(NULL, FALSE, lpName)))
PciDio96_Fail("Unable to create mutex, test can't continue.");
shared_mem_all = alloc_shared_memory(&pSharedMem);
if (shared_mem_all == NULL)
{
PciDio96_Cleanup(NULL, Clean);
PciDio96_Fail("PCI-DIO-96 shared memory initialization failed.");
}
// Save IRQ values for attaching interrupt below
IrqLevel = PciData->u.type0.InterruptLine; // interrupt level
IrqVectr = IrqLevel; // interrupt IRQ
board.TimerDelay = TimerDelay;
board.int_input = IrqLevel;
if ((initialized = board_is_initialized(cardNumber, &board)) == 0)
{
initialize_board();
RtPrintf("\nPCI-DIO-96 card %d initialized.\n", cardNumber);
}
else
RtPrintf("\nPCI-DIO-96 card %d was initialized before.\n", cardNumber);
//
// At this point the card has been initialized and is now ready to use.
// Print out user information.
//
RtPrintf("------------------------------\n");
RtPrintf("IRQ: %d\n", IrqLevel);
RtPrintf("Priority: %d\n", Priority);
if(Shared)
RtPrintf("Shared Mode\n");
else
RtPrintf("Non Shared Mode\n");
if (IsrUsage == 0)
{
isr_func = NULL;
RtPrintf("IST only, clears interrupt after delay\n");
}
else
{
isr_func = fast_respond;
if (IsrUsage == 1)
RtPrintf("ISR and IST, IST clears interrupt after delay\n");
else if (IsrUsage == 2)
RtPrintf("ISR and IST, ISR clears interrupt without delay\n");
else if (IsrUsage == 3)
RtPrintf("ISR only, clears interrupt after delay\n");
else
RtPrintf("ISR only, clears interrupt without delay\n");
}
if (IntPass > 0)
RtPrintf("Interrupt will be passed to the next ISR or IST for this board\n");
RtPrintf("\n\n");
if (Clean == 0)
max_repeat = 10;
else
max_repeat = Clean;
//
// Attempt to attach to this interrupt, using data acquired above
//
ihr = RtAttachInterruptVectorEx(NULL, // security attributes (default)
0, // stacksize (default)
respond, // interrupt handler
NULL, // context argument
Priority,
PCIBus, // interface type
IntBusNumber, // bus number
IrqLevel, // interrupt level
IrqVectr, // interrupt vector
Shared, // Shared
LevelSensitive,
isr_func //fast_respond
);
if(!ihr)
{
PciDio96_Cleanup(NULL, Clean);
board_is_cleared(cardNumber);
PciDio96_Fail("Could not attach interrupt for this card.");
}
if (initialized == 0)
{
RtGetClockTime(CLOCK_FASTEST, &init_time);
shared_board_data->init_time = init_time;
shared_board_data->previous_time = init_time;
shared_board_data->TimerDelay = start_counter(TimerDelay);
}
else
{
init_time = shared_board_data->init_time;
TimerDelay = shared_board_data->TimerDelay/2;
}
//
// Begin interrupt test.
//
while(1)
{
if (IntDone)
{
if ((Clean == 1) || (Clean == 2))
break;
else
{
print_interrupt_stat();
IntDone = 0;
}
}
Sleep(1000);
sl_time++;
if (sl_time > max_repeat)
break;
}
//
// Stop interrupt test. Clean up before exit.
//
if (board_is_cleared(cardNumber) == 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -