我正在编写一个需要将输入脉冲计数到PC104
的应用程序。
我正在使用Puppy Linux
。我在DOS
中有一个用于中断GPIO
的示例程序,但现在在Linux中迁移该代码时遇到了问题。任何人都可以通过这种方法或任何其他方法帮助我满足我的要求吗?
这是DOS代码:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<dos.h>
typedef void interrupt (far *FNISR) (...);
FNISR _pfnOldIsr;
unsigned int _nIrqNo;
unsigned int _nIntNo;
unsigned int _nOldImr;
unsigned int _nOldImr2;
static unsigned long _lCnt = 0;
void interrupt NewIsr(...)
{
cprintf("IRQ %d trigger. (%lu)\r", _nIrqNo, _lCnt++);
outp(0x9f, 0xff);
if(_nIrqNo > 7)
outp(0xa0, 0x20); //**
outp(0x20, 0x20);
// send EOI command
}
// Disable warning message "Parameter xxx is never used
#pragma warn –par
// Write south bridge register
void write_sb(unsigned char idx, unsigned long val)
{
_asm mov dx, 0cf8h
__emit__(0x66); __emit__(0xb8);
__emit__(0x00); __emit__(0x38);
__emit__(0x00); __emit__(0x80);
_asm mov al, idx
__emit__(0x66); __emit__(0xef);
_asm mov dx, 0cfch
__emit__(0x66); __emit__(0x8b); __emit__(0x46); __emit__(0x08);
__emit__(0x66); __emit__(0xef);
}
int main(int nArgCnt, char *pszArg[])
{
if(nArgCnt != 2)
{
printf("\nUsage: %s <IRQ_NUM> \n", pszArg[0]);
return 1;
}
// Install ISR for IRQ
_disable();
_nIrqNo = atoi(pszArg[1]);
_nIntNo = (_nIrqNo <= 7) ? (_nIrqNo + 8) : (_nIrqNo + 0x70 - 0x08);
_pfnOldIsr = getvect(_nIntNo);
setvect(_nIntNo, NewIsr);
unsigned char byMask = 0x00;
switch(_nIrqNo)
{
case 9:byMask = 0x01;break;
case 3:byMask = 0x02;break;
case 10:byMask = 0x03;break;
case 4:byMask = 0x04; break;
case 5:byMask = 0x05; break;
case 7:byMask = 0x06; break;
case 6:byMask = 0x07; break;
case 1:byMask = 0x08; break;
case 11: byMask = 0x09; break;
case 12: byMask = 0x0b; break;
case 14: byMask = 0x0d; break;
case 15: byMask = 0x0f; break;
}
if(byMask == 0x00)
{
printf("\nError IRQ number.\n");
return 1;
}
printf("Using IRQ %d\n", _nIrqNo);
// set 8259 interrupt controller
if(_nIrqNo <= 8)
{
_nOldImr = inp(0x21);
outp(0x21, _nOldImr & (~(1 << _nIrqNo)));
}
else
{
_nOldImr = inp(0x21);
outp(0x21, _nOldImr & (~(1 << 2)));
_nOldImr2 = inp(0xa1);
outp(0xa1, _nOldImr2 & (~(1 << (_nIrqNo - 8))));
}
printf("Test Port0: active low, trigger once\r\n");
unsigned long val = 0xffff0000L | ((0xA0 | byMask) << 8);
val = ((val << 8) | 0x0000ffffL) & 0x00ffffffL;
write_sb(0xdc, val);
_enable();
getch();
_disable();
write_sb(0xdc, 0x0000ff00L);
if(_nIrqNo <= 8)
{
outp(0x21, _nOldImr);
}
else
{
outp(0x21, _nOldImr);
outp(0xa1, _nOldImr2);
}
setvect(_nIntNo, _pfnOldIsr);
return 0;
}