很多人在学习安卓的过程里,总会觉得不知如何下手。究其原因,大多数因为不懂底层原理,很多从上层应用过来,听过框架,但也不知到底这个范围怎么界定。这一节,我们来说说操作系统。
乍一听好唬人,竟然想把操作系统讲透。实话来说,这里面要追细节,必然没完没了。于是,这节通过一种思维,将这些理论知识尽量清晰的讲给大家。
这里我再次抛出几个词语。硬件-驱动-软件。这里我们用屏幕来举例,做过单片机的朋友很容易就能理解这三个的关系,我们再来看下这个过程。
拿到一个屏,直接是不能按照你的要求显示。它需要做几个事情,才能让它正常工作。
主要有,把它连接到一个板子上。
然后要做的事,给屏安个开关,写一个开关方法,写一个读写某一位置的点亮情况,如果是多彩的,读写一个位置的颜色值。
写完这个,我们再实现一些封装。可以画一条线,画一条渐变的线条,画个正方行,画个圆,椭圆,扇形。
再继续一层,可以画个点阵字,支持国标码的文字显示。
再继续一层,可以解析ttf字库,画个矢量字。
然后我们用这个东西,写了个hello world!在屏幕上。
现在我们来拆解前面的信息:
硬件部分:
把它连接到一个板子上
驱动部分:
给屏安个开关,写一个开关方法,写一个读写某一位置的点亮情况,如果是多彩的,读写一个位置的颜色值。
驱动层封装:(SDK)
可以画一条线,画一条渐变的线条,画个正方行,画个圆,椭圆,扇形。
继续封装:(SDK)
可以画个点阵字,支持国标码的文字显示。
可以解析ttf字库,画个矢量字。
软件应用:
写了个hello world!在屏幕上。
总结起来就是三部分 硬件--驱动--(二次封装SDK)--软件
这里再感觉一个小板子,让大家对板子有个概念。
一个手机系统,或者别的板子系统,主要有这几个部分,外设****--CPU--应用。这里简单化,主要想说的是,我们的整体,都不过是输入--控制--输出。
在刚开始的51单片机,因为本身ROM,RAM比较小,功能也比较简单,主要是做类似温度检测,然后LED显示,或者加上报警,振动之类的。
所以基本不要操作系统介入,就是很简单的上电之后,进入一个死循环。类似如下这种:
while(1)
{
int ret=getEvent(&evt)//获取消息
switch(evt.Type)
{
case XXX:
break;
}
wirteWatchDog(0);
}
然后这个在执行的时候,我们这里getEvent可以是死等状态,当然如果有看门狗,那么就不能死等,要往下走,让走到wirteWatchDog里面,进行对某个位置写入固定的值,系统会判定这里的值,如果固定时间内,没有进行写值,则认为系统跑飞。而系统怎么会跑飞呢?因为器件会老化,或者外部环境过热,过冷,会导致器件出故障,这时候系统判定跑飞,让系统重启,进行恢复。
这里我们引用一个网络对于看门狗的描述:
看门狗是用来防止万一单片机程序出错造成重大损失的。防错的原理很简单,它在硬件上就是一个定时器,当它溢出的时候就会让单片机强制复位使程序重新开始执行。正常的情况下是不能让它溢出的,所以在程序上每隔一段时间要给他置一次值(俗称喂狗),只要程序中正常给它喂他就不会溢出。一旦程序跑飞了,有干扰或者进入死循环之类的情况时,不能正常执行程序了,那么就永远执行不到喂狗的指令了,但此时定时器是硬件控制的,仍然会走,所以溢出了,单片机就复位了。一般安全性要求比较高的,系统跑飞了会造成重大事故的都会加一个“狗”保安全。通常,看门狗的溢出时间越短越灵敏,跑飞之后复位的时间越短,也就越安全,但是,你喂狗的操作也要更频繁。
过了51单片机,就进入了比较复杂的Arm嵌入式,这个时候RAM已经比较大了,系统也比较复杂,所以需要多个任务并发,来协同完成。
μC/OS-****II****FreeRTOS****ucLinux是在这个场景中,使用最广泛的操作系统。当时的操作系统,没有那么复杂,同时也是使用的任务称呼,可以对应linux中的线程了。
在开始讲这些的时候,我想通过一些好玩的故事,来理解这些东西。
故事一:
有个单间澡堂,一次只能进入一个人,如果里面有人,外面的就必须等着,等他洗完了,下一个人才能进去洗澡。
这里我们把澡堂看成CPU,把人当做指令,那么上面的话就是:
有个单CPU,一次只能执行一条指令,如果当前正在执行指令,后续的指令就只能等着,等它执行完了,下一条指令才能进去执行。
故事二:
这时候如果来了一个恶霸,要进行洗澡。我们假设里面的人,听不见外面的吵闹,继续忘我的洗澡。所以,恶霸能够洗上澡的话,最快也是要等这个人洗完出来。
这里我们把恶霸当做中断的话,那么上面的话就是:
这时候如果来了一个中断,要进行执行。中断能够执行,最快也是要等这条指令执行完。
于是,我们总结便是,CPU按照一条条指令执行,当有中断来的时候,要等待这条指令执行完,CPU这时候扫描下中断线,有中断,则处理中断任务。
故事三:
我们翻过之前的故事。然后再来一个故事。故事的主角还是澡堂。
话说村子里有个老头,开了个澡堂子,两口子一直经营着,收益非常好。于是两人喜形于色,上天也眷顾,觉得这么多钱需要人花,老两口就生了个双胞胎。
双胞胎长大之后,发现了澡堂的暴利,于是两人都想占为己有。一天为了这个打得不可开交。老头回来一看,这可不行啊,于是想了个法子。
老头子说两个兄弟可以同时卖票,但是每个买完票的人,就在门口排队,洗完澡的出来,然后排队在前面的人便可以进去洗澡,如此就解决了。
这里老头子假定为操作系统,两儿子就是两个进程,排队就可以认为是通信机制,这里成为队列,澡堂子就是资源。
于是,我们总结便是,操作系统生成了两个进程,两个进程都在访问一个资源,于是就发生了抢占的事情,解决的思路就是操作系统实现一些机制,保证进程之间按照顺序执行,也就有了进程间通信。
故事四:
事情总会有意外,老头子在把手,如果两边来的人,同时抢一个位置,互不相让。都说下一个是他,该如何解决呢。
我们在第一个故事里面知道,单核CPU只能一条条指令执行,如果有人想打断,必须等到这条指令结束后,进行处理。
那么我们继续这个故事。两个人互不相让,纠缠不清的时候,老人说,有个方法,既然你们争持不下,那么我这边配置了一个锁子,这个锁子非常神奇,你们两个必然不能同时拿到,并且只要一个拿到后,下一个必然就拿不到了。拿到的就是先来的,没拿到的自然在后面排序。
在你认为两人同时到的时候,老人只管一个个执行,于是,老人在一瞬间,只会看到一个人来,而看到后他就交给了这个人,后面的人自然就要排在后面了。
翻译过来就是:CPU只会一条条指令执行,那么必然下一个指令只会有一个,而这条指令就将钥匙给出去,让当前的状态为无钥匙状态,那么当两个进程在抢占的时候,第一个进来一看有钥匙,就拿走了,第二个必然就看到没有钥匙了。这样子就能保证资源正确标记,而这种机制便是互斥锁。当多个进程访问同一资源的时候,便会发生。
网友评论