初学wince,想学习学习驱动建立步骤。(CPU)
timer1作为系统时钟。(在E:\WINCE500\PLATFORM\Ep93xx\Src\Kernel\Hal\Common下的interrupt.c文件中有定义)
timer2作为定时器用。(在触摸屏TOUCH的驱动中Delayus函数中有定义)
因此此处就针对Timer3作一个定时驱动。
1、修改\WINCE500\PLATFORM\Eac0921\files下的platform.bib和platform.reg文件
platform.bib加下面段---表示最终要将此文件写到内核
IF BSP_Timer_DRIVER
Timer.DLL $(_FLATRELEASEDIR)\Timer.DLL NK SH
ENDIF
platform.reg加下面段---表示系统启动后要加载此驱动
IF BSP_Timer_DRIVER
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Timer]
"Index"=dword:1
"Prefix"="TIM" ----注意前缀是你在.cpp文件中要使用的函数的前缀,它最长允许3个字母。
"Dll"="Timer.dll" ---是在source中定义的TARGETNAME=Timer
"Order"=dword:0
ENDIF
在编译的时候系统会将此目录下的platform.bib和platform.reg文件拷贝到\WINCE500\PLATFORM\Eac0921\Cesysgen\files下
2、在E:\WINCE500\PLATFORM\Ep93xx\Src\Drivers下建立文件夹timer。
3、修改E:\WINCE500\PLATFORM\Ep93xx\Src\Drivers下的文件dir
添加一行,表示添加timer文件夹
4、在timer文件夹中建立timer.c和timer.h
5、在timer文件夹中建立makefile和sources文件。可以从别的驱动文件夹拷贝过来修改
修改makefile文件内容
!INCLUDE $(_MAKEENVROOT)\makefile.def
修改sources文件内容
!ifndef BSP_Timer_DRIVER
SKIPBUILD=1
!endif
TARGETNAME=Timer
DEFFILE=Timer.def
RELEASETYPE=PLATFORM
TARGETTYPE=DYNLINK
DLLENTRY=DllMain
WINCEOEM=1
TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib
INCLUDES=..\..\inc
#CDEFINES=$(CDEFINES) -DREAD_FROM_REGISTRY
SOURCES=Timer.cpp
6、编写timer.h文件
7、根据字符设备驱动模式,编写驱动源码Timer.cpp。
8、由于用到了中断,必须修改中断向量文件
修改E:\WINCE500\PLATFORM\Ep93xx\Src\Inc中的文件oalintr.h
在其中加入中断向量。
#define SYSINTR_TIMER3 (SYSINTR_FIRMWARE+14)
//不能大于64。可以是随便的数值。
修改E:\WINCE500\PLATFORM\Ep93xx\Src\Kernel\Hal\Common下的interrupt.c文件,允许Timer3的中断。
在函数 int OEMInterruptHandler(unsigned int ra)
中加入 else if (ulVic2Irq & INT2_TIMER3)
{
*VIC2_INTCLEAR = INT2_TIMER3;
retval = SYSINTR_TIMER3;
}
在函数BOOL SysIntrNumToInterruptMask(DWORD dwSysIntr, PULONG pulInterruptMask1,PULONG pulInterruptMask2)
中加入 case SYSINTR_TIMER3:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_TIMER3;
break;
中断的允许和关闭在原来的函数中已经定义。
BOOL OEMInterruptEnable(DWORD idInt, LPVOID pvData, DWORD cbData)
if(ulIntMask2)
{
*VIC2_INTENABLE = ulIntMask2;
gdwInterruptMask2 |= ulIntMask2;
}
void OEMInterruptDisable(DWORD idInt)
if(ulIntMask2)
{
*VIC2_INTCLEAR = ulIntMask2;
gdwInterruptMask2 &= ~ulIntMask2;
9、在paltform\setting\environment中添加BSP_TIMER_DRIVER项,value为1。
也可以在bsp包中添加BSP_TIMER_DRIVER组件。
10、编译工程,用第一项编译。
11、编写一测试程序,在程序中调用DWORD TIM_Open (DWORD hDeviceContext,DWORD AccessCode, DWORD ShareMode)函数
DWORD TIM_Open (DWORD hDeviceContext,DWORD AccessCode, DWORD ShareMode)
附源码:
//////////////////timer.cpp//////////////////////////////////////////
#include
#include
#include
#include
#include
#include
#include "Timer.h"
#define debug_timer 0
DWORD WINAPI TIMIntScan ( LPVOID lpvparam );
void TIM_INT_DO( void );
static WORD io_set=0;
DWORD wTermCnt=0x5;
HANDLE hTIMIntEvent;
HANDLE hTIMThread=NULL;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
DWORD TIM_Init(DWORD dwContext)
{
DWORD dwRet = 1;
*GPIO_PADDR |= 0x8;
RETAILMSG(1,(TEXT("Init the Timer.\r\n")));
if( !( hTIMIntEvent=CreateEvent( NULL, FALSE, FALSE,NULL )) )
{
RETAILMSG( debug_timer,(TEXT("timer: failed to creat Event\r\n")));
}
if( !( InterruptInitialize( SYSINTR_TIMER3, hTIMIntEvent, NULL, 0 ) ) )
{
RETAILMSG( debug_timer, (TEXT( "timer: failed to initialize interrupt\r\n" )));
}
if( !( hTIMThread=CreateThread( NULL, 0, TIMIntScan, hTIMThread, CREATE_SUSPENDED, NULL) ) )
{
RETAILMSG( debug_timer,(TEXT( "timer: failed to create the thread \r\n" )));
}
CeSetThreadPriority( hTIMThread, 90);
InterruptDone( SYSINTR_TIMER3 );
return dwRet;
}
BOOL TIM_Deinit (DWORD hDeviceContext)
{
BOOL bRet = TRUE;
return bRet;
}
DWORD WINAPI TIMIntScan ( LPVOID lpvparam )
{
DWORD dwRet = 1;
RETAILMSG(1,(TEXT( "Timer: thread is resumed. \r\n" )));
while( 1 )
{
RETAILMSG( debug_timer,(TEXT( "Enter IRQ wait \r\n" )));
WaitForSingleObject ( hTIMIntEvent, INFINITE ); //wait for the timer interrupt
TIM_INT_DO();
*TIM_TIMER3CLEAR= 0xFF;
InterruptDone( SYSINTR_TIMER3 );
}
return dwRet;
}
void TIM_INT_DO(void)
{
if(io_set==0)
{
*GPIO_PADR |= 0x08;
io_set=1;
}
else
{
*GPIO_PADR &= ~0x08;
io_set=0;
}
return ;
}
DWORD TIM_Open (DWORD hDeviceContext,DWORD AccessCode, DWORD ShareMode)
{
DWORD dwRet = 1;
*TIM_TIMER3CONTROL = 0;
*TIM_TIMER3LOAD = wTermCnt;
*TIM_TIMER3CONTROL = 0xc8; /* 7bit enable 1-enable 0-disable
6bit mode 1-reload mode 0-free run
3bit clksel 1-508KHz 0-2KHz*/
ResumeThread( hTIMThread);
return dwRet;
}
BOOL TIM_Close (DWORD hOpenContext)
{
BOOL bRet = TRUE;
*TIM_TIMER3CONTROL = 0;
*TIM_TIMER3CLEAR= 0xFF;
return bRet;
}
BOOL TIM_IOControl (DWORD hOpenContext,
DWORD dwCode,
PWORD pBufIn,
DWORD dwLenIn,
PWORD pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL bRet = TRUE;
switch(dwCode)
{
case IOCTL_WRITETERMCNT_Timer:
wTermCnt = (DWORD)(*pBufIn);
RETAILMSG(debug_timer,(TEXT("Timer_IOControl:\tIOCTL_WRITETERMCNT_Timer,Timer0TermCnt=%x.\r\n"),wTermCnt));
break;
case IOCTL_READTERMCNT_Timer:
RETAILMSG(debug_timer,(TEXT("Timer_IOControl:\tIOCTL_WRITETERMCNT_Timer,Timer0TermCnt=%x.\r\n"),(*TIM_TIMER3VALUE)));
*pBufOut = (WORD)(*TIM_TIMER3VALUE);
break;
default:
bRet = FALSE;
}
return bRet;
}
void TIM_PowerDown (DWORD hDeviceContext)
{
return;
}
void TIM_PowerUp (DWORD hDeviceContext)
{
return;
}
DWORD TIM_Read (DWORD hOpenContext,LPVOID pBuffer,DWORD Count)
{
DWORD dwRet = 0;
return dwRet;
}
DWORD TIM_Seek (DWORD hOpenContext,long Amount,DWORD Type)
{
DWORD dwRet = 0;
return dwRet;
}
DWORD TIM_Write (DWORD hOpenContext,LPCVOID pSourceBytes,DWORD NumberOfBytes)
{
DWORD dwRet = 0;
return dwRet;
}
//////////////////timer.h//////////////////////////////////////////////////////
#ifndef _Timer_H_
#define _Timer_H_
#include
#define WRITETERMCNT_Timer 2800
#define READTERMCNT_Timer 2801
#define IOCTL_WRITETERMCNT_Timer CTL_CODE(FILE_DEVICE_DATALINK, WRITETERMCNT_Timer, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_READTERMCNT_Timer CTL_CODE(FILE_DEVICE_DATALINK, READTERMCNT_Timer, METHOD_BUFFERED, FILE_READ_ACCESS)
#endif
没有评论:
发表评论