一,开发环境
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为应用程序传送的参数。
上一篇:内核(2.6.14) + 根文件系统 +Qtopia Core 4移植 for S3C2410
下一篇:S3C2440A串口驱动-WINCE6.0下通过串口和外设进行数据通信(二)
推荐阅读最新更新时间:2024-11-13 11:07
推荐帖子
- 红外体温计标定方法
- 红外体温计标定方法是怎么样的?用体温计去测试黑体炉温度?黑体炉设置不同的温度,体温计测试后再比对黑体炉显示的温度?如果有偏差就修正,找出对应的函数关系?是不是这样的思路?同行都是怎样的标定方法?哪种方法更准一些红外体温计标定方法用的什么传感器标定方法用黑体,是利用普朗克黑体辐射的定律。理想化的黑体,表面的发射率为1。红外测温仪测量,调节仪器发射率值,直到所测温度与真实温度相等,现在的经验值,红外测温一般都是将发射率设为0.95原理就是黑体辐射不同的
- QWE4562009 模拟电子
- 一种应用于网络视频记录/数码录影机系统的备电方案
- 作者:Frank,Xiao图一是简单的安防系统框图,主要分为前端产品和后端产品。其中后端产品NVR(NetworkVideoRecord)和前端IPcamera对接,一般情况下一个NVR可对接4个,8个,16个IPC。在某些特定情况下,NVR系统需要短时掉电备份以保证数据非丢失。因此NVR的电池的备电系统成为安防行业一个研究方向。DVR(DigitalVideoRecorder)与CVI/TVI/AHD模拟相机对接,虽然传输信号是模拟信号,但是对备电系统的需求与NV
- alan000345 模拟与混合信号
- 基于sensortag的智能管家系统
- 总体实现这个系统的架构的可能性。是TIsensortag能够实现通用的单元模块,发挥板载传感器的同时,能够把剩余的端口利用起来,以实现不同检测,控制的功能要求。让懒人更懒一些。基于sensortag的智能管家系统
- 蓝雨夜 无线连接
- 【2023 DigiKey大赛参与奖】开箱帖 Raspberry Pi 5 4G
- 感谢得捷和EEWORLD,这次活动获得了参与奖。我用参与奖购买了一个RaspberryPi54G【2023DigiKey大赛参与奖】开箱帖RaspberryPi54G不错参与奖购买了RaspberryPi54G非常好,拍个图片看看电路板什么样子的。你这还投入了不少资金啊,RaspberryPi54G也得500啊Pi5得近600了吧。
- eew_dy9f48 DigiKey得捷技术专区
- 【TI 无线主题征集】xbee模块
- 本帖最后由fjfhjmh于2014-12-316:11编辑 xbee模块是美国DIGI的zigbee模块,XBEE只是型号,是一种远距离低功耗的数传模块,频段有2.4G,900M,868M三种同时可兼容802.15.4协议。可组mesh网络,每个模块都可以做为路由节点,协调器,以及终端节点。模块是内置协议栈,可通过X-CTU以及ZigbeeOperator这两款软件进行调试,模块的配置方式有两种,分别是AP和ATI命令。模块有嵌入式和贴片两种,即插即用自组网,更
- fjfhjmh 无线连接
- 《Cmake构建实战》5 onnxruntime手写识别实践(libpng引用失败)
- 1工程设计设计目标实现包括手写数字识别库以及一个识别命令行工具,识别库能够被C语言等其他编程语言所调用。目录结构├─cli├─cmake├─include├─models└─src└─CMakeList.txt接口设计 初始化手写数字识别库NUM_RECOGNIZER_EXPORTvoidnum_recognizer_init(); 识别器创建NUM_RECOGNIZER_EXPORTvoidnum_recognizer
- maskmoo 嵌入式系统
设计资源 培训 开发板 精华推荐
- MC34164 低压检测微处理器复位的典型应用电路
- ADP2139CB-1.5EVALZ,ADP2138 评估板,800 mA,输出电压 1.5 V,3 MHz 降压稳压器
- AM2G-1215SH30Z 15V 2瓦DC-DC转换器的典型应用
- USB分线器带读卡
- LT1764AMPQ 并联 LDO 稳压器以实现更高输出电流的典型应用
- 使用 LTC3637MPMSE 4V 至 76V 输入至 1.8V 超级电容充电器的典型应用
- LTC3374EFE 降压稳压器的典型应用电路,具有由高压上游降压转换器驱动的顺序启动
- SSM2518 数字输入立体声、2W、D 类音频功率放大器的典型应用
- C5259077_AD9850 DDS信号发生器方案验证板
- 基于GD32的音乐寻路遥控小车