嵌入式底层开发总结_嵌入式底层开发

2020-02-28 其他工作总结 下载本文

嵌入式底层开发总结由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“嵌入式底层开发”。

嵌入式底层开发总结

51单片机应该是大部分搞嵌入式最先接触的,也是学生时期接触的第一款单片机,本人是电子信息工程毕业的,接触的第一个单片机也是51,然后是STM32.51和STM32 STM32比51 难一点,不过本质上都是单片机,STM32片上外设多很多,定时器啥的复杂多的多。STM32片上外设多,功能强大,可以说学了STM32之后基本上所有的单片机应该都能马上上手的,虽然我也只是只接触到51 和STM32.。大四全国电子设计大赛之后就再也没有接触到单片机了。后来工作就一直是ARM+linux,android。

------------------任何计算机系统都是软件和硬件的结合体,如果只有硬件而没有软件,则硬件是没有灵魂的躯壳;如果只有软件没有硬件,则软件就是一堆无用的字符。在底层硬件的基础上,操作系统覆盖一层驱动,屏蔽底层硬件的操作,通过特定的软件接口去操作底层硬件,用户在用户空间可以很容易的把软件设计目标放在策略与需求上,可以很方便的屏蔽掉底层实现,从而很好的完成客户功能需求。计算机系统是软件和硬件的结合体。而软件又分为应用层软件和驱动层软件。驱动层软件是应用层软件和底层硬件的纽带。通过驱动层软件实现对底层硬件屏蔽。

在裸机时代,比如单片机系统,程序员往往是直接操作硬件寄存器,直接设置硬件。而在Linux操作系统中,硬件驱动程序中实现对硬件直接操作,而用户空间,通过通用的系统调用接口,实现对硬件操作,应用程序没有直接操作底层设备,通过posix标准,应用程序的系统调用往往是被规定和限值,用户只能通过规定的接口实现对底层硬件的操作,导致了应用程序在类UINIX操作系统具有非常好的可移植性。

图2.1 直接操作硬件程序

上图2.1 是裸机时代,应用程序和硬件操作糅合在一起,应用程序和硬件操作高度耦合的框图,上述代码一般很难有良好的代码互用和移植性。往往从一个平台移植到另一个平台,甚至是同一平台不同硬件配置都要求很大的代码改动,另外从应用层来说,应用与驱动高度耦合,应用程序也几乎难以移植,甚至说是没有应用程序概念,原因在于应用与驱动的纠缠不清。

图2.2 无操作系统应用程序和设备驱动程序关系

上图2.2所示,良好的裸机代码框架,设备驱动层和应用层之间有良好的分层思想,用户可以较好的实现策略和需求,例如:客户要求实现流水灯程序,程序员在底层机制实现(硬件操作)的基础下,可以充分在用户应用程序中把主要精力方法流水灯的实现,即策略。但是在良好的裸机程序设计,代码移植性可能从一个平台移植到另外一平台只需要修改少量的底层驱动,例如:LED_ON()的实现。但是在用户空间,没有系统调用概念,函数接口千差万别。应用程序移植性差。

图2.3 Linux系统调用框图

操作系统中,需求决定应用程序,通过系统调用,调用底层驱动,此外,在驱动程序中,把一部分公用的驱动接口抽象出来,如此,程序员只需修改很少量的驱动资源,形成特定的驱动框架。导致用户只需添加专用的硬件属性作为平台资源,在内核中获取资源,大大解放了设备驱动开发,提高了设备驱动的通用型。在用户空间,由于遵循posix标准,类UNIX操作系统中,所有操作接口基本一样,从而方便了应用程序的移植,应用程序几乎不要做修改。如图2.3所示。

Linux操作系统对于所有的硬件都是当做一个文件来操作:一切设备皆文件。Linux设备文件一般分为字符设备,块设备,网络设备。在Linux系统中,除了网络设备之外,所有的设备都被映射到Linux的文件系统中。如图2.4所示。

图2.4 Linux操作系统与应用程序关系

----------------讲讲51,linux,安卓之间的差别。先申明一下,我是实际工作中没有使用过单片机,我使用单片机仅仅是用来参加全国电子设计大赛。工作主要在android driver这一块。我们这一行很多人说单片机是有瓶颈的,我也不是很清楚。但是实话实说,这鸟东西太简单了,没啥技术含量的,你要之后android的庞大。

欢迎点赞。后面会说说android,linux,51,32单片机之间的联系与学习方法,虽然我也是菜鸟,如果你现在看不懂也没关系,有个映像就行。以后就有方向去学习了。想当初我真的是一个人孤孤学习linux ================= 补充一个:单片机要点亮一个led等,同样在安卓上你点亮一个灯也要驱动的,不然怎么亮呢,只是我们只看到了app。背后驱动,怎么实现的,安卓架构,跟单片机有啥区别,相同的地方。其实手机arm芯片跟单片机都是嵌入式微处理器,单片机叫做微控制器。高通,mtk啥的也是嵌入式微处理器~都是一样的~但是难度你想想看就知道了。

51单片机大家都知道了,裸机,直接操作硬件,直观,简单,没有框架,没有系统。STM32,可以学习一下RTOS了,实时的小系统,ucos II等等许多实时系统,STM32+ucos II这种组合学习方式还是挺好的。STM32比较难的在我印象中一个是时钟树,因为我们从51,没有时钟树的概念12M晶振,时钟不要你配置,而比较新的ARM框架,外设都是有时钟的。可能刚刚接触概念不是很清楚,但是也是很简单的。另外一个是定时器,什么输入捕获模式,定时器模式,编码器模式。。。强大的多,比起51。总的来说还是简单的。因为是没有框架的原因,代码量真的很少。你要知道,MTK android 5.1 所有的东西加起来 10G多,包括bootloader,linux kernel,android framework,定制的部分。等等。我们接触的就那些目录,当你去看C++,java代码时,你就知道面向过程的代码真的很容易看。可能有些朋友不知道android的框架,以及android 与linux之间的关系,以及linux驱动与裸机的关系,联系与区别。你现在只要知道linux驱动比较大,android框架更大。单片机简单。单片机一般是C语言,而android一般涉及三种语言:底层linux内核C,中间的JNI层是C++,framework和app是java。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 学过51单片机的朋友知道,我们要点亮一个LED灯,是这样子的P0 = xxx,我们就点亮了一个,好。一烧写,好,灯亮了。linux,上我们要亮一个灯,有点难了,有了操作系统,没那么容易了。一般人搞不定了。好,到android,更加难了。但是你想一想手机芯片也是ARM。亮灯这种肯定都是CPU的管脚操作。上了系统了,难了,点个灯都费劲的。本质上是一样的。很多人都知道单片机有瓶颈的。原因是会点硬件,会点C,轻轻松松就可以亮灯的。入门容易。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 我举一个小的例子说明一下51,linux,android三者的之间的差别。你就知道是啥区别。下面是51单片机: 大概是这样: int main(void)//一个main函数搞定 { P0 = 0xxx;while(1);return 0;} linux: 驱动程序: #include #include #include //file_operatios

//cla_create/device_create #include #include //kmalloc #include //ioremap #include #include“led.h”

struct s5pv210_device *s5pv210_dev;

volatile unsigned long *gpc0con = NULL;volatile unsigned long *gpc0dat = NULL;

staticintled_open(structinode *inode, struct file *file){ printk(KERN_INFO“%s()-%dn”, __func__, __LINE__);

/*初始化GPC0_3,GPC0_4引脚功能为输出功能*/ *gpc0con &= ~((0xf

staticize_tled_read(struct file *file, char __user *buf, size_t count, loff_t *offset){ printk(KERN_INFO“%s()-%dn”, __func__, __LINE__);return 0;}

//write(fd, &val, 4)static ize_tled_write(struct file *file, const char __user *buf, size_t count, loff_t *offset){ int ret;unsignedintval;printk(KERN_INFO“%s()-%dn”, __func__, __LINE__);

/*获取用户空间数据*/ ret = copy_from_user(&val,buf,count);if(ret){ printk(KERN_ERR“copy data from user failed!n”);return-ENODATA;}

printk(KERN_INFO“copy data from user: val=%dn”,val);if(val){ //点亮LED *gpc0dat |=((0x1

staticstructfile_operationsled_fops={.owner = THIS_MODULE,.open = led_open,.read = led_read,.write = led_write,.release = led_close, };

staticint __initled_init(void){ int ret;printk(KERN_INFO“%s()-%dn”, __func__, __LINE__);s5pv210_dev = kmalloc(sizeof(struct s5pv210_device),GFP_KERNEL);if(s5pv210_dev==NULL){ printk(KERN_INFO“no memory malloc for s5pv210_dev!n”);return-ENOMEM;} /*注册*/ led_major = register_chrdev(0,“led”,&led_fops);if(led_major

/*创建设备文件*/ s5pv210_dev->led_cla = cla_create(THIS_MODULE,“led_cla”);if(IS_ERR(s5pv210_dev->led_cla)){ printk(KERN_ERR “cla_create()failed for led_clan”);ret =-EINVAL;goto err2;}

s5pv210_dev->led_device = device_create(s5pv210_dev->led_cla,NULL,MKDEV(led_major,0),NULL,“led”);if(IS_ERR(s5pv210_dev->led_device)){ printk(KERN_ERR “device_create failed for led_devicen”);ret =-ENODEV;goto err3;}

/*将物理地址映射为虚拟地址*/ gpc0con = ioremap(S5PV210_PA_GPC0CON,8);if(gpc0con==NULL){ printk(KERN_INFO“ioremap failed!n”);ret =-ENOMEM;goto err4;} gpc0dat = gpc0con + 1;

return 0;err4: device_destroy(s5pv210_dev->led_cla,MKDEV(led_major,0));err3: cla_destroy(s5pv210_dev->led_cla);err2: unregister_chrdev(led_major,“led”);err1: kfree(s5pv210_dev);return ret;} static void __exit led_exit(void){ printk(KERN_INFO“%s()-%dn”, __func__, __LINE__);unregister_chrdev(led_major,“led”);device_destroy(s5pv210_dev->led_cla,MKDEV(led_major,0));cla_destroy(s5pv210_dev->led_cla);iounmap(gpc0con);kfree(s5pv210_dev);} module_init(led_init);module_exit(led_exit);MODULE_LICENSE(“GPL”);

应用程序:

#include #include #include #include #include #include #include #include /* **./led_test on 点亮LED **./led_test off 熄灭LED */ int main(intargc, char **argv){ intfd;intval =0;fd = open(“/dev/led”, O_RDWR);if(fd

if(strcmp(argv[1], “on”)==0){ val = 1;} else { val = 0;}

if(write(fd, &val, 4)!=4){ perror(“write failed!n”);exit(1);} close(fd);return 0;}

android:

不知道大家清不清楚android与linux之间的关系。

android是基于linux内核的,linux操作系统的5大组件:驱动,内存管理,文件系统,进程管理,网络套接字。android是基于linux kernel上的,大家平时只看到了app。app是java语言的,其实每运行一个java应用程序,实际上是fork一个linux应用程序。android四大组件,activity,service,Broadcast Receiver,Content Provider。这是android的主要框架,java应用开发是基于这开发的。android平台是基于linux内核的。在linux运行之后才建立起java世界。

直接上代码:上面的linux的驱动在android是一样的,适用于android。驱动ok之后是应用层了,也就是应用程序。我下面就是最直接的应用,不包含任何android框架性的东西,大家可以直接看到,应用app->jni->linux驱动这三层调用关系。下面是jni代码是c++; #define LOG_TAG “led-jni-log” #include

#include “jni.h”

#include #include #include #include #include #include #include

staticintfd =-1;jintopen_led(JNIEnv *env, jobjectthiz){ LOGD(“$$%sn”, __FUNCTION__);fd = open(“/dev/led1”, O_RDWR);if(fd

jintled_on(JNIEnv *env, jobjectthiz){ LOGD(“$$%sn”, __FUNCTION__);intval = 1;jint ret = 0;ret = write(fd, &val, 4);if(ret!= 4){ LOGE(“write : %sn”, strerror(errno));return-1;} return 0;}

jintled_off(JNIEnv *env, jobjectthiz){ LOGD(“$$%sn”, __FUNCTION__);intval = 0;jint ret = 0;ret = write(fd, &val, 4);if(ret!= 4){ LOGE(“write : %sn”, strerror(errno));return-1;} return 0;}

jintclose_led(JNIEnv *env, jobjectthiz){ LOGD(“$$%sn”, __FUNCTION__);if(fd> 0)close(fd);return 0;}

staticJNINativeMethodmyMethods[] ={ {“openDev”, “()I”,(void *)open_led}, {“onDev”, “()I”,(void *)led_on}, {“offDev”, “()I”,(void *)led_off}, {“closeDev”, “()I”,(void *)close_led}, };jintJNI_OnLoad(JavaVM * vm, void * reserved){ JNIEnv *env = NULL;jint ret =-1;ret = vm->GetEnv((void **)&env, JNI_VERSION_1_4);if(ret

jclamyclz = env->FindCla(“com/ledtest/LedActivity”);if(myclz == NULL){ LOGE(“FindCla errorn”);return-1;} ret = env->RegisterNatives(myclz, myMethods, sizeof(myMethods)/sizeof(myMethods[0]));if(ret

return JNI_VERSION_1_4;} 然后是java app: packagecom.ledtest;

importandroid.os.Bundle;importandroid.app.Activity;importandroid.util.Log;importandroid.view.Menu;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;

public cla LedActivity extends Activity {

final String TAG = “LedActivity”;public Button btn_on = null;public Button btn_off = null;

public void init(){ btn_on =(Button)this.findViewById(R.id.btn1);btn_on.setOnClickListener(clickListener);

btn_off =(Button)this.findViewById(R.id.btn2);btn_off.setOnClickListener(clickListener);}

OnClickListenerclickListener = new OnClickListener(){ public void onClick(View v){ switch(v.getId()){ case R.id.btn1: Log.d(TAG, “led on in app”);onDev();break;case R.id.btn2: Log.d(TAG, “led off in app”);offDev();break;default: break;} } };

@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_led);init();openDev();}

@Override publicbooleanonCreateOptionsMenu(Menu menu){ // Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.activity_led, menu);return true;}

@Override protected void onDestroy(){ // TODO Auto-generated method stub super.onDestroy();

closeDev();} static { System.loadLibrary(“led_jni”);}

public native intopenDev();

public native intonDev();

public native intoffDev();

public native intcloseDev();}

框架是这样的:最上层是java,点开app,点击一下一个button,点亮了LED,调用onDev();onDev调用c++的led_on,然后led_on是调用驱动的led_write,明白不?这样说吧:linux驱动是最下层的,驱动嘛。然后是c++层,c++包装一下是给java调用的,然后到java层。下面是android比价经典的一张框架图。

linux在最下面。lib 是动态库。然后是JNI,然后是Framework(android框架),然后是大家喜闻乐见的app。linux在最下面。lib 是动态库。然后是JNI,然后是Framework(android框架),然后是大家喜闻乐见的app。

《嵌入式底层开发总结.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
嵌入式底层开发总结
点击下载文档
相关专题 嵌入式底层开发 底层 嵌入式 嵌入式底层开发 底层 嵌入式
[其他工作总结]相关推荐
    [其他工作总结]热门文章
      下载全文