1 / 45

嵌入式软件开发导论

嵌入式软件开发导论. 6. Windows CE 系统架构. 同济大学软件学院 2005. 概述. 系统架构 NK.EXE FILESYS.EXE DEVICE.EXE GWES.EXE SERVICES.EXE Thread Migration. Windows CE 系统架构. NK. EXE. OAL. ROM. /. RAM. FLASH. Timer. INTC. CPU. NK.EXE. NK.LIB + OAL.LIB = NK.EXE 内核是硬件体系结构无关但是是处理器相关的 OAL 越小越好

Download Presentation

嵌入式软件开发导论

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式软件开发导论 6. Windows CE 系统架构 同济大学软件学院 2005

  2. 概述 • 系统架构 • NK.EXE • FILESYS.EXE • DEVICE.EXE • GWES.EXE • SERVICES.EXE • Thread Migration

  3. Windows CE 系统架构

  4. NK . EXE OAL ROM / RAM FLASH Timer INTC CPU NK.EXE • NK.LIB + OAL.LIB = NK.EXE • 内核是硬件体系结构无关但是是处理器相关的 • OAL越小越好 • 微软提供了预先编译的 NK.LIB 库文件 • NK.lib的大多数代码都是公开的 • 通过高级代码共享,可以得到更多代码 • 提供: • 内存管理 • 调度管理 • 系统调用转发 • 实现了一些基本的Win32函数

  5. Protected Server Libraries (PSL) • 实现API的系统函数 • 把操作系统的功能放在多个进程的机制 • PSL Calls run through the Kernel (NK.EXE) • 不对最终用户开放 • 你不能创建一个PSL

  6. GWES.EXE • 图形窗口事件系统 (GWES) • 管理所有的图形界面处理以及用户输入 • 桌面的 USER32 + GDI32 作为一个单独的进程

  7. DEVICE.EXE • 设备管理器 • 电池驱动已经被从GWES中拿走了 • 大多数功能都放在了devmgr.dll中。 • 提供所有的与驱动相关的函数实现 • 在启动的时候通过注册表加载驱动程序

  8. Services.EXE • 所有服务的宿主进程 • 与Device.exe分开 • FTP, TELNET, HTTPD (Web), UPnP, SMB, 其它… • 用户可以添加服务 • 提供命令行工具来启动、关闭服务 • 提供API管理服务

  9. 文件系统 • 所有与文件系统相关的函数都在 FileSys.exe中实现 • 单根 “\”, 没有像“C:\”一样的盘符 • 有三个组件: • 对象存储 • 存储管理器 • ROM 文件系统

  10. 文件系统概述

  11. 目标存储 • 被 FileSys.exe管理的一个堆 • 包括: • Registry • Database • RAM文件系统 • RAM 文件系统通常位于根目录 • Ex : “\myfile.txt” 存在于RAM中

  12. ROM 文件系统 • 被映射成“\Windows” 目录 • “\Windows” 目录中所有的文件都是只读的 • 通常是nk.bin或nk.nb0中的文件

  13. 存储管理 • 负责: • Storage device driver • Partition device driver • File System device driver • File System filter

  14. 线程迁移 CreateFile(…)

  15. 概述 • 进程 • 线程 • 虚拟内存

  16. Windows CE 内核特征 • 多进程 • 可以支持最多32个进程 • 多线程 • 支持256个线程优先级 • Fibers • 只能被应用程序手工调度的执行单元 • 同步对象 • Critical Sections, Mutexes, Semaphores, Events, Message Queues • 内存模型 • Virtual memory, Code sections Paged, No backing store for Data sections

  17. 进程 • 静态上下文,线程的容器 • 进程不被执行,线程被执行 • 系统中同时最多只能有32个进程: • 对大多数嵌入式系统来说都已经足够。推荐用多线程而不是多进程 • 迎合一些体系结构的支持 • Windows CE 使用与 Windows XP一样的加载/卸载模型 • (与其它桌面Window一样) • 支持命令行程序 • 但是与桌面Win32 API不一样 • 调用 CreateProcess() 启动进程

  18. 线程 • Win32的执行的单元 • 按照优先级调度 • 高优先级的线程会抢占低优先级的线程 • 同样的优先级使用Round-Robin算法 • 默认的时间片是 100毫秒,OEM可以在OAL中重新设置

  19. 线程调度 • 线程A拥有最高的优先级,他会一直执行直到结束或阻塞 • 线程B和C使用Round-Robin算法运行 • 在round-robin 每个线程都运行一个固定的时间,叫做时间片 • 优先级数字越小,优先级越高

  20. 线程优先级分布图(例)

  21. 优先级反转 • Avoid priority inversion by keeping all threads waiting for same resource at the same priority Example: Thread 1 blocked waiting for resource owned by Thread 3, causing Priority Inversion PriorityInversion PriorityRestored Thread 3 High Priority Thread 1 Thread 1 Blocked Preempt Medium Priority Thread 2 Thread 2 Blocked Preempt Blocked Low Priority Thread 3 Thread 3 Resource Owner: Thread 3 Thread 1

  22. Thread API • 线程创建 • CreateThread – 创建一个普通优先级的线程 • 线程优先级 • GetThreadPriority – 当前线程的优先级 • SetThreadPriority – 改变当前线程的优先级 (251) • CeGetThreadPriority – 得到实时线程的优先级 • CeSetThreadPriority – 改变实时线程的优先级 • 线程睡眠 • Sleep(0) – 放弃剩余的时间片 • Sleep (n) – 睡指定的毫秒 • Sleep (INFINITE) • SleepTillTick – 睡到下一个系统嘀嗒 • SuspendThread – 增加休眠的引用计数 • ResumeThread –减少休眠的引用计数

  23. 进程 & 线程 • Windows CE 进程不支持环境变量 • _wfopen (L“%WINDOWS%\\a.txt”, L“w”); // error • Windows CE 进程不支持当前目录 • _wfopen(L“a.txt”, L“w”); // error, first search root directory, then search \Windows directory.

  24. 同步对象 • 线程 • 需要同步对象在某些时候进行同步操作。 • 同步对象类型 • Critical Section • Mutex • Semaphore • Event • 也可以使用子增函数或者点对点消息队列

  25. 同步 (Critical Sections) • 概览 • 允许多个线程共享访问同一块数据 • 使用互斥访问保护数据 • 其他线程会block直到占有者放弃临界区 • 每个CS都是OS提供的一个数据结构,只能在同一个进程内部使用,比MUTEX要高效。 • 函数 • InitializeCriticalSection • 分配 CRITICAL_SECTION 结构 • EnterCriticalSection • 调用着在占有CS的人调用 LeaveCriticalSection之前会阻塞 • TryEnterCriticalSection • EnterCriticalSection的非阻塞版 • LeaveCriticalSection • 释放CriticalSection的所有权 • DeleteCriticalSection • 释放InitializeCriticalSection分配的资源

  26. 同步对象(Mutexes) • 概览 • 同一时刻只有一个线程可以拥有mutex • 全局名称的Mutex可以跨进程使用。 • 在没有线程拥有它时处于signal状态 • 被线程拥有的时候处于非signal状态 • 函数 • CreateMutex • 创建一个有名或无名的Mutex对象 • WaitForSingleObject or WaitForMultipleObject • 调用着在占有Mutex的人释放之前会阻塞 • ReleaseMutex • 释放对Mutex对象的占有 • CloseHandle • 删除Mutex对象

  27. 同步对象(Semaphores) • 概览 • 限制占有共享资源的数量 • 全局名称的Semaphores可以跨进程使用。 • 引用计数大于零时处于signal状态 • 引用计数小于等于0时处于非signal状态 • 函数 • CreateSemaphore • 创建一个有名或无名的Semaphore对象 • WaitForSingleObject or WaitForMultipleObject • 调用者在计数是非0之前阻塞 • ReleaseSemaphore • 增加Semaphore的引用计数 • CloseHandle • 删除Semaphore对象

  28. 同步对象(Events) • 概览 • 全局名称的Event可以跨进程使用。 • 事件发生时处于Signal状态 • 时间未发生时处于非signal状态 • 函数 • CreateEvent –创建一个有名或无名的事件对象 • SetEvent –把事件对象设置为signal状态 • ResetEvent –把事件设置为非signal状态 • PulseEvent –把事件设置为signal状态,然后在释放一定量的线程之后,转回非signal状态 • WaitForSingleObject or WaitForMultipleObject –调用者阻塞直到某一事件达到signal状态 • CloseHandle –销毁事件对象

  29. 同步 (Interlocked Functions) • 概览 • 对多个线程对同一个变量的共享访问保护 • 提供原子操作 • 函数 • InterlockedIncrement –对一个变量进行原子加1操作 • InterlockedDecrement -对一个变量进行原子减1操作InterlockedExchange –对两个变量进行交换值操作 • InterlockedTestExchange –如果变量符合,则交换两个变量的值 • InterlockedCompareExchange –基于比较,交换两个变量的值

  30. 同步 (PTP消息队列) • 概述 • 允许拥有多个用户定义的消息队列的使用者存在 • 高优先级和报警消息 • 函数 • CreateMsgQueue – 创建或打开一个消息队列 • OpenMsgQueue – 对一个现存的消息队列打开一个句柄 • CloseMsgQueue – 关闭一个打开的消息队列 • ReadMsgQueue – 从消息队列中读一个消息 • WriteMsgQueue – 向消息队列写一条消息 • GetMsgQueueInfo – 返回有关一个消息队列的信息

  31. Application C Runtime (mallc, new…) Logical Memory (Heap, stack) Virtual Memory Physical Memory * Storage Device 内存管理 * 只在桌面Windows上存在

  32. 内存结构 • 物理内存 • 在内部或外部总线上可访问的实际的RAM/ROM • 虚拟内存 • 通过内存管理单元MMU转换过的虚拟地址 • 允许代码在需要的时候再换入

  33. Reserved 2GB Memory Mapping (Shared) Slot 32:Process32 2GB . . . Slot 1:XIP DLL Code 32MB Slot 0:Active Process 虚拟内存 • 虚拟内存管理 • Windows CE为所有进程提供平板的4GB虚拟地址空间 • 系统仍然对每个进程提供保护 • 允许快速的进程间线程切换 • 使用虚拟内存 • 申请大块虚拟内存 • Windows CE把虚拟内存分成64K的块 • 使用本地堆 • 内核为你的应用程序保留的虚拟地址 • 使用栈 • 存放函数内部使用的临时数据的区域

  34. 概述 • 虚拟内存模型 • 静态映射的虚拟内存 • 进程模型 • 进程内存 • 进程 • 模块 • 堆 • 栈

  35. 虚拟内存模型 • 虚拟内存 • 一个 32-bit (4 Gigabyte) 平板式虚拟内存地址空间 • 提供了被保护物理内存的有效使用 • 虚拟地址 • 内存管理单元 (MMU) “拥有” 物理内存 • MMU将虚拟地址转换为物理地址 • 一个有效的虚拟地址必须被映射到一个物理地址 • 虚拟地址的静态和动态映射 • 物理地址 • 在上电时,在MMU有效之前只被CPU使用

  36. 虚拟内存模式 • 特权模式 • 在内核模式和用户模式间的虚拟内存split • 所有的进程共享同一个平板式虚拟内存地址空间 • 通过MMU内核模式管理用户模式进程保护 • 内核空间 • 只被特权访问的内核模式代码使用(Kmode) • 大多数是静态虚拟地址映射(不会有页内错误) • 用户空间 • 每32MB由64个slots组成 • 大多数是动态虚拟地址映射

  37. 虚拟内存模式 Kernel Space Total 4 GB VirtualSpace User Space FFFF FFFF 7FFF FFFF Kernel Addresses: KPAGE, Trap Area, Others 2 GB Slots 33-63 Object Store and Memory-Mapped Files E000 0000 Unused Kernel Space C400 0000 Slot 97: NK.EXE C200 0000 4200 0000 2 GB Unused C000 0000 UserSpace Statically Mapped Virtual Addresses: Un-Cached Slots 2-32 - Processes A000 0000 Statically Mapped Virtual Addresses: Cached 0400 0000 Slot 1 – XIP DLL code 0200 0000 Slot 0 – Current Process 8000 0000 0000 0000

  38. 静态映射虚拟地址 Virtual Memory Physical Memory FFFF FFFF Kernel Space C000 0000 512 MBUncached 32 MB Flash 64 MB RAM A000 0000 512 MBCached 32 MB Flash 82000000 32 MB Flash 64 MB RAM 8000 0000 04000000 64 MB RAM 2 GBUser AddressTranslation UserSpace 00000000 0000 0000

  39. Process Model • 虚拟地址 Slots • 每个slot是32 MB (225 bytes) 虚拟地址空间 • Slot空间被进程,DLLs, 和虚拟分配共享 • 在进程slot间快速进行上下文切换(交换页表) • 当前线程执行在slot 0上 • 管理粒度 • 虚拟地址空间以64KB的粒度被分割 • 物理地址以4KB的粒度被页进行管理 • 分配规则 • DLL 分配从高地址开始向下增长 • 进程分配从低地址开始向上增长

  40. C400 0000 32 MB Process Space nk.exe Slot 97 01FF FFFF C200 0000 . . . 8000 0000 Resource DLLs Slot 63 7E00 0000 . . . 4200 0000 Free Virtual Space Slot 32 4000 0000 Slot 31 3E00 0000 Slot 30 3C00 0000 . . . 0C00 0000 gwes.exe Slot 5 0A00 0000 device.exe Slot 4 0800 0000 shell.exe Slot 3 0600 0000 0001 0000 filesys.exe Slot 2 0400 0000 0000 0000 XIP ROM DLLs Slot 1 0200 0000 Current Process Slot 0 0000 0000 Lesson: Process Memory

  41. 模块 • 模块 • 标准的 Win32 Portable 可执行文件格式 • 标准的 Win32 工具 (符号, 数字信号, 等等) • 动态连接库 (DLL) • 用于输入和输出进程的可装载库 • 不同的实例数据执行在同一物理拷贝上 • 被当前进程激活/撤销控制 • 请求页面调度 • 将页面从存储器中提交/拷贝到RAM中用于执行 • 对于基于非压缩ROM的模块的在线执行(XIP) • 解压基于ROM模块到RAM中

  42. 系统 API 调用机制 • Coredll.dll • 定位每一个进程slot的头地址 • 从用户模式的线程实现对系统API的调用 • 直接实现一些系统API的调用 • 引起一个例外(陷阱)转递到系统API的请求上 • 内核 • 捕获系统API请求的异常陷阱 • 分配一个系统exe去执行请求 • 用户模式的线程切换到系统exe进程空间 • 用户模式的线程继承当前进程的访问权限

  43. 系统 API 调用机制 App.exe Nk.exe system EXE User mode thread KernelCall ReturnCall Function Call Coredll.dll KernelTrap Jump Win32 API Thunks Win32 API Dispatch Function Code

  44. • 用法 • 以字节为粒度来分配内存 • 独立于处理器(隐藏了内存分页) • 自动的分配内存和按要求提交页 • 不可变更 (当整个堆被释放时进行页面回收) • 使用首次适应算法(first-fit algorithm)通过堆列表进行管理 • 使用相同大小对象分配时效率最高 • 局部堆 • 在装载处理时保留192KB虚拟内存 • 提交进程分配的物理页面 • Private 堆 • 保留最初的固定和可扩展堆空间 • 一系列多线程的互斥对象 • Shared 堆 • 对于当前进程可写,对于其它进程只读

  45. • 用法 • 存储在一个函数中使用的临时数据 • 存储在执行处理过程中的处理器寄存器的状态 • 为每一个线程创建时分配默认的栈 • 按要求提交 • 大小 • 依赖于CPU默认的栈大小 • /STACK 连接器切换决定默认线程的栈大小 • 默认情况,一个进程的所有线程拥有相同的栈大小 • 使用 • /GS 连接器检查栈看是否有缓存溢出 • GetThreadCallStack – 恢复一个线程调用栈

More Related