从事安卓底层开发,工作八年,个人看法 。个人感脚51就是就是搞嵌入式第一门技术。把c语言,模数电,硬件画板等第一次联系起来。在学校的时候我们的学习路线是:

1 : 51单片机正在上传…重新上传取消(大二上学期的时候,我感觉我还是接触的挺晚的,嵌入式)

2:stm32+ucos ii正在上传…重新上传取消 (大二下学期到大三下学期)

3:Arm+linux (大四到毕业)

4.安卓驱动 ,JNI(工作,mtk平台)

然并卵,这句话适合51,但是也是非常非常非常重要的基础。如果作为学生的话,参加比赛啥的51还是不够用的。51作为最简单的单片机,真真的简单。相比于linux 安卓真的太简单。

--------------------------------------------------

51单片如我上文所说的,学生党接触的第一款单片机,答主是电子信息工程毕业的,接触的第一个单片机也是51,然后是STM32.51和STM32 STM32比51 难一点,不过本质上都是单片机,STM32片上外设多很多,定时器啥的复杂复杂复杂复杂复杂多的多。STM32片上外设多,功能强大,可以说学了STM32之后基本上所有的单片机应该都能马上上手的,虽然我也只是只接触到51 和STM32.。大四全国电子设计大赛之后就再也没有接触到单片机了。后来就一直是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<linux/init.h>#include<linux/module.h>#include<linux/fs.h>  //file_operatios#include<linux/device.h> //class_create/device_create#include<linux/slab.h>  //kmalloc#include<asm/io.h>  //ioremap#include<asm/uaccess.h>#include"led.h"struct s5pv210_device *s5pv210_dev;

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

static int led_open(struct inode *inode, struct file *file){printk(KERN_INFO"%s()-%d\n", __func__, __LINE__);

/*初始化GPC0_3,GPC0_4引脚功能为输出功能*/*gpc0con &= ~((0xf<<12)|(0xf<<16));*gpc0con |= ((0x1<<12)|(0x1<<16));return 0;}

static int led_close(struct inode *inode, struct file *file){printk(KERN_INFO"%s()-%d\n", __func__, __LINE__);//iounmap(S5PV210_PA_GPC0CON);return 0;}

static ssize_t led_read(struct file *file, char __user *buf, size_t count, loff_t *offset){printk(KERN_INFO"%s()-%d\n", __func__, __LINE__);

return 0;}

//write(fd, &val, 4)static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t *offset){int ret;unsigned int val;printk(KERN_INFO"%s()-%d\n", __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=%d\n",val);

if(val){//点亮LED*gpc0dat |= ((0x1<<3)|(0x1<<4));}else{//熄灭LED*gpc0dat &= ~((0x1<<3)|(0x1<<4));

}return ret?0:count;}

static struct file_operations led_fops={.owner = THIS_MODULE,.open = led_open,.read = led_read,.write = led_write,.release = led_close,

};

static int __init led_init(void){int ret;printk(KERN_INFO"%s()-%d\n", __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<0){printk(KERN_INFO"register major failed!\n");ret = -EINVAL;goto err1;}

/*创建设备文件*/s5pv210_dev->led_class = class_create(THIS_MODULE,"led_class");if (IS_ERR(s5pv210_dev->led_class)) {printk(KERN_ERR "class_create() failed for led_class\n");ret = -EINVAL;goto err2;}

s5pv210_dev->led_device = device_create(s5pv210_dev->led_class,NULL,MKDEV(led_major,0),NULL,"led");if (IS_ERR(s5pv210_dev->led_device)) {printk(KERN_ERR "device_create failed for led_device\n");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_class,MKDEV(led_major,0));err3:class_destroy(s5pv210_dev->led_class);err2:unregister_chrdev(led_major,"led");err1:kfree(s5pv210_dev);return ret;}static void __exit led_exit(void){printk(KERN_INFO"%s()-%d\n", __func__, __LINE__);unregister_chrdev(led_major,"led");device_destroy(s5pv210_dev->led_class,MKDEV(led_major,0));class_destroy(s5pv210_dev->led_class);iounmap(gpc0con);kfree(s5pv210_dev);}module_init(led_init);module_exit(led_exit);MODULE_LICENSE("GPL");

应用程序:

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

/*

** ./led_test on  点亮LED

** ./led_test off  熄灭LED

*/

int main(int argc, char **argv)

{

int fd;

int val =0;

fd = open("/dev/led", O_RDWR);

if(fd<0)

{

perror("open failed!\n");

exit(1);

}

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 <utils/Log.h>#include "jni.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>static int fd = -1;

jint open_led(JNIEnv *env, jobject thiz){LOGD("$$$%s\n", __FUNCTION__);fd = open("/dev/led1", O_RDWR);if(fd < 0){LOGE("open : %s\n", strerror(errno));return -1;}

return 0;}

jint led_on(JNIEnv *env, jobject thiz){LOGD("$$$%s\n", __FUNCTION__);int val = 1;jint ret = 0;ret = write(fd, &val, 4);if(ret != 4){LOGE("write : %s\n", strerror(errno));return -1;}return 0;}

jint led_off(JNIEnv *env, jobject thiz){LOGD("$$$%s\n", __FUNCTION__);int val = 0;jint ret = 0;ret = write(fd, &val, 4);if(ret != 4){LOGE("write : %s\n", strerror(errno));return -1;}return 0;}

jint close_led(JNIEnv *env, jobject thiz){LOGD("$$$%s\n", __FUNCTION__);if(fd > 0)close(fd);return 0;}

static JNINativeMethod myMethods[] ={{"openDev", "()I", (void *)open_led},{"onDev", "()I", (void *)led_on},{"offDev", "()I", (void *)led_off},{"closeDev", "()I", (void *)close_led},};

jint JNI_OnLoad(JavaVM * vm, void * reserved){JNIEnv *env = NULL;jint ret = -1;ret = vm->GetEnv((void **)&env, JNI_VERSION_1_4);if(ret < 0){LOGE("GetEnv error\n");return -1;}

jclass myclz = env->FindClass("com/ledtest/LedActivity");if(myclz == NULL){LOGE("FindClass error\n");return -1;}ret = env->RegisterNatives(myclz, myMethods, sizeof(myMethods)/sizeof(myMethods[0]));if(ret < 0){LOGE("RegisterNatives error\n");return -1;}

return JNI_VERSION_1_4;}

然后是java app:

package com.ledtest;

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

public class 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);}

OnClickListener clickListener = 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;}

}};

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

@Overridepublic boolean onCreateOptionsMenu(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;}

@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();

closeDev();}

static {System.loadLibrary("led_jni");}

public native int openDev();

public native int onDev();

public native int offDev();

public native int closeDev();}

框架是这样的:最上层是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。

通过地球259其中的5852最后316有干货~来的都发全套入门课程

扫地僧是怎样练成的,前辈学51单片机的感悟是怎么样的相关推荐

  1. python打印七段数码管引脚图_前辈学51单片机的感悟是怎么样的?说说看

    从事安卓底层开发,工作一年,个人看法 ,处女答.个人感脚51就是就是搞嵌入式第一门技术.把c语言,模数电,硬件画板等第一次联系起来.在学校的时候我们的学习路线是: 1 : 51单片机(大二上学期的时候 ...

  2. 练手小项目:51单片机控制的智能台灯设计(自动感应调光) 电路图,测试图,源代码全技术资料

    功能及概述 本系统组成如图一所示,主要由三部分组成: 传感器及信号处理部分:检测人体辐射红外信号及光强信号经过处理后变成可处理的数字信号 以80C51组成的中央处理单元:处理信号并发出控制命令 提醒电 ...

  3. 这家公司凭什么成了互联网教育的扫地僧?

    这几天看到一份榜单,<2015年8月移动APP排行榜TOP200>,其排榜依据是App的月活跃用户数,即MOU.这份榜单上出现的App基本都有所耳闻,唯有一家叫做"小伴龙&quo ...

  4. 北大扫地僧“火”了!手提馒头矿泉水的他,是博士毕业1年就成北大助理教授的90后!...

    学术整理自:齐鲁晚报.NSMath数学新星网.量子位.知乎等. 没想到,北大一男子因一瓶水.一袋馒头上了热搜. 那是在一个街头采访的视频中,一个看着像学生的男子手拿一瓶水.一袋馒头接受了媒体的采访. ...

  5. 【转】做一名开源社区的扫地僧 (上)

    不知道怎么为开源软件做贡献?从汇报 Bug 开始吧,或许还有钱赚呢- 且看 Qian Hong 的经验分享. 今年的软件自由日(SFD),我在广州Linux用户组的线下活动上做了一个分享,主题叫做&l ...

  6. 做一名开源社区的扫地僧——从Bug report到Google Summer of Code(GSoC):从200个bug到5000美金

    今年的软件自由日(SFD),我在广州Linux用户组的线下活动上做了一个分享,主题叫做<做一名开源社区的扫地僧(上)>.我把演讲的内容重新整理扩充, 写出了文字版, 希望可以跟更多朋友分享 ...

  7. 做一名开源社区的扫地僧

    不知道怎么为开源软件做贡献?从汇报 Bug 开始吧,或许还有钱赚呢- 且看 Qian Hong 的经验分享.全文转载开始 今年的软件自由日(SFD),我在广州Linux用户组的线下活动上做了一个分享, ...

  8. 做一名开源社区扫地僧(转)

    2019独角兽企业重金招聘Python工程师标准>>> 今年的软件自由日(SFD), 我在广州Linux用户组的线下活动上做了一个分享, 主题叫做<<做一名开源社区的扫地 ...

  9. 做一名开源社区的扫地僧 (上)

    原载:LinuxTOY 作者:黑日白月 原文网址:http://linuxtoy.org/archives/from-bug-reporter-google-summer-code.html 不知道怎 ...

最新文章

  1. 全面解读WEB 2.0
  2. mac安装mysql8.0.11_【MySQL】Mac安装MySQL(V8.0.15)蹚坑记录
  3. 后生可畏!中国军团称霸阅读理解竞赛RACE:微信AI称王,高中生力压腾讯康奈尔联队(附资料)...
  4. HDU2026 首字母变大写
  5. 算法设计与分析——递归与分治策略——棋盘覆盖
  6. 保驾护航金三银四,100%好评!
  7. vue-router linkActiveClass问题
  8. Python之快速排序算法实现(二)
  9. 深度学习入门:一句话告诉你什么是神经网络(CNN,RNN,DNN)
  10. java工作流flowable
  11. matlab线性规划系列之基础解题
  12. grunt源码解析1——如何安装grunt:grunt命令是怎样运行起来的
  13. Using Oracle Database 11g Release 2 Result Cache in an Oracle RAC Environment
  14. Cocos2d-x 2.0 百例精讲:如何让一个精灵跟随触点移动
  15. win7计算机广告更改,Win7电脑如何找到带来弹窗广告的软件【图文教程】
  16. 《MATLAB智能算法30个案例》:第20章 基于遗传模拟退火算法的聚类算法
  17. 基于python的网络舆情系统通用框架
  18. 抖音无水印视频解析源码
  19. python项目的QQ机器人使用及部署在腾讯云服务器
  20. 席裕庚《预测控制》学习记录 (一)-基于阶跃响应的动态矩阵控制(DMC)包含仿真

热门文章

  1. CFS调度时间片计算
  2. OSI七层网络模型 TCP五层网络模型
  3. STM32 RCC设置
  4. oppo reno7参数配置
  5. 一文带你了解web前端是如何制作表白网站(HTML+CSS+JS)
  6. GBase 8a数据库加载流程介绍
  7. 然后上传到linux主机上,Xshell实现Windows上传文件到Linux主机
  8. 工作流相关讲解 转载
  9. yum和repo详细解析
  10. java中实现同步的方法