windows ce 嵌入式系统读书笔记(一)

 引导程序BootLoader是在硬件开发板上执行的一段代码,它的主要功能是初始化硬件,加载操作系统映像到内存,然后跳转到操作系统代码去执行。BootLoader可通过串口、usb、以太网下载;BootLoader也可以从本地的存储设备,例如cf卡和硬盘中读取操作系统映像。当BootLoader得到操作系统映像后,它可把操作系统映像存放到内存里或者本地的存储设备中以便以后使用。
当引导程序引导操作系统结束后,由oal负责硬件平台初始化,包括中断服务例程、实时时钟、计时器、内核调试、开关中断和内核性能监测等工作。
所有的应用程序都不能直接与操作系统或硬件打交道,如果应用程序希望访问windows ce所提供的服务,那么只能通过coredll.dll进行。
coredll.dll的主要功能是负责应用程序与windows ce通信以及完成windows ce的系统调用。系统调用是操作系统向应用程序提供的服务,一般以函数的形式提供,这些函数通常在应用程序之外的进程中实现。coredll.dll会被windows ce上的所有进程加载。
其实在windows ce中,系统调用发生的整个过程中,并没有发生真正的县城上下文切换。windows ce内核负责把api调用转到实现该api的psl进程。psl进程会把进行系统调用的执行线程从一个进程迁移到下一个进程。也就是说,在整个系统调用过程中,在处理器上执行的线程始终是同一个。从系统的角度看,每个应用程序都是windows ce中的一个单独的进程。

TCHAR szBuf[MAX_PATH];
DWORD dwPathLen;
TCHAR pStr = NULL;
dwPathLen = GetModuleFileName(NULL, szBuf, MAX_PATH);
if(! dwPathLen)
{
  return -1;
}

while(szBuf[--dwPathLen] !='//');
szBuf[dwPathLen + 1] = NULL;
_tcscat(szBuf, TEXT("MyFile.txt"));

CeGetThreadPriority();
CeSetThreadPriority();
使用这两个函数设置的优先级只能是248~255之间的某个值。
通常在串行接口控制器上会有两个FIFO用作接收和发送缓冲,当接收到数据后会直接将接收到的数据置入该缓冲器,并同时由控制电路向本地总线发出通知,以便让本地总线将缓冲器内的数据读走,这样在响应(等待和读取)的过程中仍然能通过缓冲器接收数据。
如果某些共享资源同时只能被一个线程访问,那么使用Mutex对其进行同步是最好的选择。
在创建时如果mutex名字不为空,系统会首先搜索系统中已经存在的mutex,如果发现有同名的mutex,则直接返回该mutex;否则就创建一个新的同步对象。
HANDLE hMutex;
INT i = 0;
VOID Init()
{
hMutex = CreateMutex(NULL, FALSE, NULL);
CreateThread(NULL, NULL, ThreadProc1, NULL, NULL, NULL);
CreateThread(NULL, NULL, ThreadProc2, NULL, NULL, NULL);
}

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
WaitForSingleObject(hMutex, INFINITE);
i++;
ReleaseMutex(hMutex);
reture 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
WaitForSingleObject(hMutex, INFINITE);
i--;
ReleaseMutex(hMutex);
return 0;
}

如果某些共享资源同时只能被固定数量的线程使用,那么应该选用semaphore对它进行同步。如果一个semaphore带有计数n,当n个线程占有了semaphore后,其他希望占有该semaphore的线程才会进入等待状态。
在windows ce中,除了oal之外的任何地方关中断都是不支持的。
使用wm_copydata只适合有窗口消息队列的进程。
通过内存映射文件可在进程的共享虚拟地址空间内保留一个地址空间的区域,同时将文件所在的物理内存映射到此区域。这样,只须对虚拟内存进行读写操作就能实现对文件的操作。

通过使用消息队列获得文件系统挂载的通知。
DWORD NotificationsThread(LPVOID lpParameter)
{
GUID guid = STORE_MOUNT_GUID;
HANDLE hMsgQ;
DWORD numRead;
DWORD flags;
BYTE buf[sizeof(DEVDETAIL) + MAX_DEVCLASS_NAMELEN * sizeof(TCHAR)];
MSGQUEUEOPTIONS qoptions = {sizeof(MSGQUEUEOPTIONS), MSGQUEUE_NOPRECOMMIT, 0, sizeof(buf), TRUE};
hMsgQ = CreateMsgQueue(NULL, &qoptions);
if(hMsgQ == NULL)
{
return 0;
}

hNotifications = RequestDeviceNotifications(&guid, hMsgQ, TRUE);
if(hNotifications == NULL)
{
return 0;
}

HANDLE waitHandles[] = {XXXXXX, hStopEvent};
while(WAIT_OBJECT_0 == WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE))
{
if(!ReadMsgQueue(hMsgQ, buf, sizeof(buf), &numRead, 0, &flags))
{
return 0;
}

OnMountStorage(*((const DEVDETAIL *)buf, flags);
}

CloseMsgQueue(hMsgQ);
CloseHandle(hStopEvent);

return 1;
}

ram为操作系统和应用程序提供运行和缓冲空间。rom在windows ce中通常用来存储程序。其内容可断电永久保存。rom中的内容通常是不能改动的。rom中的程序可被复制到内存中然后再执行。windows ce也支持本地执行,本地执行时代码无需复制到内存中,而直接在rom中执行。windows ce的所有进程共享一个4gb的虚拟地址空间。
虚拟内存把进程申请的内存映射到物理内存,并且提供4gb的寻址能力。
可用GetProcessHeap()来得到默认堆。默认对保留192kb大小的虚拟内存。可用VirtualAlloc()函数来为默认堆申请更多内存。函数调用是进行参数传递,函数中的局部变量都占用栈上的内存,而且在函数调用结束后自动释放。windows ce为每个线程分配60kb的栈,并且把栈顶的2kb拿来作为检测栈是否已满。从操作系统的角度来看,malloc和new都返回默认堆上的一个指针,堆管理器并不对crt库函数和LocalAlloc()函数申请的内存进行区分,而是把它们一视同仁。new可自动调用c++语言类的构造函数,delete会调用类的析构函数,这些功能是windows api无法取代的。
除了系统启动时mmu被启用之前的一小段代码之外,windows ce内核和应用程序都是工作在虚拟内存模式下的。windows ce提供了如下几个内存访问函数来访问虚拟内存。
VirtualAlloc();
VirtualFree();
VirtualProtect();
VirtualQuery();
对象存储是一个被FILESYS.EXE控制的内存堆,如果有后备电源,它就可以为应用程序提供永久的存储。
基于ram的注册表把整个注册表作为一个对象存储堆存放在系统内存中。这意味着如果对系统进行冷启动或者系统断电,对注册表的所有改动都会丢失。
1.windows ce提供了两个系统api用来保存和还原整个注册表。
RegCopyFile();
RegRestoreFile();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值