单片机和CPU有什么区别呢?我觉得最大的区别是CPU一般都有MMU,有虚实地址的映射,有地址空间的权限管理等。
单片机编程和linux内核编程有什么区别呢?
共同点,是CPU提供的资源都可以使用。都可以对外围模块的寄存器进行读写,从而控制整个处理器的完整行为,不管是单片机还是CPU.
区别: 单片机编程一般是从零开始,HLA硬件抽象层都是自己建立,功能实现建立在HLA之上。对整个firmware具有100%的把控力
linux内核编程要利用linux提供的一些内核函数,遵守linux定义的一些规则,例如虚实地址映射。最简单的说,你手册里查到的寄存器地址,一般情况下都是无法直接进行访问的,这个视CPU的架构设计而定
作为一个单片机出身的linux系统工程师,我第一个兴趣点,就是如何像操作单片机一样,对CPU的所有外围具有充分的控制力?
这个问题可以简化为,如何控制CPU的各个寄存器?前面提到了虚实地址映射,代码中访问的地址必须是虚地址,而手册里提供的都是实地址,物理地址。
linux提供了很方便的映射机制。按照下面步骤,我们就可以像单片机一样,对CPU有绝对的控制力,从而进行各种功能实现
1)首先,当然是我们最有效的资料,CPU 数据手册,从中获得我们需要的寄存器的地址信息,当然这个地址,你直接在内核态下访问的,系统会遗憾的提示你一个oops。
2)调用内核提供的request_mem_region(start,len,name)向系统申请一段IO地址空间资源,这开始让我觉得很不爽,你个linux内核是为我服务的,我还得按你的规定一步步来。后来我想通了,就好比雇了一个管家,人家有自己的打理家庭的方式,你雇主是不该进行细节的规定地,用人不疑嘛。书归正传,调用返回一个非零值代表申请失败,绝大部分原因是在前面的调试中,插入内核模块时申请了这段资源,卸载时没有释放。如果返回零,恭喜你。这段寄存器空间是你的了。可以在/proc/iomem中看到你的地址范围和你静心起的名字了。
3)在申请下来资源后,剩下的问题就是使用了。仍然是内核大爷提供的函数ioremap(phy_start,len)返回的一个地址变量就是用来访问寄存器空间的起始地址,并且是虚地址,可以在代码里利用这个返回值加上手册里提供的偏移量访问你感兴趣的寄存器了。
这样,CPU就是一个很强力的单片机了。以前单片机的那一套东西,都拿来尽情使用吧。