|
初学CE,平台是S3C2440 + wince5.0
在网上找了个周立功的按键中断流驱动程序,就按着这个程序开始写了个串口流驱动,程序在WaitForSingleObject()处停止了,无法进入线程处理。可能是什么原因呀?
com0是CE调试串口,我写的驱动是对com1操作。
以下是部分程序代码:
#define UART1_BASE 0xB1000000
#define IOP_BASE 0xB1600000
/* UART1 的物理中断号及逻辑中断号 */
PRIVATE UINT32 g_EINTIrq = IRQ_UART1; //23
PRIVATE UINT32 g_EINTSysIntr = SYSINTR_UNDEFINED;
PRIVATE VOID UART1_Config(VOID)
{
int i;
RETAILMSG(1,(TEXT("\n-----> Access UART1_Config().\r\n")));
//设置IO口为RXD1,TXD1
v_pIOPregs->GPHCON &= ~(3 << 8);
v_pIOPregs->GPHCON |= 2 << 8;
v_pIOPregs->GPHCON &= ~(3 << 10);
v_pIOPregs->GPHCON |= 2 << 10;
//初始化串口1
v_pUARTregs->UFCON = 0x0; //UART channel 0 FIFO control register, FIFO disable
v_pUARTregs->UMCON = 0x0; //UART chaneel 0 MODEM control register, AFC disable
v_pUARTregs->ULCON = 0x3; //Line control register : Normal,No parity,1 stop,8 bits
v_pUARTregs->UCON = 0x245; // Control register
v_pUARTregs->UBRDIV =( (int)(50000000/16./115200) -1 ); //Baud rate divisior register 0
for(i = 0; i < 0xffff; i++);
RETAILMSG(1,(TEXT("-----> Exit UART1_Config().\r\n\n")));
}
PRIVATE BOOL UART1_InitializeAddresses(VOID)
{
。。。。。。
}
DWORD UART1_IntrThread(PVOID pArg)
{
DWORD ret;
RETAILMSG(1, (TEXT("\n-----> UART1_IntrThread().\r\n")));
// 创建外部中断中断事件
gWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
RETAILMSG(1, (TEXT("::: gWaitEvent = 0x%x.\r\n"), gWaitEvent));
// 初始化外部按键中断: 注册中断事件, 允许外部中断
if (!(InterruptInitialize(g_EINTSysIntr, gWaitEvent, 0, 0)))
{
RETAILMSG(1, (TEXT("ERROR: UART1: InterruptInitialize failed.\r\n")));
CloseHandle(gWaitEvent);
return 0;
}
// 外部按键中断线程开始运行
while (1)
{
RETAILMSG(1, (TEXT("-----> while ( 1 ).\r\n")));
RETAILMSG(1, (TEXT("::: GetLastError() = 0x%x.\r\n"), GetLastError()));
ret = WaitForSingleObject(gWaitEvent, INFINITE); //------------------------------------------->程序一直停在这里?????
RETAILMSG(1, (TEXT("::: GetLastError() = 0x%x.\r\n"), GetLastError()));
RETAILMSG(1, (TEXT("::: ret = 0x%x.\r\n"), ret));
if ((ret == WAIT_OBJECT_0) && (g_bKillIST == FALSE))
{
RETAILMSG(1, (TEXT("if ((ret == WAIT_OBJECT_0) && (g_bKillIST == FALSE)).\r\n")));
if (v_pUARTregs->UTRSTAT & (0x1 << 0)) /* UART1收到一个数据 */
{
SetEvent(gReadKeyEvent[0]); /* 通知读函数, 外部中断按键按键按下 */
RETAILMSG(1, (TEXT("::: UART1 Received. \r\n")));
}
}
else
{
CloseHandle(gWaitEvent);
RETAILMSG(1, (TEXT("::: UART1_IntrThread Exit. \r\n")));
return 0;
} //if (ret != WAIT_OBJECT_0) or Error occurs
RETAILMSG(1, (TEXT("::: while(1){ --- }. \r\n")));
InterruptDone(g_EINTSysIntr); /* 通知内核: 中断处理结束 */
}
RETAILMSG(1, (TEXT("-----> Exit UART1_IntrThread().\r\n\n")));
return 1;
}
PUBLIC DWORD URT_Init(DWORD dwContext)
{
DWORD IDThread;
RETAILMSG(1, (TEXT("\n-----> Access URT_Init().\r\n")));
// 取得 UART1 相关寄存器的虚拟地址空间
if (UART1_InitializeAddresses() == FALSE)
return 0;
//
UART1_Config();
// 从 OAL 请求一个 SYSINTR 值
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_EINTIrq, sizeof(UINT32), &g_EINTSysIntr, sizeof(UINT32), NULL))
{
RETAILMSG(1, (TEXT("ERROR: UART1: Failed to request sysintr value for UART1 interrupt.\r\n")));
return(0);
}
RETAILMSG(1,(TEXT("INF UART1: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_EINTIrq, g_EINTSysIntr));
// 创建一个外部中断处理线程 IST
gEINTIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)UART1_IntrThread, 0, 0, &IDThread);
RETAILMSG(1, (TEXT("::: gEINTIntrThread = 0x%x\r\n"), gEINTIntrThread));
if (gEINTIntrThread == NULL)
{
RETAILMSG(1, (TEXT("::: URT_Init: CreateThread() Fail.\r\n")));
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_EINTSysIntr, sizeof(UINT32), NULL, 0, NULL);
return 0;
}
gReadKeyEvent[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
gReadKeyEvent[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
RETAILMSG(1, (TEXT("::: gReadKeyEvent[0] = 0x%x\r\n"), gReadKeyEvent[0]));
RETAILMSG(1, (TEXT("::: gReadKeyEvent[1] = 0x%x\r\n"), gReadKeyEvent[1]));
RETAILMSG(1, (TEXT("::: URT_Init Sucessfully! \r\n")));
RETAILMSG(1, (TEXT("-----> Exit URT_Init().\r\n\n")));
// 返回不为0的数
return (DWORD)gEINTIntrThread;
}
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("-----> Key: DLL_PROCESS_ATTACH. \r\n")));
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;//挂载成功
case DLL_PROCESS_DETACH:
RETAILMSG(1, (TEXT("-----> Key: DLL_PROCESS_DETACH. \r\n")));
break;//卸载成功
}
return (TRUE);
}
程序编译成功,把生成的DLL下载到开发板上,用流驱动调试工具加载成功,从com0输出的信息看,WaitForSingleObject()前的信息都挺正常的,可我连续往com1发数据时,驱动并未往下执行,好像一直被挂起,没被触发。再用寄存器查看工具,看了com1的所有寄存器,设置与程序一样,UTRSTAT[0] = 1,UFSTAT[0-5] = 我发的单个字节数,正确,URXH = 我发的单个字节数,正确,但是UERSTAT[0]=1溢出错误?是这个问题么?
串口打印的信息如下:
RETAILMSG(1,(TEXT("INF UART1: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_EINTIrq, g_EINTSysIntr));
输出:"INF UART1: Mapped Irq 0x17 to SysIntr 0x1e."
::: gEINTIntrThread = 0x87d964f6.
::: gReadKeyEvent[0] = 0x879d3f8e.
::: gReadKeyEvent[1] = 0x87b65fda.
::: gWaitEvent = 0x6799d9ae.
从上面打印信息可以看出ISR正确关联了吧,可好像ISR没有中断
现在的现象是:我手动从PC上串口调试软件发送1个字节,UERSTAT没有溢出错误,但还是停在WaitForSingleObject();当以1s一个字节自动发送时,UERSTAT溢出标志在0与1间交替变换。什么原因啊?????
我在OEMInterruptHandler()中加了打印信息,发现com1没进中断。而当我在CE中使用串口调试工具时,所调用的串口模型驱动却很正常,打印信息显示中断正常?
这是为什么?我写的流驱动与BSP中的模型驱动有冲突???
我在UART1_Config()中已经设置了寄存器
v_pUARTregs->UCON = 0x245; // Interrupt Type - Level Rx Interrupt Type - Pulse
串口的中断类型也设置了,为什么没触发呢?
而我同样用这个流驱动,做了个EINT0的按键驱动,却可以正常响应。
是不是串口中断部分还要设置其他地方???还要改哪个文件呢?
望大侠们指教!!!!
|
|