wince关闭驱动需要做哪些工作

onelove2009 2011-08-31 04:52:20
最近写了个键盘中断驱动,应用程序通过Creatfile打开驱动,但如果在应用程序关闭前不进行关闭驱动操作下次就无法打开驱动。。。就想把这个关闭动作放在析构函数里,应用程序关闭时自动closehandle,但是第二次打开应用程序根本无法打开。。。
请教大牛:wince关闭驱动需要做哪些工作,在应用程序中如何处理?
...全文
265 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
onelove2009 2011-10-11
  • 打赏
  • 举报
回复
不小心发了两遍。。。大牛们帮帮忙吧。。。
onelove2009 2011-10-11
  • 打赏
  • 举报
回复
HANDLE hFile = INVALID_HANDLE_VALUE;					/* 驱动程序设备句柄 */
DWORD Key1Count = 0;

// 读 KEY1 状态线程
DWORD CKey1ExampleDlg::ReadKey1Thread(LPVOID lparam)
{
BYTE status;
DWORD actlen;
CString strCount;
CKey1ExampleDlg *pDlg = (CKey1ExampleDlg*)lparam; /* 取得对话框指针 */
CStatic *pCountStatic = (CStatic*)pDlg->GetDlgItem(IDC_KEY1_COUNTER);
/* 取得显示计数值的文本框指针 */

while(TRUE)
{
if (hFile == INVALID_HANDLE_VALUE)
break; /* 驱动未打开, 退出线程 */

if (ReadFile(hFile, &status, 1, &actlen, NULL) == TRUE)
{
OutputDebugString(_T("ReadFile(hFile, &status, 1, &actlen, NULL)\r\n"));
if (status == 0x03)
{ /* KEY1 按键按下 */
Key1Count++; /* 计数器计数 */
strCount.Format(_T("%d"), Key1Count);
pCountStatic->SetWindowText(strCount); /* 显示 */
OutputDebugString(_T("STATUS ======= 3\r\n"));
}
else if (status == 0xff)
{ /* KEY1 按键按下 */

OutputDebugString(_T("STATUS ======= ff\r\n"));
}
else if (status == 1)
{ /* KEY1 按键按下 */
Key1Count++; /* 计数器计数 */
strCount.Format(_T("%d"), Key1Count);
pCountStatic->SetWindowText(strCount); /* 显示 */
OutputDebugString(_T("STATUS ======= 3\r\n"));
}
else
{
break;
}
}
else
break;
}

return 1;
}


// "打开驱动" 按键单击事件代码
void CKey1ExampleDlg::OnOpenKey1()
{
DWORD IDThread;
HANDLE hReadKey1Thread; /* 读 KEY1 线程句柄 */

// 打开 KEY1 驱动
hFile = CreateFile(TEXT("KEY1:"), GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox(_T("打开 KEY1 驱动失败!"));
return;
}

// 创建读 KEY1 状态线程
hReadKey1Thread = CreateThread(0, 0, ReadKey1Thread, this, 0, &IDThread);
if (hReadKey1Thread == NULL)
{
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return;
}
CloseHandle(hReadKey1Thread);

// 使能 "关闭驱动" 按键, 禁止 "打开驱动" 按键
CButton *pOpenButton = (CButton*)GetDlgItem(IDC_OPEN_KEY1); /* 取得控件指针 */
CButton *pCloseButton = (CButton*)GetDlgItem(IDC_CLOSE_KEY1); /* 取得控件指针 */
pOpenButton->EnableWindow(FALSE);
pCloseButton->EnableWindow(TRUE);

MessageBox(_T("打开 KEY1 驱动成功!"));
}


// "关闭驱动" 按键单击事件代码
void CKey1ExampleDlg::OnCloseKey1()
{
CButton *pOpenButton = (CButton*)GetDlgItem(IDC_OPEN_KEY1); /* 取得控件指针 */
CButton *pCloseButton = (CButton*)GetDlgItem(IDC_CLOSE_KEY1); /* 取得控件指针 */

if (hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile); /* 关闭驱动 */
hFile = INVALID_HANDLE_VALUE;
pOpenButton->EnableWindow(TRUE); /* 使能"打开驱动"按键 */
pCloseButton->EnableWindow(FALSE); /* 禁止"关闭驱动"按键 */
}
}
onelove2009 2011-10-11
  • 打赏
  • 举报
回复
HANDLE hFile = INVALID_HANDLE_VALUE;					/* 驱动程序设备句柄 */
DWORD Key1Count = 0;

// 读 KEY1 状态线程
DWORD CKey1ExampleDlg::ReadKey1Thread(LPVOID lparam)
{
BYTE status;
DWORD actlen;
CString strCount;
CKey1ExampleDlg *pDlg = (CKey1ExampleDlg*)lparam; /* 取得对话框指针 */
CStatic *pCountStatic = (CStatic*)pDlg->GetDlgItem(IDC_KEY1_COUNTER);
/* 取得显示计数值的文本框指针 */

while(TRUE)
{
if (hFile == INVALID_HANDLE_VALUE)
break; /* 驱动未打开, 退出线程 */

if (ReadFile(hFile, &status, 1, &actlen, NULL) == TRUE)
{
OutputDebugString(_T("ReadFile(hFile, &status, 1, &actlen, NULL)\r\n"));
if (status == 0x03)
{ /* KEY1 按键按下 */
Key1Count++; /* 计数器计数 */
strCount.Format(_T("%d"), Key1Count);
pCountStatic->SetWindowText(strCount); /* 显示 */
OutputDebugString(_T("STATUS ======= 3\r\n"));
}
else if (status == 0xff)
{ /* KEY1 按键按下 */

OutputDebugString(_T("STATUS ======= ff\r\n"));
}
else if (status == 1)
{ /* KEY1 按键按下 */
Key1Count++; /* 计数器计数 */
strCount.Format(_T("%d"), Key1Count);
pCountStatic->SetWindowText(strCount); /* 显示 */
OutputDebugString(_T("STATUS ======= 3\r\n"));
}
else
{
break;
}
}
else
break;
}

return 1;
}


// "打开驱动" 按键单击事件代码
void CKey1ExampleDlg::OnOpenKey1()
{
DWORD IDThread;
HANDLE hReadKey1Thread; /* 读 KEY1 线程句柄 */

// 打开 KEY1 驱动
hFile = CreateFile(TEXT("KEY1:"), GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox(_T("打开 KEY1 驱动失败!"));
return;
}

// 创建读 KEY1 状态线程
hReadKey1Thread = CreateThread(0, 0, ReadKey1Thread, this, 0, &IDThread);
if (hReadKey1Thread == NULL)
{
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return;
}
CloseHandle(hReadKey1Thread);

// 使能 "关闭驱动" 按键, 禁止 "打开驱动" 按键
CButton *pOpenButton = (CButton*)GetDlgItem(IDC_OPEN_KEY1); /* 取得控件指针 */
CButton *pCloseButton = (CButton*)GetDlgItem(IDC_CLOSE_KEY1); /* 取得控件指针 */
pOpenButton->EnableWindow(FALSE);
pCloseButton->EnableWindow(TRUE);

MessageBox(_T("打开 KEY1 驱动成功!"));
}


// "关闭驱动" 按键单击事件代码
void CKey1ExampleDlg::OnCloseKey1()
{
CButton *pOpenButton = (CButton*)GetDlgItem(IDC_OPEN_KEY1); /* 取得控件指针 */
CButton *pCloseButton = (CButton*)GetDlgItem(IDC_CLOSE_KEY1); /* 取得控件指针 */

if (hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile); /* 关闭驱动 */
hFile = INVALID_HANDLE_VALUE;
pOpenButton->EnableWindow(TRUE); /* 使能"打开驱动"按键 */
pCloseButton->EnableWindow(FALSE); /* 禁止"关闭驱动"按键 */
}
}
xiaosan5871 2011-09-29
  • 打赏
  • 举报
回复
看了下,驱动是没有问题的呀!


是你应用程序调用的问题。(不支持多个打开,这是驱动的局限之处)


一般操作的话,在一个button里边,会3行代码连在一起:
createfile,xxx_IOControl,CloseHandle。

如果您非要 只打开一次,然后进行所有操作之后,CloseHandle,那么您另想办法呀

您说的析构函数会死机,应该是您内存释放逻辑的问题~上app代码吧?


onelove2009 2011-09-13
  • 打赏
  • 举报
回复
过完节了,问题还没解决。。。大牛们帮帮忙啊。。。
猫xiaowai 2011-09-07
  • 打赏
  • 举报
回复
大体看了下,不知道对不对:
KEY_IOControl、KEY_Write如果为空的话,应该return 1;

你是在类里面CreateFile的么?
还有析构函数能确定调用了吗。。
onelove2009 2011-09-06
  • 打赏
  • 举报
回复
/*******************************************************************************************
函数名称: KEY_Open
描 述: 打开驱动程序
输入参数: DWORD dwData : 驱动程序引用事例句柄
DWORD dwAccess : 访问请求代码,是读和写的组合
DWORD dwShareMode: 共享模式
输出参数: 无
返 回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD KEY_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
if (gOpenCount > 0)
{
return 0; // 本驱动只允许单一访问
}
gOpenCount = 1;
RETAILMSG(1, (TEXT("::: KEY_Open Successfully! \r\n")));
return gOpenCount;
}

/*******************************************************************************************
函数名称: KEY_Read
描 述: 读取按键标识
输入参数: DWORD Handle : 驱动程序引用事例句柄
LPVOID pBuffer : 接收缓冲区
DWORD dwNumBytes: 要读的字节数
输出参数: 无
返 回: 实际读到字节数
*******************************************************************************************/
DWORD KEY_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
DWORD ret;
uchar* pReadBuffer;
if ((pBuffer == NULL) || (dwNumBytes <= 0))
{
return 0;
}
/*驱动程序和应用程序之间传递数据时何时调用MapPtrToProcess?
因为设备管理器负责加载驱动程序DLL,这意味着当应用程序调用驱动程序接口函数的时候,WINCE内核会将调
用驱动程序接口函数的线程转移到设备管理器的进程空间然后执行具体的驱动程序代码,应用程序和设备管理
器处于两个进程空间,这就造成设备管理器无法访问应用程序传递的指针(虚拟地址),所以当我们在应用程
序中传递指针给流驱动程序接口函数时,WINCE内核从中作了一个地址映射,例如ReadFile、WriteFile、
DeviceIoControl函数的参数凡是指针都经过了映射才传递给驱动程序,所以很多驱动程序开发者并不了解其中
的奥秘就可以编程了。但是如果参数是一个指向一个结构体的指针,而结构体里包括一个或多个指针,那么WINCE
内核并不负责映射,所以就需要开发者在驱动程序接口函数中调用API函数MapPtrToProcess来映射地址。例如:
pPointer_retval = MapPtrToProcess(pPointer, GetCallerProcess()); */
pReadBuffer = (uchar*)MapPtrToProcess(pBuffer, GetCallerProcess()); //pReadBuffer是应用程序的pBuffer在设备管理器上的地址映射!
*pReadBuffer = 0; //是否需要进行强制转换dxj
//*pReadBuffer表示地址里存的内容
/* 挂起当前线程,直到 KEY1 按键按下或驱动关闭 */
v_pIOPregs->rGPBDAT |= (3<<6);
// ret = WaitForMultipleObjects(2, gReadKeyEvent, FALSE, INFINITE);
ret = WaitForSingleObject(gReadKeyEvent[0], INFINITE);
if (ret == WAIT_OBJECT_0)
{
ResetEvent(gReadKeyEvent[0]);
*pReadBuffer = 1; /* 按键按下 */
v_pIOPregs->rGPBDAT &= ~(3<<6);
RETAILMSG (1,(TEXT("%x \r\n"),*pReadBuffer));
RETAILMSG(1, (TEXT("::: KEY_Read Successfully! \r\n")));
return 1;
}
/* else if(ret == (WAIT_OBJECT_0 + 1))
{
ResetEvent(gReadKeyEvent[1]);
*pReadBuffer = 0; // 驱动关闭
RETAILMSG(1, (TEXT("::: KEY_Close Already! \r\n")));
return 1;
}
*/

return 0;

}

/*******************************************************************************************
函数名称: KEY_IOControl
描 述: 驱动程序 I/O 请求
输入参数:
输出参数:
返 回: 本驱动不支持该请求,返回 FALSE
*******************************************************************************************/
BOOL KEY_IOControl(DWORD Handle, DWORD dwIoControlCode, PBYTE pInBuf,
DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
RETAILMSG(1, (TEXT("::: KEY_IOControl Successfully! \r\n")));
return FALSE;
}

/*******************************************************************************************
函数名称: KEY_Write
描 述: 写函数,本驱动不支持
输入参数:
输出参数:
返 回:
*******************************************************************************************/
DWORD KEY_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
RETAILMSG(1, (TEXT("::: KEY_Write Successfully! \r\n")));
return 0;
}

/*******************************************************************************************
函数名称: KEY_Seek
描 述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数:
输出参数:
返 回:
*******************************************************************************************/
DWORD KEY_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
return 0;
}

/*******************************************************************************************
函数名称: KEY_PowerUp
描 述: 电源上电驱动处理函数
输入参数:
输出参数:
返 回: 无
*******************************************************************************************/
void KEY_PowerUp(void)
{
return;
}

/*******************************************************************************************
函数名称: KEY_PowerDown
描 述: 电源下电驱动处理函数
输入参数:
输出参数:
返 回: 无
*******************************************************************************************/
void KEY_PowerDown(void)
{
return;
}

/*******************************************************************************************
函数名称: DllMain
描 述: 驱动程序动态库入口
输入参数:
输出参数:
返 回:
*******************************************************************************************/
BOOL WINAPI DllMain(HANDLE hinstDll, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("KEY_DllMain: DLL_PROCESS_ATTACH\r\n")));
break;

case DLL_PROCESS_DETACH:
RETAILMSG(1, (TEXT("KEY_DllMain: DLL_PROCESS_DETACH\r\n")));
break;
}
return TRUE;
}

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\KeyIntr]
"Prefix"="KEY"
"Dll"="KeyIntr.dll"
"Order"=dword:0
"Index"=dword:1
onelove2009 2011-09-06
  • 打赏
  • 举报
回复
/*******************************************************************************************
函数名称: KeyIntr_Thread
描 述: 外部中断按键服务线程IST,将按键标识敷给全局变量g_KeyNumber
输入参数: PVOID pArg: 线程输入参数
输出参数: 无
返 回: 1 或 0
*******************************************************************************************/
DWORD KeyIntr_Thread(PVOID pArg)
{
DWORD ret;
g_KeyIntr = CreateEvent(NULL, FALSE, FALSE, NULL);
if(g_KeyIntr == NULL)
{
RETAILMSG(1, (TEXT("DEMO:Event creation failed!\r\n")));
return 0;
}
//初始化外部中断事件
if(!(InterruptInitialize(SYSINTR_KEYINT,g_KeyIntr,0,0)))
{
RETAILMSG(1,(TEXT("DEMO:InterruptInitialize failed\r\n")));
CloseHandle(g_KeyIntr);
return 0;
}
RETAILMSG(1, (TEXT("::: InterruptInitialize Successfully! \r\n")));

while (1)
{
RETAILMSG(1, (TEXT("while (1) WaitForSingleObject(g_KeyIntr, INFINITE);\r\n")));
ret = WaitForSingleObject(g_KeyIntr, INFINITE);
if ((ret == WAIT_OBJECT_0) && (g_KillKeyInterIST == FALSE))
{
//InterruptDisable(SYSINTR_KEYINT);//进中断后在未处理完中断IST前先关掉中断; 是应该这么做啊????

InitializeCriticalSection(&cs);//初始化临界区
EnterCriticalSection(&cs);//进入临界区

//进入中断后将I/O口由中断功能转化为输入
//v_pIOPregs->rGPFCON &= (~((3<<4)|(3<<0))) | ((00<<4)|(00<<0)) ; //GPF2,0 set I/O input

//if ((v_s2440INT->rINTPND & BIT_EINT0) | (v_s2440INT->rINTPND & BIT_EINT2))
//{
// v_s2440INT->rINTPND = BIT_EINT0 | BIT_EINT2;
// v_s2440INT->rSRCPND = BIT_EINT0 | BIT_EINT2;
//}

//RETAILMSG(1, (TEXT("Is Key Pushed really?\r\n")));
//RETAILMSG(1, (TEXT("v_pIOPregs->rGPFDAT = 0x%x===========test by dxj\r\n"), v_pIOPregs->rGPFDAT));
if (Key_IsPushed())
{
//Delay(200); /* 延时用于滤去噪声 */
Sleep(20);
if (Key_IsPushed()) /* 外部中断按键确实已按下 */
{
RETAILMSG(1, (TEXT("v_pIOPregs->rGPGDAT = 0x%x===========test by dxj\r\n"), v_pIOPregs->rGPGDAT));
SetEvent(gReadKeyEvent[0]); /* 通知读函数, 外部中断按键按键按下 */
RETAILMSG(1, (TEXT("Interrupt occur,Key has been pressed!========")));
RETAILMSG (1,(TEXT("%x \r\n"),g_KeyNumber));

// v_pIOPregs->rGPBDAT &= ~(3<<6); //扫描结束,GPB6\GPB7从新输出为低电平
//v_pIOPregs->rGPFCON &= (~((3<<4)|(3<<0))) | ((2<<4)|(2<<0)) ; //GPF2,0 set EINT
}
}
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs);//删除临界区
}// if ((ret == WAIT_OBJECT_0) && (g_KillKeyInterIST == FALSE))
else
{
CloseHandle(g_KeyIntr);
RETAILMSG(1, (TEXT("::: EINTKey_IntrThread Exit. \r\n")));
return 0;
} //if (ret != WAIT_OBJECT_0) or Error occurs

InterruptDone(SYSINTR_KEYINT); /* 通知内核: 中断处理结束 */
}
return 1;
}

/*******************************************************************************************
函数名称: SetInterrupt
描 述: 创建中断IST,并设置中断优先级
输入参数: 无
输出参数: 无
返 回: > 0 分配得到的虚拟地址; FALSE: 分配失败
*******************************************************************************************/
void SetInterrupt(void)
{
DWORD IDThread;
int m_KeyIntrPriority;

g_KeyIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)KeyIntr_Thread, 0, 0, &IDThread);
if(g_KeyIntrThread==NULL)
{
RETAILMSG(1,(TEXT("DEMO:Thread creation failed!\r\n")));
return; //如果执行了这句,该函数后面的语句将不再执行
}

m_KeyIntrPriority = 5;
if(!CeSetThreadPriority(g_KeyIntrThread, m_KeyIntrPriority))
{
RETAILMSG(1,(TEXT("DEMO:Failed setting Thread Priority!\r\n")));
return;
}
}

/*******************************************************************************************
函数名称: KEY_Init
描 述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置
输出参数: 无
返 回: 驱动程序句柄
*******************************************************************************************/
DWORD KEY_Init(DWORD dwContext)
{
// 取得 GPIO 相关寄存器的虚拟地址空间
if (EINT_InitializeAddresses() == FALSE)
return 0;
//使能中断 下降沿触发
Port_Init();
g_KeyNumber = 0xff;
SetInterrupt();
gReadKeyEvent[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
// gReadKeyEvent[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
RETAILMSG(1, (TEXT("::: KEY_Init Successfully! \r\n")));
return (DWORD)g_KeyIntrThread;
}

/*******************************************************************************************
函数名称: KEY_Close
描 述: 驱动程序关闭函数
输入参数: DWORD Handle:驱动程序句柄
输出参数: 无
返 回: FALSE: 失败 TRUE: 成功
*******************************************************************************************/
BOOL KEY_Close(DWORD Handle)
{

g_KeyNumber = 0xff;
// if (gOpenCount > 0)
// SetEvent(gReadKeyEvent[1]);
gOpenCount = 0;

RETAILMSG(1, (TEXT("::: KEY_Close Successfully! \r\n")));
return TRUE;
}

/*******************************************************************************************
函数名称: KEY_Deinit
描 述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返 回: FALSE: 失败 TRUE: 成功
*******************************************************************************************/
BOOL KEY_Deinit(DWORD dwContext)
{
SetEvent(g_KeyIntr);
g_KillKeyInterIST = TRUE;
Sleep(200); // 等待中断服务线程退出

// SetEvent(gReadKeyEvent[1]);

InterruptDone(SYSINTR_KEYINT);
InterruptDisable(SYSINTR_KEYINT);

v_pIOPregs->rGPGCON &= (~((3<<6))); //GPG3 set GPIO

if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
gOpenCount = 0;
g_KeyNumber = 0xff;

CloseHandle(gReadKeyEvent[0]); /* 关闭相关事件 */
// CloseHandle(gReadKeyEvent[1]);

RETAILMSG(1, (TEXT("::: KEY_Deinit Successfully! \r\n")));
return TRUE;
}

onelove2009 2011-09-06
  • 打赏
  • 举报
回复
#include <windows.h>
#include <tchar.h>
#include <nkintr.h>
#include <types.h>
#include "oalintr.h"
#include <pm.h> //??????dxj
#include "pmplatform.h" //??????dxj
#include "drv_glob.h" //??????dxj
//#include "2440addr.h" //
#include "s2440.h"

//读按键事件
HANDLE gReadKeyEvent[2];
HANDLE g_KeyIntr;//中断事件句柄
HANDLE g_KeyIntrThread;//中断线程句柄
UINT32 g_KillKeyInterIST = FALSE; //中断服务线程(IST)
volatile IOPreg *v_pIOPregs; //定义IOPreg结构的指针,以便对IO口进行初始化设置
//volatile PWMreg *v_pWMPregs;
//volatile INTreg *v_s2440INT = (INTreg *)INT_BASE;
BYTE g_KeyNumber = 0xFF; //按键编号
UINT32 gOpenCount = 0; //驱动打开计数
CRITICAL_SECTION cs;//临界区

/*******************************************************************************************
函数名称: Port_Init
描 述: 配置外部中断引脚并使能为 下降 沿触发,配置GPB6和GPB7输出高电平
输入参数: 无
输出参数: 无
返 回: 无
********************************************************************************************/
void Port_Init(void)
{
v_pIOPregs->rGPBCON &= ~((3<<12)|(3<<14));
v_pIOPregs->rGPBCON |= ((1<<12)|(1<<14)); //从新设置为输出
v_pIOPregs->rGPBUP |= (3<<6); //禁止其上拉
v_pIOPregs->rGPBDAT |= (3<<6); //输出为高电平

v_pIOPregs->rGPGCON &= (~((3<<6))); //GPG3 set EINT
v_pIOPregs->rGPGCON |= (2<<6) ; //GPG3 set EINT
v_pIOPregs->rGPGUP &= (~(3<<3)) | (1<<3) ; // The pull up function is disabled GPG3
v_pIOPregs->rEXTINT1 &= ~(7<<12);
v_pIOPregs->rEXTINT1 |= (2<<12); //set eint11 falling edge triggered
}

/*******************************************************************************************
函数名称: EINT_InitializeAddresses
描 述: 取得相关寄存器的虚拟地址
输入参数: 无
输出参数: 无
返 回: > 0 分配得到的虚拟地址; FALSE: 分配失败
*******************************************************************************************/
BOOL EINT_InitializeAddresses(VOID)
{
BOOL RetValue = TRUE;
RETAILMSG(1, (TEXT(">>> EINT_initalization address..set..\r\n")));
/* IO Register Allocation */
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
//在s2440.h中:#deifine IOP_BASE 0xB1600000,而实际物理地址是:0x56000000;
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)((IOP_BASE-0x5B600000)>>8), sizeof(IOPreg), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
RETAILMSG (1, (TEXT("::: EINT_InitializeAddresses - Fail!!\r\n") ));
if (v_pIOPregs)
{
VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
else
RETAILMSG (1, (TEXT("::: EINT_InitializeAddresses - Success\r\n") ));
RETAILMSG(1, (TEXT("*v_pIOPregs = 0x%x===========virtual address test by dxj\r\n"), *v_pIOPregs));
return(RetValue);
}

/*******************************************************************************************
函数名称: Key_IsPushed
描 述: 查询按键是否已按下
输入参数: 无
输出参数: 无
返 回: FALSE: 按键未按下 TRUE: 按键已按下
*******************************************************************************************/
BOOL Key_IsPushed(void)
{
if(((v_pIOPregs->rGPGDAT)&(1<<3)) == 0)
{
g_KeyNumber=3;
RETAILMSG(1, (TEXT("Key_IsPushed======Key2 \r\n")));
return TRUE;
}
else
return FALSE;
//return (((v_pIOPregs->rGPFDAT & (1 << 0)) | ((v_pIOPregs->rGPFDAT & (1 << 2))) ? FALSE : TRUE);
}
onelove2009 2011-09-06
  • 打赏
  • 举报
回复
啊啊啊。。。程序也贴了。。。有没有人救救我啊~~~
xiaosan5871 2011-09-06
  • 打赏
  • 举报
回复
能确定析构函数调用了吗?

你是动态申请还是静态申请的啊?上源代码吧~还有Key的reg部分,也粘上来
winged_fish 2011-09-06
  • 打赏
  • 举报
回复
只知道CloseHandle + DeactivateDevice
支持一下
onelove2009 2011-09-05
  • 打赏
  • 举报
回复
实在想不通为什么在关闭应用程序之后会有KEY_IOControl函数被调用呢???
一介布衣萧萧 2011-09-05
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 onelove2009 的回复:]

那请问这个Handle的释放应该放在哪呢?我在析构函数里释放,结果应用程序直接死机了啊。。。
引用 11 楼 xiaosan5871 的回复:
无语,你应用程序的问题,为什么要怪驱动呢???


你关闭对话框之前,或者在操作之后,就不能把CloseHandle()写入代码中吗?

为什么会出现关闭了对话框,Handle还没有释放???程序员怎么能出现这种毛病呢?
[/Quote]

不知道LZ在析构函数中释放Handle句柄有木有先判空,如果判空再释放一般都不会出错的。不然的话有可能出现多次释放导致异常的问题
onelove2009 2011-09-05
  • 打赏
  • 举报
回复
那请问这个Handle的释放应该放在哪呢?我在析构函数里释放,结果应用程序直接死机了啊。。。
[Quote=引用 11 楼 xiaosan5871 的回复:]
无语,你应用程序的问题,为什么要怪驱动呢???


你关闭对话框之前,或者在操作之后,就不能把CloseHandle()写入代码中吗?

为什么会出现关闭了对话框,Handle还没有释放???程序员怎么能出现这种毛病呢?
[/Quote]
tianlu123 2011-09-04
  • 打赏
  • 举报
回复
哈哈,偶不懂,没有发言权
xiaosan5871 2011-09-04
  • 打赏
  • 举报
回复
无语,你应用程序的问题,为什么要怪驱动呢???


你关闭对话框之前,或者在操作之后,就不能把CloseHandle()写入代码中吗?

为什么会出现关闭了对话框,Handle还没有释放???程序员怎么能出现这种毛病呢?
猫xiaowai 2011-09-02
  • 打赏
  • 举报
回复
所有流驱动的框架都是差不多的,楼主可以贴点代码看看
onelove2009 2011-09-01
  • 打赏
  • 举报
回复
对比两个驱动,基本框架都差不多啊,大家分析一下可能是哪里的问题啊?为什么关闭应用程序时会自动调用KEY_IOControl呢?
一介布衣萧萧 2011-09-01
  • 打赏
  • 举报
回复
一般应用程序调用驱动,出现第二次之后调用驱动时失败的问题都是由于资源没有释放所导致的。资源释放就包括应用层调用驱动不用后要释放。同时驱动在应用层执行卸装驱动或CloseHandle操作的时候,对应的XXX_Deinit和XXX_Close接口也要做相应的释放操作
加载更多回复(7)

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧