S3C6410外部中断问题

时间:2022-03-24 12:21:27
请教一下:
    最近遇到一个问题:我在S3C6410的两个IO口外接了读卡器,通过IO外部中断来读卡数据,但是实际测试时发现数据正确率较低,经常会读错数据,始终找不到问题在哪里?以下附上中断驱动和应用程序,麻烦大家帮我看哈!

DWORD
EIN_Init(DWORD dwContext)
{
       Button_initialize_register_address((void *)g_pGPIOReg);

    // Interrupt Disable and Clear Pending
   // Button_EINT8btn_disable_interrupt();
 g_pGPIOReg->EINT0MASK |= (0x1<<8);    // Mask EINT8
   // Button_EINT9btn_disable_interrupt();
 g_pGPIOReg->EINT0MASK |= (0x1<<9);        // Mask EINT9

    // Initialize Port as External Interrupt
g_pGPIOReg->GPNCON &= 0xfff0ffff;//gpn8/9 set as eint8/9
g_pGPIOReg->GPNCON |= 0x000a0000;
g_pGPIOReg->EINT0CON0 &= 0xfff0ffff;//Setting the signaling method of the EINT9 and EINT8 as Falling edge triggered
g_pGPIOReg->EINT0CON0 |= 0x00030000;

    // Create Eint8 Thread
    g_hThreadEint8Btn = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Eint8Thread, NULL, 0, NULL);
    if (g_hThreadEint8Btn == NULL )
    {
        RETAILMSG(1,(TEXT("[EINT:ERR] EINT_Init() : CreateThread() EINT8 Failed \n\r")));
        goto CleanUp;
    }

    // Create Eint8 Thread
    g_hThreadEint9Btn = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Eint9Thread, NULL, 0, NULL);
    if (g_hThreadEint9Btn == NULL )
    {
        RETAILMSG(1,(TEXT("[EINT:ERR] EINT_Init() : CreateThread() EINT9 Failed \n\r")));
        goto CleanUp;
    }
。。。。。。。。。
}

INT WINAPI Eint8Thread(void)
{
    DWORD nBtnCount = 0;

//RETAILMSG(TRUE,(_T("[EINT:INF] Eint8Thread()\r\n")));

    while(!g_bExitThread)
    {
        WaitForSingleObject(g_hEventEint8Btn, INFINITE);

        if(g_bExitThread)
        {
            break;
        }

SetEvent(gReadEintEvent[0]); /* 通知读函数, 外部中断到来 */  
  
        InterruptDone(g_dwSysIntrEint8Btn);

        nBtnCount++;
       
    }
    return 0;
}


INT WINAPI Eint9Thread(void)
{
DWORD nBtnCount = 0;
   

    while(!g_bExitThread)
    {
        WaitForSingleObject(g_hEventEint9Btn, INFINITE);

        if(g_bExitThread)
        {
            break;
        }

SetEvent(gReadEintEvent[1]); /* 通知读函数, 外部中断到来 */  
        InterruptDone(g_dwSysIntrEint9Btn);


    }

  nBtnCount++;
       //RETAILMSG(1,(TEXT("[EINT] Eint9 Button Event [%d]\r\n"), nBtnCount));

    return 0;
}


DWORD EIN_Read (DWORD pContext, LPVOID pBuf, DWORD Len)
{
DWORD ret;
 /* 挂起当前线程,直到Eint8到来按键按下或Eint9到来 */   
// RETAILMSG(1,(TEXT("EIN_Read\n")));
// RETAILMSG(1,(TEXT("[EINT] EINT_Read(0x%08x, 0x%08x, 0x%08x)\r\n"), pContext, pBuf, Len)); 
// RETAILMSG(1,(TEXT("[EINT] pReadBuffer=(0x%08x)\r\n"), pReadBuffer)); 
unsigned char * pReadBuffer;
pReadBuffer = (unsigned char*)MapPtrToProcess(pBuf, GetCallerProcess()); 
    ret = WaitForMultipleObjects(2, gReadEintEvent, FALSE, INFINITE);  

if( ret==WAIT_OBJECT_0)
{
//RETAILMSG(1,(TEXT("[EINT] EINT8->WG1\r\n")));

*pReadBuffer =1;
ResetEvent(gReadEintEvent[0]);   //EINT8->WG1


}
 if (ret==WAIT_OBJECT_0+1)
{
//RETAILMSG(1,(TEXT("[EINT] EINT9->WG0\r\n")));

*pReadBuffer =0; 
ResetEvent(gReadEintEvent[1]);   //EINT9->WG0


}
 return 1;
}

以下为应用程序部分,读取数据

WaitThread(LPVOID lparam)
{

BYTE status=0;
unsigned char get;
DWORD actlen;

TRACE(L"WaitThread \n");

while(1)
{

if (ReadFile(hDrv,&status, 1, &actlen, NULL) == TRUE) 
{

//printf("status=%d\n",status);
if(status == 1)
{
data_buf[byte_cnt] |= mask;

//OutputDebugString(L" ReadFile data 1..\r\n");
}
else if(status == 0)
{

data_buf[byte_cnt] &= ~mask;
//OutputDebugString(L" ReadFile data 0..\r\n");
}

mask >>= 1;
bit_cnt++;

if (mask == 0)
{
//printf("data_buf[%d]=%d",byte_cnt,data_buf[byte_cnt]);
mask = 0x80;
byte_cnt++;

}

if(bit_cnt==26)
{
resume_wg26_data();



}
else
{
printf("GetLastError()=%d",GetLastError());
OutputDebugString(L"Failed to ReadFile..\r\n");
break;
}

 }


return 0;


}

20 个解决方案

#1


问题补充:
    就是韦根读卡,有时候很容易读,有时候又半天读不对,不知道问题出在哪里啊

#2


看看时序是不是正确,还有就是如果要发送命令,在命令发送完后等待一下再读数据,试试看

#3


谢谢guetcw,
卡数据位与位的时间间隔为2ms,你的意思是我调用ReadFile太快了吗?在应用程序的while循环中应该加上延时吗

#4


不清楚你的具体情况,你的两个IO口用的是什么通信协议

#5


就是用的标准韦根26协议
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢

#6


再仔细测了一下,发现读卡时,中间会出现1、2位读不到的情况,导致整个数据错误。

#7


如果是在脉冲驱动下一位一位读的,那可能是时序不对,是不是太快了,外部读卡器来不及送出数据

#8


我在Eint8Thread和Eint9Thread加了延时函数,感觉出错少些了,但还是有错误,难道是读的太快了

#9


在最底层的操作那两个IO口的地方加,你的ReadFile是调用哪个驱动的

#10


我参照6410的PowerButton写的EINT8,EINT9外部中断驱动,就是贴出来的部分,ReadFile就是调用的它。
你的意思我应该在OAL层里添加延时,对吗

#11


我在中断触发的事件Eint8Thread和Eint9Thread里分别打印1,0,读卡错误时,就只打印24位或25位出来,是不是中断没有触发到呢

#12


引用 5 楼 wlily123 的回复:
就是用的标准韦根26协议
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢

今天第一次知道韦根26协议,^_^,暂时不了解,应该还是时序方面的问题。

#13


会不会是wince的中断处理机制影响了系统的实时性,在中断快速到来的时候,造成某些中断不能及时得到响应呢?

#14


wince的实时性是比较差的,但是很多接口控制器都会有缓冲器,一般驱动没问题的话是不会丢数据的,你现在都把注意力放在那两个按键中断上没什么用的,要去分析正真去读数据的那个底层驱动,也就是ReadFile调用的那个驱动。

#15


LZ 是否有設 Thread Priority?? 是否有考慮過 ISR-IST Latency.

WinCE6 號稱是 Hard Real-Time 的 OS, 但 CPU 只有一個 Core, 所以同時只能根據 Priority 執行一個 Thread, 故不代表你的每一個 Thread 都是 Real-Time, 必須自行調整 Priority.

Paul, Chao @ Techware

#16


谢谢两位的解答,之前没有接触过wince,理解起来还比较困难~
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况

ISR-IST Latency应该不超过1ms,应该没什么影响吧

#17


引用 16 楼 wlily123 的回复:
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况
ISR-IST Latency应该不超过1ms,应该没什么影响吧


那可不一定, 但若是沒設 priority 的話, 保證是會有可能超過的

建議 LZ 在 IST 中加入
/C++CeSetThreadPriority(GetCurrentThread(), 80);


一般應是有改善

Paul, Chao @ Techware

#18


不好意思,最近忙其他的取了。
我在两个IST:Eint8Thread和Eint9Thread两个线程里用CeGetThreadPriority(GetCurrentThread())函数得到,两个的线程优先级都为0啊,就是说两个线程是相同的优先级了?

我又在应用程序的读线程里把线程优先级从251改成了5,感觉真的有改善,但还是会有错误产生,具体原因还是不明白啊

#19


我把两个中断对应一个IST,来一次中断就进行计数,但是测试还是有问题:读卡应该有26次中断,但是计数有时候只有25次,或24次,也就是有中断没有响应到的情况

#20


问题还没有解决,不过感谢各位的解答了
先结贴了,有新想法再讨论了

#1


问题补充:
    就是韦根读卡,有时候很容易读,有时候又半天读不对,不知道问题出在哪里啊

#2


看看时序是不是正确,还有就是如果要发送命令,在命令发送完后等待一下再读数据,试试看

#3


谢谢guetcw,
卡数据位与位的时间间隔为2ms,你的意思是我调用ReadFile太快了吗?在应用程序的while循环中应该加上延时吗

#4


不清楚你的具体情况,你的两个IO口用的是什么通信协议

#5


就是用的标准韦根26协议
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢

#6


再仔细测了一下,发现读卡时,中间会出现1、2位读不到的情况,导致整个数据错误。

#7


如果是在脉冲驱动下一位一位读的,那可能是时序不对,是不是太快了,外部读卡器来不及送出数据

#8


我在Eint8Thread和Eint9Thread加了延时函数,感觉出错少些了,但还是有错误,难道是读的太快了

#9


在最底层的操作那两个IO口的地方加,你的ReadFile是调用哪个驱动的

#10


我参照6410的PowerButton写的EINT8,EINT9外部中断驱动,就是贴出来的部分,ReadFile就是调用的它。
你的意思我应该在OAL层里添加延时,对吗

#11


我在中断触发的事件Eint8Thread和Eint9Thread里分别打印1,0,读卡错误时,就只打印24位或25位出来,是不是中断没有触发到呢

#12


引用 5 楼 wlily123 的回复:
就是用的标准韦根26协议
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢

今天第一次知道韦根26协议,^_^,暂时不了解,应该还是时序方面的问题。

#13


会不会是wince的中断处理机制影响了系统的实时性,在中断快速到来的时候,造成某些中断不能及时得到响应呢?

#14


wince的实时性是比较差的,但是很多接口控制器都会有缓冲器,一般驱动没问题的话是不会丢数据的,你现在都把注意力放在那两个按键中断上没什么用的,要去分析正真去读数据的那个底层驱动,也就是ReadFile调用的那个驱动。

#15


LZ 是否有設 Thread Priority?? 是否有考慮過 ISR-IST Latency.

WinCE6 號稱是 Hard Real-Time 的 OS, 但 CPU 只有一個 Core, 所以同時只能根據 Priority 執行一個 Thread, 故不代表你的每一個 Thread 都是 Real-Time, 必須自行調整 Priority.

Paul, Chao @ Techware

#16


谢谢两位的解答,之前没有接触过wince,理解起来还比较困难~
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况

ISR-IST Latency应该不超过1ms,应该没什么影响吧

#17


引用 16 楼 wlily123 的回复:
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况
ISR-IST Latency应该不超过1ms,应该没什么影响吧


那可不一定, 但若是沒設 priority 的話, 保證是會有可能超過的

建議 LZ 在 IST 中加入
/C++CeSetThreadPriority(GetCurrentThread(), 80);


一般應是有改善

Paul, Chao @ Techware

#18


不好意思,最近忙其他的取了。
我在两个IST:Eint8Thread和Eint9Thread两个线程里用CeGetThreadPriority(GetCurrentThread())函数得到,两个的线程优先级都为0啊,就是说两个线程是相同的优先级了?

我又在应用程序的读线程里把线程优先级从251改成了5,感觉真的有改善,但还是会有错误产生,具体原因还是不明白啊

#19


我把两个中断对应一个IST,来一次中断就进行计数,但是测试还是有问题:读卡应该有26次中断,但是计数有时候只有25次,或24次,也就是有中断没有响应到的情况

#20


问题还没有解决,不过感谢各位的解答了
先结贴了,有新想法再讨论了

#21