最近遇到一个问题:我在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循环中应该加上延时吗
卡数据位与位的时间间隔为2ms,你的意思是我调用ReadFile太快了吗?在应用程序的while循环中应该加上延时吗
#4
不清楚你的具体情况,你的两个IO口用的是什么通信协议
#5
就是用的标准韦根26协议
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢
#6
再仔细测了一下,发现读卡时,中间会出现1、2位读不到的情况,导致整个数据错误。
#7
如果是在脉冲驱动下一位一位读的,那可能是时序不对,是不是太快了,外部读卡器来不及送出数据
#8
我在Eint8Thread和Eint9Thread加了延时函数,感觉出错少些了,但还是有错误,难道是读的太快了
#9
在最底层的操作那两个IO口的地方加,你的ReadFile是调用哪个驱动的
#10
我参照6410的PowerButton写的EINT8,EINT9外部中断驱动,就是贴出来的部分,ReadFile就是调用的它。
你的意思我应该在OAL层里添加延时,对吗
你的意思我应该在OAL层里添加延时,对吗
#11
我在中断触发的事件Eint8Thread和Eint9Thread里分别打印1,0,读卡错误时,就只打印24位或25位出来,是不是中断没有触发到呢
#12
今天第一次知道韦根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
WinCE6 號稱是 Hard Real-Time 的 OS, 但 CPU 只有一個 Core, 所以同時只能根據 Priority 執行一個 Thread, 故不代表你的每一個 Thread 都是 Real-Time, 必須自行調整 Priority.
Paul, Chao @ Techware
#16
谢谢两位的解答,之前没有接触过wince,理解起来还比较困难~
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况
ISR-IST Latency应该不超过1ms,应该没什么影响吧
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况
ISR-IST Latency应该不超过1ms,应该没什么影响吧
#17
那可不一定, 但若是沒設 priority 的話, 保證是會有可能超過的
建議 LZ 在 IST 中加入
/C++CeSetThreadPriority(GetCurrentThread(), 80);
一般應是有改善
Paul, Chao @ Techware
#18
不好意思,最近忙其他的取了。
我在两个IST:Eint8Thread和Eint9Thread两个线程里用CeGetThreadPriority(GetCurrentThread())函数得到,两个的线程优先级都为0啊,就是说两个线程是相同的优先级了?
我又在应用程序的读线程里把线程优先级从251改成了5,感觉真的有改善,但还是会有错误产生,具体原因还是不明白啊
我在两个IST:Eint8Thread和Eint9Thread两个线程里用CeGetThreadPriority(GetCurrentThread())函数得到,两个的线程优先级都为0啊,就是说两个线程是相同的优先级了?
我又在应用程序的读线程里把线程优先级从251改成了5,感觉真的有改善,但还是会有错误产生,具体原因还是不明白啊
#19
我把两个中断对应一个IST,来一次中断就进行计数,但是测试还是有问题:读卡应该有26次中断,但是计数有时候只有25次,或24次,也就是有中断没有响应到的情况
#20
问题还没有解决,不过感谢各位的解答了
先结贴了,有新想法再讨论了
先结贴了,有新想法再讨论了
#21
#1
问题补充:
就是韦根读卡,有时候很容易读,有时候又半天读不对,不知道问题出在哪里啊
就是韦根读卡,有时候很容易读,有时候又半天读不对,不知道问题出在哪里啊
#2
看看时序是不是正确,还有就是如果要发送命令,在命令发送完后等待一下再读数据,试试看
#3
谢谢guetcw,
卡数据位与位的时间间隔为2ms,你的意思是我调用ReadFile太快了吗?在应用程序的while循环中应该加上延时吗
卡数据位与位的时间间隔为2ms,你的意思是我调用ReadFile太快了吗?在应用程序的while循环中应该加上延时吗
#4
不清楚你的具体情况,你的两个IO口用的是什么通信协议
#5
就是用的标准韦根26协议
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢
两个IO口设为外部中断,对应Data0,Data1,通过中断读取数据。感觉就是数据读错了,就是中断一次读一位,不知道应该怎么设时序呢
#6
再仔细测了一下,发现读卡时,中间会出现1、2位读不到的情况,导致整个数据错误。
#7
如果是在脉冲驱动下一位一位读的,那可能是时序不对,是不是太快了,外部读卡器来不及送出数据
#8
我在Eint8Thread和Eint9Thread加了延时函数,感觉出错少些了,但还是有错误,难道是读的太快了
#9
在最底层的操作那两个IO口的地方加,你的ReadFile是调用哪个驱动的
#10
我参照6410的PowerButton写的EINT8,EINT9外部中断驱动,就是贴出来的部分,ReadFile就是调用的它。
你的意思我应该在OAL层里添加延时,对吗
你的意思我应该在OAL层里添加延时,对吗
#11
我在中断触发的事件Eint8Thread和Eint9Thread里分别打印1,0,读卡错误时,就只打印24位或25位出来,是不是中断没有触发到呢
#12
今天第一次知道韦根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
WinCE6 號稱是 Hard Real-Time 的 OS, 但 CPU 只有一個 Core, 所以同時只能根據 Priority 執行一個 Thread, 故不代表你的每一個 Thread 都是 Real-Time, 必須自行調整 Priority.
Paul, Chao @ Techware
#16
谢谢两位的解答,之前没有接触过wince,理解起来还比较困难~
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况
ISR-IST Latency应该不超过1ms,应该没什么影响吧
我没有设线程优先级,我想每两个中断间隔2ms的话,应该不会产生同时来两个中断的情况
ISR-IST Latency应该不超过1ms,应该没什么影响吧
#17
那可不一定, 但若是沒設 priority 的話, 保證是會有可能超過的
建議 LZ 在 IST 中加入
/C++CeSetThreadPriority(GetCurrentThread(), 80);
一般應是有改善
Paul, Chao @ Techware
#18
不好意思,最近忙其他的取了。
我在两个IST:Eint8Thread和Eint9Thread两个线程里用CeGetThreadPriority(GetCurrentThread())函数得到,两个的线程优先级都为0啊,就是说两个线程是相同的优先级了?
我又在应用程序的读线程里把线程优先级从251改成了5,感觉真的有改善,但还是会有错误产生,具体原因还是不明白啊
我在两个IST:Eint8Thread和Eint9Thread两个线程里用CeGetThreadPriority(GetCurrentThread())函数得到,两个的线程优先级都为0啊,就是说两个线程是相同的优先级了?
我又在应用程序的读线程里把线程优先级从251改成了5,感觉真的有改善,但还是会有错误产生,具体原因还是不明白啊
#19
我把两个中断对应一个IST,来一次中断就进行计数,但是测试还是有问题:读卡应该有26次中断,但是计数有时候只有25次,或24次,也就是有中断没有响应到的情况
#20
问题还没有解决,不过感谢各位的解答了
先结贴了,有新想法再讨论了
先结贴了,有新想法再讨论了