主题 : 初学wince。通过Kn控制LEDn(线程阻塞) 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 69726
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
贡献值: 0 点
综合积分: 8 分
注册时间: 2012-05-10
最后登录: 2012-05-26
楼主  发表于: 2012-05-24 16:19

 初学wince。通过Kn控制LEDn(线程阻塞)

功能描述:按下Kn的时候LEDn亮(n=1..4)

一、 驱动程序(KeyLed.cpp)
#include <windows.h>
//#include <ceddk.h>
#include <nkintr.h>
//#include <oalintr.h>
#include <pm.h>
#include "pmplatform.h"
#include "Pkfuncs.h"
#include "s2440.h"


volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;

HANDLE KeyThread;

void Virtual_Alloc(); // Virtual allocation
DWORD UserKeyProcessThread(void);

// 该线程的作用是将LEDn的状态和Kn的状态绑定在一起
DWORD UserKeyProcessThread(void)
{
const char nIndex[] = { 0, 3, 5, 6};
const char nIndex2[]= { 5, 6, 7, 8};
while(1)
{
for (int i = 0; i < 4; i++)
{
bool down = !(s2440IOP->rGPGDAT & (1 <<nIndex));
if (down)
{
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<nIndex2);
}
else
{
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<nIndex2);
}
}
}
}

void Virtual_Alloc()
{
// 申请虚拟内存空间
s2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
if(s2440IOP == NULL)
{
RETAILMSG(1,(TEXT("For s2440IOP: VirtualAlloc failed!\r\n")));
}
else
{
// 将虚拟内存空间映射到物理内存空间
if(!VirtualCopy((PVOID)s2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE | PAGE_NOCACHE ))
{
RETAILMSG(1,(TEXT("For s2440IOP: VirtualCopy failed!\r\n")));
}
}
}


BOOL WINAPI
DllEntry(HANDLE hinstDLL,
DWORD dwReason,
LPVOID Reserved/* lpvReserved */)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hinstDLL);
return TRUE;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
#ifdef UNDER_CE
case DLL_PROCESS_EXITING:
break;
case DLL_SYSTEM_STARTED:
break;
#endif
}

return TRUE;
}


BOOL KEL_Deinit(DWORD hDeviceContext)
{
BOOL bRet = TRUE;

RETAILMSG(1,(TEXT("USERKEY: KEY_Deinit\r\n")));

// 关闭线程
CloseHandle(KeyThread);
// 内存释放
VirtualFree((void*)s2440IOP, sizeof(IOPreg), MEM_RELEASE);

return TRUE;
}


BOOL KeyGpioInit()
{
RETAILMSG(1,(TEXT("Key_Gpio_Setting----\r\n")));
// K1设置为输入
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 0x0)) | (0x2 << 0x0); // GPG0 == EINT8
// K2设置为输入
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 6)) | (0x2 << 6); // GPG3 == EINT11
// K3设置为输入
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 10)) | (0x2 << 10); // GPG5 == EINT13
// K4设置为输入
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 12)) | (0x2 << 12); // GPG6 == EINT14
// LED1设置为输出
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 10)) | (1<< 10); // GPB5 == OUTPUT.
// LED2设置为输出
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 12)) | (1<< 12); // GPB6 == OUTPUT.
// LED3设置为输出
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
// LED4设置为输出
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.
return TRUE;
}

DWORD KEL_Init(DWORD dwContext)
{
DWORD threadID; // thread ID
RETAILMSG(1,(TEXT("KEY_Init----\r\n")));

// 申请内存
Virtual_Alloc();

// 初始化寄存器
KeyGpioInit();

// 创建线程
KeyThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)UserKeyProcessThread, 0, 0, &threadID);

if (NULL == KeyThread )
{
RETAILMSG(1,(TEXT("ERROR: failed to Create Key Thread!\r\n")));
return FALSE;
}

return TRUE;
}

//-----------------------------------------------------------------------------
DWORD KEL_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
RETAILMSG(1,(TEXT("KEYLED: KEL_Open ret is\r\n")));

return TRUE;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL KEL_Close(DWORD hOpenContext)
{
RETAILMSG(1,(TEXT("KEYLED: KEL_Close\r\n")));
return TRUE;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void KEL_PowerDown(DWORD hDeviceContext)
{

}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void KEL_PowerUp(DWORD hDeviceContext)
{
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEL_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
RETAILMSG(1,(TEXT("KEYLED: KEL_Read\r\n")));
return 1;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEL_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
RETAILMSG(1,(TEXT("KEYLED: KEL_Seek\r\n")));
return 0;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEL_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
RETAILMSG(1,(TEXT("KEYLED: KEL_Write\r\n")));
return 0;
}

二、 把驱动程序添加到BSP中编译
1) 在mini2440\Src\Drivers下建立KeyLed目录,并在dirs文件中加入此目录,使系统编译bsp的时候可以编译这个文件
2) 为驱动创建Makefile文件
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of Peg
#
!INCLUDE $(_MAKEENVROOT)\makefile.def
3) 为驱动创建source文件
!if 0
File: sources

Author: fire

Copyright (c) 1995-2002 Microsoft Corporation. All rights reserved.
!endif

RELEASETYPE=PLATFORM
TARGETNAME=KEYLED
TARGETTYPE=DYNLINK
DLLENTRY=DllEntry

TARGETLIBS= \
$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib \

MSC_WARNING_LEVEL = $(MSC_WARNING_LEVEL) /W3 /WX

INCLUDES= \
$(_TARGETPLATROOT)\inc; \
$(_COMMONOAKROOT)\inc; \
$(_PUBLICROOT)\common\oak\inc;$(_PUBLICROOT)\common\sdk\inc;$(_PUBLICROOT)\common\ddk\inc; \
..\..\inc

SOURCES= \
KeyLed.cpp \

4) 编写Keyled.def导出dll符号
;
; Windows CE Key Driver. Written by flyingfingers

LIBRARY KeyLed
EXPORTS
KEL_Close
KEL_Deinit
KEL_Init
; KEL_IOControl
KEL_Open
KEL_PowerDown
KEL_PowerUp
KEL_Read
KEL_Seek
KEL_Write
5) 把驱动加入内核
在配置文件platform.bib中加入以下内容:(不是很明白为什么要加入IF BSP_NOKEL)
IF BSP_NOKEL !
keyled.dll $(_FLATRELEASEDIR)\keyled.dll NK SH
ENDIF BSP_NOKEL !
6) 把驱动加入注册表
在注册表文件platform.reg中加入以下内容:
IF BSP_NOKEL !
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\keyled]
"Prefix"="KEL"
"Dll"="keyled.dll"
"Order"="200"
ENDIF BSP_NOKEL !
三、 上机结果
友善之臂的Micro2440+WINCE5.0
按下Kn,LEDn亮;松开Kn,LEDn灭(n=1..4)
运行其他程序的时候,会卡。
浪费CPU。


初学WINCE。欢迎交流。


描述:源文件
附件: Keyled.zip (14 K) 下载次数:20