历史上的今天
今天是:2024年08月26日(星期一)
2021年08月26日 | S3C2440A串口驱动-WINCE6.0下通过串口和外设进行数据通信(一)
2021-08-26 来源:eefocus
一,开发环境
WINCE6.0下编写串口驱动,使用S3C2440A的UART0和PC进行通信,UART1、UART2和AVR Atemga162单片机进行通信。
二,串口流驱动流程
主要完成 XXX_Init,XXX_Open,XXX_Read,XXX_Write,XXX_Seek,XXX_PowerUp,XXX_PowerDown,XXX_Close,XXX_Deinit,XXX_IOControl函数。下面介绍自己在驱动中用到的函数。
1,XXX_Init()
在XXX_Init()函数中完成驱动中相关变量和资源等的初始化工作。如S3C2440A相关寄存器的初始化,为其分配地址空间。例如串口0控制寄存器的初始化
/*Uart0 Controller Register*/
v_pUART0regs = (volatile S3C2440A_UART_REG *)VirtualAlloc(0,sizeof(S3C2440A_UART_REG),MEM_RESERVE, PAGE_NOACCESS);
if (v_pUART0regs == NULL)
{
RETAILMSG(1,(TEXT("v_pUART0regs: VirtualAlloc failed!rn")));
goto MAP_ERROR;
}
if (!VirtualCopy((PVOID)v_pUART0regs,(PVOID)(S3C2440A_BASE_REG_PA_UART0>>8),sizeof(S3C2440A_UART_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCAC HE ))
{
RETAILMSG(1,(TEXT("v_pUART0regs: VirtualCopy failed!rn")));
goto MAP_ERROR;
}
RETAILMSG(1,(TEXT("[SRM] v_pUART0regs is mapped to %xnr"), v_pUART0regs));
XXX_Init()中,重要的还有为串口的物理中断申请WINCE系统的逻辑中断。完成映射的方式包括动态映射和静态映射,静态映射可以在SrcCommonIntrintr.c中系统初始化时为物理中断分配系统默认的一些逻辑中断 ,如
OALIntrStaticTranslate(SYSINTR_ETH, IRQ_EINT7);
也可以用动态的方式,通过调用函数KernelIoControl申请逻辑中断号,如以下代码,为串口0中断申请逻辑中断号
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_Uart0Irq, sizeof(UINT32), &g_Uart0SysIntr, sizeof(UINT32), NULL))
{
RETAILMSG(1, (TEXT("ERROR: UART0_INIT: Failed to request sysintr value for UART0_INIT interrupt.rn")));
return FALSE;
}
RETAILMSG(1,(TEXT("INFO: UART0: Mapped IRQ_UART0 to SysIntr 0x%x.rn"), g_Uart0SysIntr));
当然我们需要配置串口的寄存器和串口中断服务线程。关于S3C2440A串口中断寄存器相关配置在下一篇文章再详细介绍,在移植WINCE5.0到WINCE6.0串口驱动时,发现和串口的FIFO控制寄存器有很大关系。串口接受 中断线程的初始化代码如下
BOOL UART0_InitInterruptThread()
{
BOOL bSuccess = FALSE;
RETAILMSG(DEBUGMODE,(TEXT("+++UART0_InitInterruptThreadn")));
m_hUART0InterruptEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
if (!m_hUART0InterruptEvent)
{
RETAILMSG(1,(TEXT("+++Create m_hUART0Interrupt Faile n")));
return FALSE;
}
bSuccess = InterruptInitialize(g_Uart0SysIntr, m_hUART0InterruptEvent, NULL, 0);
if(!bSuccess)
{
RETAILMSG(1,(TEXT("+++InterruptInitialize Faile n")));
return FALSE;
}
m_hUART0InterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CallUART0InterruptThread,
0,
0,
NULL);
if (!m_hUART0InterruptThread)
{
RETAILMSG(1,(TEXT("----UART0_InitInterruptThread failn")));
return FALSE;
}
// Bump up the priority since the interrupt must be serviced immediately.
CeSetThreadPriority(m_hUART0InterruptThread,30); //change 3
RETAILMSG(DEBUGMODE,(TEXT("----UART0_InitInterruptThreadn")));
return TRUE;
}
首先通过CreateEvent()函数创建一个事件,然后把该事件和前面通过KernelIoControl()申请的逻辑中断号绑定,最后用CreateThread()函数创建接收线程,CeSetThreadPriority()函数设置线程的优先级,优先级的范围如下
0 through 96 Reserved for real-time above drivers.
97 through 152 Used by the default Windows Embedded CE-based device drivers.
153 through 247 Reserved for real-time below drivers.
248 through 255 Maps to non-real-time priorities.
可以根据通信的实时性要求进行不同等级的设置。
串口发送线程的初始化函数如下
BOOL UART0_InitTransmitThread(){
RETAILMSG(DEBUGMODE,(TEXT("+++UART0_InitTransmitThreadn")));
m_hUART0TransmitThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,0,(LPTHREAD_START_ROUTINE)CallUART0TransmitThread,0,0,NULL);
if (!m_hUART0TransmitThread)
{
RETAILMSG(1,(TEXT("----CallUART0TransmitThread Failn")));
return FALSE;
}
CeSetThreadPriority(m_hUART0TransmitThread,30); //change 2
RETAILMSG(DEBUGMODE,(TEXT("----UART0_InitTransmitThreadn")));
return TRUE;
}
2,XXX_IOControl
XXX_IOControl()函数主要用于接受应用程序调用驱动程序时发送的命令,根据命令的不同执行不同操作。函数原型如下
BOOL DMA_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
其中dwCode为命令控制码,pBufIn为应用程序传送的参数。
史海拾趣
|
dxp sp2 中为什么在禁止布线层画边框范围时总是自己跳层 protel dxp sp2 中为什么在禁止布线层画边框范围时总是自己跳层??只要一开始画边框他就会自己跳到布线层,愁死了,新装的dxp sp2 :\'( 第一次碰到这种情况,郁闷啊,大家帮帮忙!!… 查看全部问答> |
|
Pretous中LPC2138 P1口接1602液晶 仿真无法显示!! 本人在搭个Proteus中的虚拟仿真平台,用到LM1602时,无法正常显示发送的数据,相同的代码本人在LPC2106的P0口中曾成功过,因为外接部件多所以选用了LPC2138的P1,单步调试时写操作数都是正确的但是数据写入到IOSET1中就是无法显示;本人最怕在仿真 ...… 查看全部问答> |
|
层被琐后Blt返回DDERR_SURFACEBUSY是由谁返回的? 请问执行Blt时有没有锁?如果有,加在哪里?跟到HalBlt里面没有加锁。层被琐时执行Blt操作直接返回DDERR_SURFACEBUSY,没有进HalBlt操作,错误码是由谁返回的?Blt和BltFast跟到底层都是执行的HalBlt,他们对硬件的依赖代码是否封在directDraw里面?… 查看全部问答> |
|
?以前没做过嵌入式开发,现两家公司招聘被录用,一家做手机,一家做电视? 哪家更好些? ?以前没做过嵌入式开发,现两家公司招聘被录用,一家做手机,一家做电视? 哪家更好些? 因为两家公司实力相当,我没有办法比较。 以前做研发只用vc开发过项目,对嵌入式并不了解。 所以,想问问各位: 做软件, 开发手机和开发电视 ,哪个前 ...… 查看全部问答> |
|
OEMStartDoc( SURFOBJ *pso, PWSTR pwszDocName, DWORD dwJobId) { TERSE(UNITEXT(\"OEMStartDoc ...… 查看全部问答> |
|
在vxsim仿真环境中用到 POSIX中的函数,如何包含INCLUDE_POSIX_SCHED,不选bsp建立的工程(downloadable)的工程是不是都不能选组件配置?有什么其他方法么?谢谢。 ps:问题得到解决怎么揭帖?… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:59 编辑 安装lunux环境 安装编译工具 下载Linux kernel 安装Android SDK 获得root file system 修改Linux kernel源码 配置Linux kernel 修改root file system 编译Linux kernel 下载 ...… 查看全部问答> |
|
【设计工具】文档介绍了使用ISE10.1进行某种功能的FPGA操作步骤 文档介绍了使用ISE10.1进行某种功能的FPGA操作步骤,包括从新建文档、综合、功能仿真、编译实现和插入IP核等步骤,讲解非常详细。 … 查看全部问答> |




