随笔 - 6  文章 - 8 评论 - 13 
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(2)

随笔分类(4)

文章档案(8)

Symbian Resources

VC Resources

搜索

  •  

最新评论

阅读排行榜

评论排行榜

第一部分: hello world程序解说

symbian的不同点:
需要自己处理下面的事情:
trap harness,cleanup stack,leave,heap marking
也就是需要自己进行错误检查,
由于没有异常机制,所以symbian使用cleanupstack处理异常
TRAP宏像是catch(…) 函数名带L的像是throw
最后只要在E32Main里面使用一次TRAP就可以了 这样保证内存没有泻漏

对于c字符串,需要使用_L把它转换成symbain使用的描述
symbian是面向对象的,所以对多数c库函数进行了封装,如printf
symbian的入口是E32Main函数
GLDEF_C宏表示这个函数是模块的接口
由于c中没有规定基本类型的长度,symbian使用typedef重定义了基本类型,如TInt16表示16位int

编译:
工程定义文件
可以使用codewarrior或是gcc编译,我们把编译相关信息放在工程定义文件中(扩展名为.mmp,makmake project),并使用其它工具把mmp文件变成makefile或是其它环境下(如codewarrior)的工程文件.下面是hellotext.mmp的内容:
// hellotext.mmp
TARGET HelloText.exe
TARGETTYPE exe
SOURCEPATH .
UID 0
SOURCE hellotext.cpp
USERINCLUDE .
SYSTEMINCLUDE epoc32include
LIBRARY euser.lib
TARGET表示生成的可执行文件的名字,TARGETTYPE表示生成的文件的类型,这里是exe
UID对GUI程序很重要,这里设置为0
SOURCEPATH表示源文件(.cpp)的目录
SOURCE指明源文件名
USERINCLUDE和SYSTEMINCLUDE表示用户自己声明的头文件与系统头文件的目录
通常我们都需要把SYSTEMINCLUDE声明成epoc32include
LIBRARY声明需要链接的库,一般需要E32用户库就可以,也就是euser.lib

组件定义文件
symbian需要一个组件定义文件,这个文件名字总是bld.inf,在这个文件中包含所有的工程定义文件(mmp),更复杂的情况下会包括其它相关信息
下面是hellotext的
// BLD.INF
PRJ_MMPFILES
hellotext.mmp

编译
cd scmphellotext
bldmake bldfiles
上面的命令会在scmphellotext下生成abld.bat文件,同时会创建epoc32buildscmphellotext目录
abld build winscw udeb
winscw表示生成codewarrior(cw)模拟器(win
simulator)的工程文件,udeb表示创建unicode的debug版本
build分下面六个步骤:
export过程复制输出文件到它们的目标,一般会把通用头文件复制到epoc32include,多数应用程序在这步不需要任何操作
makefile阶段生成必须的makefile或ide的工作空间(如vc的dsp文件)
库阶段创建输入库
资源阶段创建应用程序的资源文件,位图和应用程序信息文件(aufs)
目标阶段生成应用程序的主执行文件
最后阶段执行任何最后的操作,多数程序这里不需要

这些阶段都有选项在abld工具中,可以使用abld help得到各选项内容

最后结果放在epoc32releasewinscwudebhellotext.exe,你可以在那里双击它

自己的操作如下
bldmake bldfiles @UIQ_21:com.symbian.UIQ
abld build wins udeb @UIQ_21:com.symbian.UIQ
然后运行epoc32releasewinscwudebhellotext.exe
使用@UIQ_21:com.symbian.UIQ的原因是因为没有设置EPOCROOT环境变量,并且安装了两套symbian环境一个安装在C:SymbianUIQ_21

创建手机上运行的程序
abld build armi urel

创建安装文件
在scmphellotext下运行
makesys hellotext.pkg
这将会生成hellotext.sis,你可以把它上传到手机上


第二部分:系统结构

在symbian os上运行的四种软件
应用程序
服务
引擎
内核
symbian系统使用活动对象与客户-服务器对事件处理系统进行了优化
硬件资源:
一个cpu,32位arm
一个rom(只读存储器),里面有操作系统与内建的中间件和应用程序
ROM盘被映射到z:盘,所有的文件都可以通过Z:盘访问。
系统RAM.系统RAM用于两个方面,一是被当前活动的程序和系统核心使用,另一个是当成”C”盘的磁盘空间。这两个部分的大小是变化的,不可以保留某个的大小。由于RAM通常只有8MB到16MB,所以内存可能用完,因此经常出现内存越界错误或是(写文件时)磁盘已满错误
IO设备,包括带数字笔输入的触摸屏,键盘,记忆卡(被当成D盘),rs232串口,红外口,蓝牙。
电源,包括电池与外接电源

symbian os与pc系统的区别如下:
资源限制:cpu太慢与太少内存
没有硬盘,不能使用写到硬盘的虚拟内存,不能保证有足够的空间保存程序或是数据文件
电源条件严格.

symbian软件环境如下:

server | server| Application| Application | Application Dll
| | +————–+————- boundary
| | | |
| | | Enghine | Engine
——–+———+————+————–+————– Privilege
boundary
Kernel

kernel工作在高级别,管理机器所有硬件资源。对其它软件模块提供访问这些硬件资源的接口
其它应用程序工作在用户模式
上面如果理解普通操作系统如linux的话,那跟普通操作系统没有区别
应用程序是一个有用户界面的程序,在独立的进程中运行
这与普通操作系统也没有区别
服务是没有用户界面的程序.服务管理一个或多个资源,并提供api,让客户可以访问它的服务.服务的客户可以是一个程序或是其它服务.每个服务也运行在独立的进程空间中。
在symbian中,使用服务的形式提供类似其它操作系统上用驱动程序或是内核程序提供的功能。如文件系统的访问也是客户/服务类型的。(微内核Razz)
引擎是一个应用程序中操作数据而不是与用户交互的部分.通常你可以把一个程序分成引擎部分和一个GUI部分,多部symbian内带的程序都是这样做的。
一个应用程序引擎可以是一个独立的代码模块或是一个独立的dll,或是几个dll.
引擎和应用程序间的边界是模块或dll的边界。

所以在symbian中有四个组件类型与三个边界类型。dll或是模块组件对交叉引用来说很方便。它们使系统模块化与保持封装。
权限边界对交叉引用比较费资源,但是保证系统对用户太程序隐藏内核与设备
进程边界是所有的交叉中最昂贵的,它们保证在ram中分开每个程序

可执行文件的格式
在symbian中有两种类型的可执行文件:
exe,每个程序都有一个主入口E32main()(看上面的例子),它在独立的进程中运行
dll,提供多个入口,由系统或是已存在的线程(进程)调用
有两种类型的dll,
共享库dll,为一个或多个程序提供固定的api,这些dll多数后缀是.dll,当程序启动时就被读到内存中。
多态dll,这些dll实现抽象的api,如一个打印机驱动,socket协议或是一个应用程序。它们的扩展名多不是.dll,而是.prn或.prt或.app等。它们从与dll相关的类继承,并通常只有在程序需要它们时才读入。

从技术上看起来与普通系统上动态库的静态载入与动态载入没有区别
但是从功能上看就不一样了,一种是实现某种特殊功能的,从某个相关类继承的dll,另一个是普通dll

代码执行
如果程序代码在rom上,则直接执行,不然需要读到ram中(与普通操作系统不同,普通操作系统都需要读到ram中
不能直接在硬盘上执行)
可执行代码包括三种类型的二进制数据:
程序代码
只读静态数据
可写静态数据
在symbian中对待.exe与.dll是不同的
由于.exe是不可共享的,如果它在ram中执行,那与普通pc系统没有区别,如果在ram中执行,那它在ram中为可写静态数据分配内存
而.dll是共享的,当dll首次读入内存中时,它被分配到一个特殊的地址,第二个线程需要这个dll时它只要访问已经存在的这份copy就可以。在所有使用它的进程中dll的地址都是相同的。symbian系统维护一个引用计数,当没有其它线程引用时才将它unload.
在rom上的dll像rom上的exe一样直接在rom上执行

为了对dll的大小进行优化,symbbian进行如下操作;
多数系统支持通过名字与通过数字访问dll提供的入口,由于名字太长,浪费空间,所以symbian只提供通过数字访问,当然在link时可以通过名字link.也就是说在.dll中没有名字访问办法,在.lib(引导库,引导linker正确的link这个dll,这个是在windows中使用的概念,在win下每创建一个dll都会创建一个用户引导链接的同名.lib)中有,你的程序link时link的是.lib,link完成后编译器会自动把引用dll的代码变成数字引用
如果dll被读到ram,那重定位信息(把dll
load到什么地址)也必须包含在可执行文件格式中,这个的影响就是你不能把一个在rom中执行的程序放到ram中执行的程序.(rom中执行的多是oem厂家,所以普通开发者多不用关心)

多数应用程序有自己有exe来创建进程,其它的程序使用动态库(DL)L的形式,在主服务线程中调用自己的线程
多数gui程序都是多态(polymorphic)dll,有一个主入口点NewApplication(),这个入口点创建并返回一个继承自CEikAppication的对象.这样的程序被apprun.exe调用,app文件名为参数传入。

电源管理
电源必须高效使用
在系统已经关机时,确定程序仍然可以运行。如闹钤,关机后,到时时仍然可以开机
电源突然关掉时,关键数据应该可以保存

设备驱动
虽然一般不会了解它,但是理解一下还是很有用的
设备驱动工作在两个级别
第一个是中断服务程序(ISR),ISR必须很短,并且不能做很多事情,因为它可能在任何时间出现,甚至在内核服务中。通常它只是通知设备产生了中断并设置一个标志,要求内核为第二阶段的处理运行一个延迟的函数调用(delayed function call DFC)
在方便的时候内核调度DFC.DFC可以使用多数的核心api,通常只是工作了后向用户线程通知io操作已经完成

定时器
` 内核支持真机上64hz的时钟与模拟器上10hz的时钟
时钟中断是最高优先级中断,它可以通过User::After或是RTime::After访问。时钟中断在关机时停止,所以如果你请求5s后的定时操作,然后跑2s,关机,再开机时它也要等3s
内核同时支持日期/时间时钟,你可以使用User::At或是RTime::At。这个定时器很准确。在关机时,如果时间到了,那它会开机,这对闹钟很合适。

内存
symbian使用内存管理单元(memory management unit MMU)管理内存
ROM被映射到z:盘,被映射到一个固定的地址。
物理RAM被MMU分在4k的页,每个物理页可以用于:
用户进程的虚地址空间。
内核服务的虚地址空间
ram盘,盘符是c:,ram盘只可通过文件服务进程访问
如果dll不在rom中,那它被读到ram,dll被读到ram里面后页面标记为只读只读的。
MMU的页面转换表.如果想理解的话学习一下操作系统原理
自由页表

每个进程的地址空间可以分成下面三类:
系统范围的内存,如系统的rom或是读到ram中的dll
进程范围的内存,如进程的.exe映象和它的可写的静态数据
每个线程的内存,包括线程的栈与线程默认的堆(使用线程默认堆的原因只是为了提高内存分配与释放的速度,从开发角度来看,它与系统里面的内存没有区别)。
注意没有交换文件,所以所有的内存都是直接使用。同时,也可能会发生内存不够或是磁盘(cSmile已满错误
每个线程的默认栈很小,只有12k,所以在symbian开发中,不要放太多东西到栈中,一般对象都是在堆中分配的。
线程创建后,它的栈大小就不可再改变。
线程可以使用new或是User::Alloc从线程默认堆中分配内存.如果希望从其它堆中分配内存,只能使用new

动态库(DLL)
symbian中dll不支持可写的静态数据,所以你在里面不可能使用可写的全局变量或是静态变量.
为什么不支持呢?如果支持,那每个进程调用这个dll时,都需要为这个进程分配一个独立的堆,而堆最小单位是4k,系统中有很多堆,并且有很多程序,所以内存消费基金是很大的。所以就不支持了Very Happy
这样开发时不是很不方便?因为在dll中有时需要保存自己的状态,进行交互
为了解决这个问题,symbian中引入了线程本地数据(thread-local storage
TLS)概念(查看Dll::Tls
Dll;;SetTls)。但是调用TLS性能比较慢.tls的最大大小是1.8k 通常这够用了。

文件:
c: flash ram盘
z: rom盘
d: 记忆棒之类的外挂盘

事件处理
事件处理模型如下图:

keyborad |—————————
|interrupt
|
kernel/driver–+-isr/dfc
|
key event
|
|
window serv—–handle key event———–+update window
| |
|key event draw |request
application +—————– handle ———-+
key event

在symbian中使用活动对象(active object)来处理事件
在symbian os中,所有的symbian
os线程都是事件处理器,每个线程有一个活动调度对象,加上一个或多个活动对象来处理从设备或其它程序发过来的事件。

每个活动对象都有一个虚拟的成员函数RunL(),在这个函数里面处理事件。

多任务与抢占式
symbian os实现抢占式多线程。
活动对象用于在单个线程内实现非抢占式多任务

posted on 2007-05-04 23:51 Boon 阅读(278) 评论(0)  编辑 收藏 引用