迁移中断GPIO程序在DOS中可用于Linux

时间:2014-09-11 11:05:02

标签: c linux

我正在编写一个需要将输入脉冲计数到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;
 }

0 个答案:

没有答案