串行通信是一种用于两台设备间(典型情况下是距离较近)传输数据的低级别点对点技术。Series60支持红外线和蓝牙上的串行通信。Series60实现的中心是串行通信服务器(Serial Communication Server,又称Comms服务器或C32)。它使用Symbian OS客户端/服务器框架,提供对串行硬件的访问,并且是通用的和共享的。通用是指红外线和蓝牙串行通信使用相同的API,共享是指多个客户端线程可以安全地并发使用同一个串行端口。

Series60中所有的串行通信都使用下列基本步骤实现:
1. 装载串行设备驱动器
2. 启动Comms服务器
3. 连接到Comms服务器
4. 装载一个comms模块(又称CSY: “Comms SYstem”)----Comms服务器的插件,它将决定使用哪种类型的串行端口(红外线or蓝牙)
5. 打开一个串行端口
6. 配置此串行端口
7. 从端口读写数据
8. 最后关闭端口

通信过程中会涉及到几个重要的类,下面简单介绍之:
1. RCommServ
串行通信服务器会话类。它描述了同Comms服务器的会话。提供了连接到服务器函数、装载/卸载不同comms模块函数、查询有效端口名字和数量函数等。
同comms服务器间的会话是不可共享的。此类不能被继承。继承自RSessionBase。
Members
Defined in RCommServ:
Connect(), CreateThreadInCommProc(), GetPortInfo(), LoadCommModule(), NumPorts(), RCommServ(), UnloadCommModule(), Version(), __DbgCheckHeap(), __DbgFailNext(), __DbgMarkEnd(), __DbgMarkHeap(), __DbgSetTraceMask()

Inherited from RHandleBase:
Attributes(), Close(), Duplicate(), FullName(), Handle(), HandleInfo(), Name(), SetHandle(), SetHandleNC(), iHandle

Inherited from RSessionBase:
CreateSession(), EAutoAttach, EExplicitAttach, Open(), Send(), SendReceive(), SetReturnedHandle(), ShareAuto(), ShareProtected(), TAttachMode

2. RComm
继承自RSubSessionBase,描述了一个子会话,使用某一个端口同C32服务器通信。提供的函数均通过操作端口来实现通信,包括打开、关闭、读写、端口配置和性能检测等。一旦使用了某端口来通信,就不能再改变此端口。

下面是串行通信步骤的详解:
1. 装载串行设备驱动器

有两个部分需要装载:一个物理驱动器(直接与硬件交互)和一个逻辑驱动器(提供物理驱动器上的API)。它们的名字是固定的,在这里属于全局性定义。注意,用于模拟器生成(WINS)的物理设备驱动器和用于目标生成的不同。
// Physical device driver names
#if defined (__WINS__)
    _LIT (KPddName, "ECDRV");
#else
    _LIT (KPddName, "EUART1");
#endif

// Logical device driver names
_LIT (KLddName, "ECOMM");

下面是装载驱动器的过程:

TInt err;

#if defined (__WINS__) // File Server required in WINS to enable loading of device drivers
    RFs fileServer;
    User::LeaveIfError(fileServer.Connect());
    fileServer.Close();
#endif

// Load the physical device driver.
    err = User::LoadPhysicalDevice(KPddName);
    if (err != KErrNone && err != KErrAlreadyExists)
        {
        User::Leave(err);
        }

// Load the logical device driver.
    err = User::LoadLogicalDevice(KLddName);
    if (err != KErrNone && err != KErrAlreadyExists)
        {
        User::Leave(err);
        }

若装载函数返回KErrAlreadyExists,则说明此驱动器已装载,这不会被视为错误,因此不需要事先检测驱动器是否已装载。如果使用的代码是UI应用程序的一部分,则这些驱动器将已经被Series60的UI框架装载。前面的#ifdefined(__WINS_)的几行代码首先连接一个RFs会话,然后关闭它,目的是确保调用装载驱动器前已经装载了File服务器。

2. 启动Comms服务器

// Start the comms server process
    err = StartC32();
    if (err != KErrNone && err != KErrAlreadyExists)
        {
        User::Leave(err);
        }

3. 连接到Comms服务器

RCommServ是Comms服务器的客户端句柄,所有后续代码都将使用它与Comms服务器通信。

// Connect to the Serial comms server.
    User::LeaveIfError(iCommServer. Connect());

4. 装载CSY

CSY是Comms服务器的DLL插件,进行数据传输之前需要显式装载它。和驱动器一样,分别使用名字"IRCOMM"和"BTCOMM"装载红外线和蓝牙CSY。

// Comms modules
    _LIT (KIrComm, "IRCOMM");

// Load the CSY module.
    User::LeaveIfError(iCommServer.LoadCommModule(KIrComm));

5. 打开串行端口

接下来打开一个串行端口。同样,仍然按名字打开它。但注意端口名是不固定的,可能需要动态获取它。不过对于红外线的情况,端口名是公认的。

// Comm Port Name
    _LIT (KPortName, "IRCOMM::0");

User::LeaveIfError(iCommPort.Open(iCommServer, KPortName, ECommShared));

RComm::Open()的第三个参数说明打开此端口的模式,可能的取值如下:
ECommExclusive:此端口一旦打开,即不能被其他任意RComm客户端使用
ECommShared:此端口可以被在相同模式下打开的其他RComm客户端共享
ECommPreemptable:如果其他客户端试图打开此端口则会丢失

对于非公开的端口名,下面的代码演示了如何动态获取它:

TSerialInfo portInfo;

// 获取选择CSY所对应的端口信息
User::LeaveIfError(iCommServer.GetPortInfo(KIrComm, portInfo));

// 构建一个描述符,包含该CSY所支持的最低端口
// 要求它的大小足以包含TSerialInfo.iName的值(定义为KMaxPortName,最大值为16个字符)
// 加上两个冒号和1或2个数字

_LIT(KColons, ":: ");

TBuf<KMaxPortName + 4> portName;
portName.Append(portInfo.iName);
portName.Append(KColons);
portName.AppendNum(portInfo.iLowUnit);

// 现在打开第一个串行端口,在此为唯一模式
User::LeaveIfError(iCommPort.Open(iCommServer, portName, ECommExclusive));

6. 配置串行端口

最终使用已打开的串行端口之前,可能需要对它进行配置。这取决于希望连接到的设备的需求。提供串行通信的设备通常会附带某种形式的文档,详细说明需要的配置。同时可以通过查询端口的功能确保它支持需要的配置。
查询端口功能的方法如下:
    // Check port capabilities
    TCommCaps portCapabilities;
    iCommPort.Caps(portCapabilities);

if (((portCapabilities().iRate & KCapsBps19200) == 0) ||
        ((portCapabilities().iDataBits & KCapsData8) == 0) ||
        ((portCapabilities().iStopBits & KCapsStop1) == 0) ||
        ((portCapabilities().iParity & KCapsParityNone) == 0))
            User::Leave (KErrNotSupported);
           
这里使用的所有常数值(如KCapsBps19200)都在系统头文件d32comm.h中定义。此外,如果端口的功能与需求不匹配,并不需要异常退出,可以选择以不同的方式处理此情况,例如提示用户选择不同的端口或CSY。
接下来,可以设置端口的配置。首先应该获取当前配置,这样可以使不希望显式设置的值保持不变:
    // Configure port
    TCommConfig portSettings;
    iCommPort.Config(portSettings); // Get current configuration

// Set port characteristics
    portSettings().iRate = EBps19200;
    portSettings().iParity = EParityNone;
    portSettings().iDataBits = EData8;
    portSettings().iStopBits = EStop1;
    portSettings().iFifo = EFifoEnable;
    portSettings().iHandshake = KConfigObeyXoff|KConfigSendXoff;
    portSettings().iTerminator[0] = 10; // line feed character
    portSettings().iTerminatorCount = 1;

User::LeaveIfError(iCommPort.SetConfig(portSettings));

最后,有些杂项配置信息不能使用TCommConfig对象设置,例如对于DTR(Data Terminal Ready,数据终端就绪)和RTS(Ready To Send,准备发送)之类的流控制信号,需要使用RComm::SetSignals()设置它们:
     // Turn on DTR and RTS
    iCommPort.SetSignals(KSignalDTR, 0);
    iCommPort.SetSignals(KSignalRTS, 0);

// Set buffer size
    const TInt KBufferLength = 4096;
    iCommPort.SetReceiveBufferLength(KBufferLength);
   
7. 在端口上传输数据

// Timeout Value
    const TTimeIntervalMicroSeconds32 KTimeOut(4000000);
    Cancel();

iDataBuf.Copy(aTxData);
    iCommPort.Write(iStatus, KTimeOut, iDataBuf);
    SetActive();

有几个重要的地方需要注意:
* 调用Write()之前调用了Cancel(),这是因为Write()是异步的,这样可以确保不会试图同时执行两个写操作,这将导致错误。
* Series60是一个Unicode平台,所以aTxData是一个16位描述符。因此不能把它直接传递到RComm::Write()---该函数需要一个显式的8位描述符,所以首先需要把它复制到一个8位描述符,然后传递到Write()。
* Write()的第二个参数是一个超时值,这里定义为4秒。如果Write()请求未在此时限内完成将会强制结束,并把iStatus设置为KErrTimedOut。

8. 关闭端口

在串行端口上发送和接收数据结束后,必须关闭此端口(或更明确的说,关闭此端口的句柄),同时还要关闭服务器:
    iCommPort.Close();
    iCommServer.Close();

symbian 串行通信相关推荐

  1. symbian学习转载

    [虎.无名]学习Blog 诺盛电信咨询:移动支付是什么- -| 回首页 | 2006年索引 | - -Nokia 6681菜鸟必修课 zt 腾达智能社区:Symbian基础类知识- - http:// ...

  2. Symbian OS 初探

    Symbian OS 初探 2008-12-22 20:56 Symbian OS 初探 tombkeeper@xfocus,http://hi.baidu.com/tombkeeper 2005.1 ...

  3. Symbian开发系列 - 入门篇

    要开始我的Symbian开发之旅了, 先收集一些相关资料,如Symbian概述, 开发平台搭建, 参考书籍与网络资源. [基础] 什么是Symbian 学习Symbian的基本概念  Symbian操 ...

  4. (解释)单片机与各种外围设备(Flash、RAM、网络控制器、A/D、传感器、MCU等)进行直接串行通信通常采用( D)接口

    单片机与各种外围设备(Flash.RAM.网络控制器.A/D.传感器.MCU等)进行直接串行通信通常采用( D)接口. A. RS232C B. RS485 C. COM D. SPI A:RS-23 ...

  5. 【转】symbian操作系统 入门篇

    一.symbian简介 Symbian是一个实时性.多任务的纯32位操作系统,具有功耗低.内存占用少等特点,非常适合手机等移动设备使用,经过不断完善,可以支持GPRS.蓝芽.SyncML.以及3G技术 ...

  6. Symbian的内存管理机制

    Symbian解决内存泄露的机制:Cleanup Stack 概念: 构造一个全局堆栈,用来记录类对象指针.每实例化一个对象,则将对象指针备份到这个堆栈中,程序go on.最终两种情况:①所有函数执行 ...

  7. 基于Virtex-6 FPGA的三种串行通信协议测试及对比

    在高性能雷达信号处理机研制中,高速串行总线正逐步取代并行总线.业界广泛使用的Xilinx公司Virtex-6系列FPGA支持多种高速串行通信协议,本文针对其中较为常用的Aurora 8B/10B和PC ...

  8. 【ARM】arm串行通信

    异步通信 所谓异步通信,是指数据传送以字符为单位,字符与字符间的传送是完全异步的,位与位之间的传送基本是同步的. 异步串行通信的特点可以概括如下 1)以字符为单位传送信息 2)相邻两字符间的间隔是任意 ...

  9. STM32串行通信USART解说笔记

    STM32串行通信USART程序例举链接:http://blog.csdn.net/dragon12345666/article/details/24883111 1.STM32串行通信USART的相 ...

  10. Symbian 编程总结导读

    Symbian 编程总结 - 基础篇 类类型 异常处理机制 使用"清理栈"手动管理内存 描述符(1)-描述符基本概念 描述符(2)-TDesC8与TDesC16之间的互转 描述符( ...

最新文章

  1. Pandas 使用入门
  2. 数据结构学习(十三)、快速排序
  3. mysql 自定义哈希函数_C++ STL无序容器自定义哈希函数和比较规则(超级详细)...
  4. 论强化学习的根本缺陷
  5. mysql 按照指定顺序排序
  6. 跟着 Github 学习 Restful HTTP API 的优雅设计
  7. node异步非阻塞的杂谈
  8. Java中常用的测试工具JUnit
  9. MySQL多种安装方式选择
  10. 学习笔记=《你不知道的JavaScript(上卷)》第三章:函数作用域和块级作用域...
  11. 吴恩达机器学习笔记一
  12. SynchronousQueueE简介
  13. android鸿洋布局,Android基础ConstrainLayout约束布局的介绍和使用
  14. swagger 上传文件 参数_跟我一起学.NetCore之Swagger让前后端不再烦恼及界面自定义...
  15. 想知道ios系统还有哪些比较好用的思维导图软件?
  16. Redis 实战指南
  17. 小程序 | 微信小程序布局左对齐自动换行
  18. python编写程序统计一元人民币换成一分、两分和五分的所有兑换方案个数(用while循环)
  19. GAN——生成对抗网络详解
  20. set(gca,'fontsize',8);

热门文章

  1. 如何将谷歌浏览器指定网页的背景颜色调成黑色,其他网页背景颜色不变——以HDLBits为例
  2. 音视频系列--MediaProjection录屏生成H264和H265文件
  3. 2012考研数学二第(11)题——链式法则偏导数
  4. 1.18 物主代词 形容词 宾语从句
  5. 为什么FFFF FFFF是4GB
  6. “我消灭你,但与你无关” 请接受跨界打劫!
  7. 微信小程序登陆踩坑记录
  8. java中1字节(8位)_Java中基本数据类型占几个字节多少位
  9. win10 休眠不读u盘_如何解决win10识别不了U盘问题
  10. 如何为水晶报表rpt文件添加数据连接