嵌入式linux_嵌入式linux开发 - CSDN
嵌入式linux 订阅
嵌入式 Linux是嵌入式操作系统的一个新成员,其最大的特点是源代码公开并且遵循GPL协议,近几年来已成为研究热点。目前正在开发的嵌入式系统中,有近50%的项目选择Linux作为嵌入式操作系统。 [1]  嵌入式linux 是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。嵌入式linux既继承了Internet上无限的开放源代码资源,又具有嵌入式操作系统的特性。嵌入式Linux的特点是版权费免费;购买费用媒介成本技术支持全世界的自由软件开发者提供支持网络特性免费,而且性能优异,软件移植容易,代码开放,有许多应用软件支持,应用产品开发周期短,新产品上市迅速,因为有许多公开的代码可以参考和移植,实时性能RT_Linux Hardhat Linux 等嵌入式Linux支持,实时性能稳定性好安全性好。 [2] 展开全文
嵌入式 Linux是嵌入式操作系统的一个新成员,其最大的特点是源代码公开并且遵循GPL协议,近几年来已成为研究热点。目前正在开发的嵌入式系统中,有近50%的项目选择Linux作为嵌入式操作系统。 [1]  嵌入式linux 是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。嵌入式linux既继承了Internet上无限的开放源代码资源,又具有嵌入式操作系统的特性。嵌入式Linux的特点是版权费免费;购买费用媒介成本技术支持全世界的自由软件开发者提供支持网络特性免费,而且性能优异,软件移植容易,代码开放,有许多应用软件支持,应用产品开发周期短,新产品上市迅速,因为有许多公开的代码可以参考和移植,实时性能RT_Linux Hardhat Linux 等嵌入式Linux支持,实时性能稳定性好安全性好。 [2]
信息
广泛应用
移动电话
行业协会
Embedded Linux Consortum
中文名
嵌入式linux
出    现
20世纪60年代晚期
嵌入式linux简介
嵌入式linux 是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。嵌入式linux既继承了Internet上无限的开放源代码资源,又具有嵌入式操作系统的特性。嵌入式Linux的特点是版权费免费;购买费用媒介成本技术支持全世界的自由软件开发者提供支持网络特性免费,而且性能优异,软件移植容易,代码开放,有许多应用软件支持,应用产品开发周期短,新产品上市迅速,因为有许多公开的代码可以参考和移植,实时性能RT_Linux Hardhat Linux 等嵌入式Linux支持,实时性能稳定性好安全性好。 [2]  如果分别让10位工程师给出嵌入式系统的定义,将得到10个不同的答案。一般来说,大部分的嵌入式系统执行特定的任务。我们假定最简单的嵌入式系统包括输入/输出功能,以及一些控制逻辑,该系统基于它的配置执行某些类型的功能。按照这个标准,可以认为一个包含实现控制逻辑74123计数器以及一个状态是一个嵌入式系统。也许可以补充说,该系统必须可通过存储在固件中的软件进行编程。这个新的嵌入式系统定义包括输入/输出(I/O),以及存储在系统固件中的控制逻辑。一个带有鼠标、键盘、网络连接并运行图形用户界面(GUI,graphical user interface)多任务操作系统的桌面计算机显然满足这些要求,但我们能认为它是一个嵌入式系统吗?如果桌面计算机不是一个嵌入式系统,那么手持设备呢?它们有I/O功能,可以运行存储在固件中的控制逻辑。有人说,桌面计算机和手持设备都有通用计算机设备,可以运行软件来执行许多不同的任务,与之不同的是,嵌入式系统(例如,洗碗机控制器或飞行导航系统)主要是为特定任务而设计的。这种特定的功能限定使嵌入式设备有功能上的唯一性。如果是这样,为什么一些嵌入式系统设计成具有附加的功能,如存储在非易失性存储器中的程序,并且具有运行可以完成原始设计范围之外的任务的多任务操作系统的能力呢?在过去,区分嵌入式系统和通用计算机比简单得多。例如,可以很容易地区分出一个基于8051的T1分幅卡嵌入式系统和一台Sun UNIX工作站。从功能方面很难区分一台Sun工作站和一个包含PowerPC以及32MB内存和16MB闪存的机顶盒。这样的机顶盒可以运行带GUI的多任务操作系统,可现场升级,可以同时运行多个程序(如视频控制器、数字录像和Java虚拟机),还可以进行安全的因特网在线交易。很难判断这种机顶盒是否是一个嵌入式系统。显然,硬件性能的提升和价格的下降使通用计算机和嵌入式系统之间的界限变得很模糊,技术的进步使得我们很难定义什么是嵌入式。
收起全文
精华内容
参与话题
  • 嵌入式Linux入门:概述

    万次阅读 多人点赞 2019-09-25 14:07:27
    本文就结合笔者经历写一写个人的嵌入式Linux入门的一些步骤和经验。不当之处,望方家指正。 在正式开始之前,先花一点时间写写笔者学习的经历。我是计算机专业,因此,对于模拟电路、数字电路、操作系统原理、...

    李迟按:

    嵌入式入门文章比比皆是,不同的人有不同的入门方法。本文就结合笔者经历写一写个人的嵌入式Linux入门的一些步骤和经验。不当之处,望方家指正。

    在正式开始之前,先花一点时间写写笔者学习的经历。我是计算机专业,因此,对于模拟电路、数字电路、操作系统原理、数据库原理、编译原理、计算组成原理、计算机体系结构、数据结构等等课程,都是必修课。我虽然都不精通,但起码是学习了。

    我从大二开始就已经接触51和AVR单片机,当时机缘巧合,由同专业的同学——也是我老乡带我开始的。然后开始画板、做板、焊板、写程序这些路子,前后陆续接触大约一两年时间,这些经历对于自学嵌入式Linux打下很好的基础。——事实上,在我开发单片机时,我已经计划好要学嵌入式,而且是偏向软件方向。

    同时我也开始安装Linux,自己捣鼓,包括虚拟机安装、物理机安装。因为考试和困难放弃一段时间,但最后还是继续。

    后来大三买了一块ARM9的开发板,自己捣鼓(不用“研究”,是因为以纯粹的门外汉去进行的)uboot、内核、根文件系统。本着不服输的精神,虽然一度放弃,但还是坚持下去。

    在毕业时慢慢摸到一些门道。但此时技术还不够,代码量还不够,后来工作多年,大量接触各式不同的技术,虽然并没有很深入,但足够养成习惯,——解决问题、研究新技术的方法、习惯。

    综上,我走的路子概括为:单片机-->使用Linux-->嵌入式Linux(u-boot->kernel->rootfs)。软件知识:基础必修课->linux环境编译->Linux驱动。

    从上文可以看到,笔者是作为计算机专业的学生而进入嵌入式Linux领域的。但并不是说一定要在学校学习那些课程才能入门。无论学习什么知识,都是靠自己进行的,但有了过来人指点、带你入门,往往省时省力很多——而这正是本文的目的。

    下面进入正文部分。

    一、系统环境

    1、环境搭建

    开发嵌入式需要大量辅助软件,一般来说,我们是在电脑上开发好程序,然后通过某些方式将程序下载到开发板上运行。按这个顺序列出一些我认为必须的:

    Linux系统:主要作为程序开发的系统,选择多人使用并资源丰富的版本,建议ubuntu或fedora,目前我使用ubuntu。可以使用在虚拟机或物理机上。

    虚拟机:有条件的推荐使用物理机安装,但一般经常使用vmware这类虚拟机软件,通过这个软件安装ubuntu系统,然后设置共享。然后在这个系统上交叉编译。

    共享方式:有的人喜欢用vmware自带共享功能,有的人喜欢用samba共享。个人建议在ubuntu中设置samba共享,这样可以在windows上将ubuntu共享目录映射成为其中一个盘符,这样做,就可以在windows下操作linux系统的目录、文件了,不过前提是需要网络性能良好。另一种常见的共享方式是nfs,多用于主机和开发板之间的文件传输。

    开发IDE:有的人建议在linux系统中用vim或emacs,但作为初学者入门,不要如此,使用vim、emacs学习成本高,而会打击积极性。在samba共享情况下,建议使用Notepad++、source insight进行代码编辑

    交叉编译:交叉编译是嵌入式一个很重要的概念。由于我们编译的程序是在开发板(开发板又称目标板)上运行的,但开发板又没有环境进行编译,所以带出“交叉编译”概念。即在一台linux主机系统上使用交叉编译器对代码进行编译,但编译得到的二进制文件无法在该主机运行,只能在开发板上运行。不同的板子使用的交叉编译器不同。一般使用商家自带的交叉编译器。

    下载手段:根据应用场合,可以用jtag烧录器下载程序(适用如u-boot开发)。可以使用tftp方式下载程序(适用kernel开发)。在开发板系统启动后且网络正常情况下,可以使用tftp下载、nfs拷贝等方式进行调试(适用于应用层程序开发)。

    另外对于USB转串口线、网络这类的东西,就不一一详细说明了。

     

    掌握程度:不同人使用的开发环境不尽相同。原则上只要是自己熟悉的环境就可以了,以提高开发效率为准则。

    推荐软件:vmware、notepad++、source insight、tftpd32(均为windows系统软件)。

    2、系统使用

    工欲善其事,必先利其器。系统环境使用熟悉程度越高,越能提高开发速度。举个例了,曾经遇到过别人在设备上调试应用程序,步骤是:编码、编译、制作软件包、用工具升级软件包到设备上,设备上电看效果。这一系列步骤中,制作包、升级软件包耗时很长,对于调试十分不利。如果使用NFS,时间能省至少三分之二。所以说,环境的熟悉是十分重要和必要的。

    本节主要针对Linux系统,对于入门者而言,Linux系统的使用是一个大坎。但要知道,嵌入式开发是离不开linux系统的,是必须学的。目前网络资料十分广泛,几乎遇到的问题都在找到答案,但质量往往良莠不齐,有些甚至会误导人。因此,建议一边学一边做笔记,把自己的疑问、心得、步骤都记录下来(比如,记录第1小节提到的nfs、samba服务安装的步骤)。

    如果时间允许,最好找书本来学习,边看书边敲命令。因为书籍介绍比较系统,有利于了解全貌,再逐个知识点深入,做到胸有成竹。下面列一下需要学习的知识点。

    1、掌握常用命令。必须要学的命令不多,像查看文件、拷贝文件、创建文件、查找文件、显示日期、查看/修改IP,等等。这些常用命令只要使用次数多了,就能熟练掌握。具体的自行搜索。

    2、掌握软件安装步骤。一般linux系统发行版自带有安装工具,如unbutu,在联网情况下直接输入命令apt-get install tool-name,就能安装了。

    3、编译源码方式安装软件。有些工具提供源码需要自己进行编译(比如要在开发板上运行的程序,则无法通过apt-get来安装,需要交叉编译)。linux编译一般有三个步骤:

    配置:./configure

    编译:make

    安装:make install。

    这个知识点自行百度。

    4、了解linux文件系统、目录结构、设备文件。如根目录名称是“/”,配置文件一般位于/etc目录,运行程序一般位于/bin、/sbin、/usr/bin、/usr/sbin,等等。因为嵌入式涉及到根文件系统概念,因而需要对linux目录结构有了解。如果感兴趣,可以去搜索一下LFS。

    5、学习IO重定向、管道概念,学习并会写简单shell脚本。

    6、学习编辑器vi的简单使用(因为有些情况下只有这个编辑器可用)、编译器gcc用法、Makefile知识、gdb调试。(此项针对开发而言)

    推荐资源:

    笔者的主页和博客有大量linux系统使用、软件编译、Makefile,等等文章,欢迎前来围观。

    学习建议:

    1、看书、网络搜索

    2、学会man命令(这是linux内置的帮助命令,比如要了解cp命令的用法,则输入man cp)

    3、记录笔记

    二、应用层

    1、C/C++语言

    C/C++语言本身与具体平台相关不大,但必须结合具体环境平台才能展现其作用。比如,MFC使用C/C++,QT也使用C/C++,Linux内核中使用C,单片机使用C,等等。环境不同,其侧重点不同。在学校里学习C/C++语法,考完试,却没有结合实际项目编程,就有人纠结学了C/C++不懂能做什么。只有真正在某一领域使用了C语言,它才是一个可以看得见、摸得着的东西,而不再是抽象的。

     

    这里结合Linux系统,列举出一些要掌握、学习的知识点。

    1、linux系统编程基本概念:Makefile、gcc、gdb。

    2、文件IO操作。

    3、进程控制、进程间通信、多线程操作

    4、信号处理

    5、网络编程

    6、串口编程

     

    另外也列举C/C++语言的学习点:

    1、标准库

    输入输出(fprintf、sscanf)、文件操作(fopen、fclose)、字符类操作(isalpha、islower)、字符串操作(strcpy、strcmp、memcpy)、信号处理(signal)、日期时间(mktime、ctime)

    2、C++ STL

    向量vector、队列queue、栈stack、列表list。

    推荐网站:http://www.cplusplus.com/reference/

     

    下面列出一些我认为较好的书籍。每种类型的书籍应用场合不同,按需求学习。——不仅嵌入式Linux领域,其它很多领域同时需要C,因而要提高C技能。

    入门篇:

    《Linux C 编程一站式学习》

    《Linux C从入门到精通》

    《Linux C编程从初学到精通 》

    《Linux C编程实战》

    《嵌入式linux应用开发完全手册》 (该书对嵌入式Linux开发整体都有讲述,一书以看窥全貌,入门适用)

    linux网络编程篇:

    《UNIX网络编程》

    《UNIX环境高级编程》

    C/C++提高篇:

     

    《C陷阱与缺陷》

    《C专家编程》

    《C和指》

    《C++沉思录》

    《C/C++深层探索》

    《Effective C++中文版》

    《提高c++性能的编程技术》

    《0 bug:C/C++商用工程之道》 (这本书网络有一定争论,笔者认为有部分的确有可取之处,请辩证看待)

     

    学习路线:

    环境:安装虚拟机linux,配置好samba,有windows下用notepad++编写代码,然后在命令行使用gcc编译并运行。像ubuntu安装必要开发工具sudo apt-get install build-essential 这类的知识点本文就不涉及了。

    实践:首先了解linux下gcc编译基本概念,然后逐个知识点学习。以上每点均是一个知识块,需要手动写代码。建议在github上建立仓库,形成自己的代码库,方便日后使用。

    2、版本控制

    版本控制可以提高开发效率,目前很多公司使用svn或git进行代码管理,很多开源项目——包括kernel,都使用git来管理。对于不涉密的代码,推荐使用github托管,而不便公开的代码,可以在bitbucket或csdn上托管。养成保存代码的习惯很重要。笔者很多年前没有代码托管意识,一次电脑被偷,导致很多代码消失了,如今想找也想不回来了。

    版本控制学习成本不大,无非创建仓库、提交代码这些过程,结合日常编码练习,慢慢熟悉掌握即可。

     

    笔者录制了一个git教程,欢迎观看:

    http://edu.csdn.net/course/detail/4562

    3、脚本

    Linux系统的脚本语言有很多,使用场合也不同,主要目的是提高开发效率。比如:在shell脚本中完成代码的编译并拷贝到nfs共享目录(或tftp服务目录)。这样只需要执行脚本就完成多项工作,节省很多时间。

    4、界面开发

    界面开发不是笔者强项,就写一写笔者的经历。笔者接触过的界面开发有QT、SDL、MFC。这些都是作为工具而存在的,不是专门研究,都是工作需要时再去学习,边学习边实践。

    比如,做一个视频采集的软件,使用了SDL进行显示。

    比如,为了显示YUV格式的文件,使用MFC编写一个播放器。

    5、其它书籍推荐

    内功修炼篇:

    《程序员的自我修养——链接、装载与库》(偏底层的人建议看看)

    《高效程序员的45个习惯 敏捷开发修炼之道》

    《高质量程序设计指南》(建议看看,工作中编写代码一定要注意编码规范,否则维护难度太大)

    《Linux开发工具箱:项目开发的最有效途径》(对应英文版本《The Linux Programmer's Toolbox》,网络有资源)

    (注:入门级别书籍不建议购买,通过网络资源或去图书馆借书等手段来学习就行了。当然经济条件允许的除外)

    笔者这几年也积累一定的文章,欢迎阅读:http://blog.csdn.net/subfate/article/category/752115

    三、底层

    这里说的底层包括三大方面,这三大方面缺一不可。

    bootloader:作为上电运行的第一个程序,负责最原始的初始化操作,初始化芯片、初始化内存、初始化IO复用,读取内核代码并将控制权移交到内核,从而完成使命。

    kernel:提供基本的运行环境,提供外设操作控制接口。

    rootfs:向用词(应用层)提供基本操作环境,包括命令行、程序库等。

    1、bootloader(启动装载程序)

    嵌入式Linux常见的bootloader是u-boot,而X86领域中一般称为BIOS。u-boot的学习没有捷径,最好是在有ARM开发板情况下进行研究,通过打印信息的方法跟踪其流程。但是,看懂u-boot代码需要电路基本知识、芯片手册知识等等。——这些知识,同样适用于内核驱动的开发。

    首先要建立的是整体概念和认识。建议先把厂商提供的u-boot源码编译通过,并下载到开发板上看到正常结果后,再用串口打印信息搜索代码,以了解u-boot的代码流程。然后再慢慢研究。如果bootloader不是学习重点,在有一定概念前提下就可以跳过到内核驱动层了,不过就笔者经验来看,bootloader和内核关系十分密切且部分代码是相通的。

    一般初始化的代码是汇编代码,对于入门者而言,初学阶段不用追究,等有一定基础后再回头研究也不晚。

    笔者许多年前移植过u-boot,写了几篇文章,版本旧了一些,但对于学习而言还有有好处的:

    http://blog.csdn.net/subfate/article/category/751064

    笔者曾经研究过x86的开源bios,写了几篇文章,大家可以看看。虽然对于u-boot学习帮助不大,但可以了解笔者如何从零开始学习一个未知的知识。地址:http://blog.csdn.net/column/details/15826.html

    2、kernel(内核)

    内核是比较大的一块,涉及内容十分多。作为入门者,与u-boot类似,首先要建立的整体概念。先把厂商提供的内核源码编译通过,并下载到开发板上,串口会打印很多启动信息,这些启动信息能帮助我们学习内核,自己也可以在内核中打印语句,以了解其流程。

    每一个平台芯片不同,外设不同,内核均不同,需要进行移植。所谓的“移植”,就是找到合适的驱动,修改适应到该平台的过程。比如,某平台使用2个LCD屏,一个是3.5寸的,另一个是4.3寸的,这需要对内核进行修改。比如,这个平台使用nand flash是1GB的,另一个平台使用的是512MB的,也需要修改内核。其它如EEPROM、电源芯片、网卡,等等,均如此。

    内核知识点分2部分,一是kernel本身的知识点,如内存管理机制(MMU)、时间管理、同步机制,等等。二是外设驱动,如LED灯、GPIO、按键。

    初学者建议学习:

    1、了解内核编译的过程:配置内核、编译uImage。

    2、了解platform驱动模型(笔者文章有现成的模板,已经应用于很多个平台上)。

    3、了解一般外设驱动模型。建议从简单的LED、GPIO入门。

     

    高阶知识点:

    1、学习各种子系统,如MTD、USB、IIC、SPI、RTC、WDT。

    2、学习内核知识,如延时队列、时间管理,同步机制,等等。

    以下是笔者笔记关于内核专题的目录:

     

    推荐资源:

    《Linux设备驱动程序》第三版

    《Linux设备驱动开发详解》

    笔者开了一个专栏讲内核的,欢迎阅读:http://blog.csdn.net/column/details/15829.htm

     

    3、rootfs(根文件系统)

     

    一般情况下,开发板厂商会提供根文件系统,如果没有,则可以自己编译制作。一般嵌入式Linux使用busybox制作文件系统必要的程序、库、配置文件。因为busybox编译出来的内容体积小,节省空间,所以很多ARM开发板上都是用busybox的。另外还涉及到文件系统格式,像Yaffs2、ramfs、ext4、UBI,等等。所有这些知识点,请自行搜索学习。

    掌握程度:

    1、知道系统启动过程涉及到哪些脚本。知道上电启动时如何添加自己程序启动。

    2、了解各目录功能、存储哪些文件(如改IP在哪个配置文件,动态库在哪些目录)。

    四、其他知识

    1、电路原理图、datasheet

    作为底层开发人员来说,能看懂硬件原理图和datasheet是必要的一项技能。

    看懂硬件原理图,就可以知道这个系统上有什么器件,哪些器件有什么功能,如何连接(使用什么协议),提供什么接口。有了这些认知后,才会对系统有一个全局整体的认识掌握。对于开发人员来说绝对是有利的。

    看懂datasheet,才能知道如何访问器件,如何操作器件,了解其时序。

    另外,对于嵌入式经常接触到的如I2C协议,SPI协议等等的协议也要掌握。

     

    掌握程度:不需要像硬件专业同学那样学习数电、模电课程。但起码掌握上升沿、下降沿的概念,知道高电平、低电平概念,懂得看I2C协议的时序图。懂得如何找到datasheet中关键信息(寄存器说明、时序图)。

    学习路线:碎片时间多的人,建议在遇到不懂知识点时上网搜索学习。有条件的建议借书或买来学习。

     

    2、英文

    作为开发人员,英文是无涯逾越的坎,因为datasheet还有开发手册,几乎都是英文的。英文资料的特点是长句子多,而技术性术语多。初看英文的资料,可能进展很慢,但只要坚持下去,就会发现,英文手册也就那些术语而已。遇到不懂的术语,就记录下来。积累多了,阅读就慢慢顺畅了。除了术语外,语法难度,远低于高考、四级水平。

    值得说的是,国外原版书籍或手册,用词往往通俗易懂,但翻译成中文后,有的术语不对,有的句子顺序不对。这加大了阅读难度,也是造成技术书籍难懂的原因之一。

    个人经历:在某次旅途火车上,用手机看了一遍ONVIF协议手册,多年后再回看,基本已掌握。但目前ONVIF中文资料还是少。看懂英文资料,无疑有很大帮助。

    某次工作遇到网络问题,中文搜索无果,去各大英文论坛看,无意发现pause frame,继而看ieee802.3标准手册找权威说明,最后解决。这里英文资料帮了很大忙。

     

    3、其它

    其实很有许多其它知识,无法一一列举。

    本文提及的众多知识点,但绝不是在炫耀水平——因为那是笔者工作被逼去了解掌握的。但总而言这,在认清自己专注核心技能外,多掌握一些技能,总归有好处的。

    五、入门路线

    这里以偏重嵌入式Linux(ARM)驱动开发为例,给出一条入门的路线。

    1、买一款使用广泛、资料多的ARM开发板。因为使用的人多,你遇到的问题别人可能早就遇到并解决了,这样能省很多时间,并且提高自信心。可以到某宝上看看板子。因为是学习使用,最好便宜又适用的。

    2、使用vmware安装一个ubuntu系统。在vmware软件中设置物理桥接方式上网。在ubuntu设置好samba服务、nfs服务、tftp服务。

    3、首先自己动手亲自编译u-boot、kernel,烧写到板子上(注:有可能rootfs不提供源码,而是提供img镜像文件)。

    4、自己修改kernel,并编译busybox,烧写到板子,在板子挂载NFS,在虚拟机交叉编译一个Helloworld程序,并在板子上运行。

    5、根据兴趣,开始捣鼓:u-boot、kernel、应用层开发、QT开发。

    5、选择自己重点关注方面,继续研究。

    这个路线不一定要严格遵守时间轴。

    六、补充

    以上这些项,因不同人的基础而异。像硬件专业的同学,数电、模电和电路图已经掌握,就要加强C和Linux系统的学习。反之,计算机软件专业的同学,就要去学习硬件知识。等等。

    对于书籍,有的可能一下子无法理解,那是因为功力不到。有的可能觉得没有用处,那是因为还没有涉及此方面。比如,非计算专业的人看《编译原理》,《操作系统原理》,《计算机体系结构》,肯定是看不懂的,而且初学者也不必要看。又比如,嵌入式有的领域使用到H264编码、MPEG编码,802.11、CDMA,如果不是进入有关行业的,也不必学习。另外网上很多人写的嵌入式入门文章提到0.11内核版本、2.4内核版本的书,还有离散数字、算法导论的书,并不是都适用所有人。 所以大家一定要量体裁衣,有多大胃口吃多少饭,有多大头戴多大帽,根据自己已有的知识和所处的阶段进行选择。

    另外要说明的是,很多知识点是密不可分的,且界线是很模糊的。比如应用层和底层。因为有时出现问题,并不知道具体哪里的问题,这就需要站在比较高的层面(系统视野)看问题,才会快速定位并解决问题。建议以某一方面为核心点,另一方面做了解掌握。如果有能力,最好都学。

    本文所列举的项目条款,根据个人实际情况学习。建议逐步学习,各个击破。理论上知识点学得越多,越有利于看问题深度、广度的提高。

    一般情况下,嵌入式Linux没有速成。但可以达到入门速成,根据个人能力,我认为大约半个月~2个月即可,不过入门后就要不断学习和积累了,——这个积累,需要精力、时间的投入。

    在后续的系列文章中,笔者将介绍嵌入式Linux入门的一些方法和步骤,当然,不会详细到每个命令,每个驱动,只是根据笔者经验来描述,因此,更多的是经验的分享。

    PS:

    本文提到的服务设置这类操作,自行搜索了解。

    本文提到硬件、协议这类知识,自行搜索了解。

    文中提到书籍的机构与笔者无利益关系,不构成购买理由,请自行把控。

    李迟 2017.6.1 周四 (在远方顺祝我家大锤节日快乐,礼物上周已经网购回去了)

     

    展开全文
  • 嵌入式linux,老手给新手的建议(转载)

    万次阅读 多人点赞 2012-06-16 16:45:31
    最近经常有用人单位给 我打来电话,问我这有没有嵌入式Linux方面的开发人员,他们说他们单位急需要懂得在嵌入式linux环境下的软件开发人员,我回答说,现在每年毕业的 大学生那么多,还招不到合适的软件开发人员吗?...

    嵌入式时代已经来临,你还在等什么?
     ---循序渐进学习嵌入式开发技术
    最近经常有用人单位给 我打来电话,问我这有没有嵌入式Linux方面的开发人员,他们说他们单位急需要懂得在嵌入式linux环境下的软件开发人员,我回答说,现在每年毕业的 大学生那么多,还招不到合适的软件开发人员吗?他跟我说,毕业大学生虽然多,但大部分都能力不够,不能达到他们的工作的要求。该公司HR的一句话说出来我 们现在的大学教学和大学生就业的现状:一方面每年那么多大学生毕业找不到合适的工作,另一方面很多用人单位和企业又找不到合适的人才。造成这种现象最基本 的原因是学校教育和社会需求的严重脱节。其他的专业和行业我不清楚,但是对于嵌入式专业和嵌入式软件行业来说,通过与多所高校的老师和在校高年级本科生, 研究生交流,我还是有所了解的,高校的嵌入式专业的教学现状我在前一篇文章里仔细分析过,造成很多嵌入式专业的学生在毕业后,还是很难达到用人单位的要求 最主要的原因在于高校在嵌入式教学方面重理论和轻实践,很多嵌入式专业的老师也没有实际的工作经验,这样培养出的学生可能让他讲起来头头是道,但是让他去 真正编写,调试一个应用程序就傻眼了,不知道从何下手,因为他们在学校的学习可能从来就没有老师带着他们实际调试过嵌入式程序,也没有机会让你去调试嵌入 式应用程序,那些看起来非常不错的嵌入式实验箱大部分时间都躺在实验室睡大觉,只有在上实验课的时候搬出来让大家看2眼,摸2下,还没有弄明白怎么回事, 又要收到实验室睡大觉去了。这样的教学模式,如何能培养出一名合格的嵌入式工程师呢?出现企业找不到合适的人,大学毕业生找不到合适的工作也就不奇怪了。
    嵌入式专业是一门实践性非常强的学科,只有多动手,多实践,多编程,多调试,多看书,多思考才能真正掌握好嵌入式开发技术。
    现 在很多同学也意识到了学校培养模式和社会需求脱节问题,有一部分同学也先行行动起来,开始注重培养自己的实际动手能力,培养自己实际分析问题,解决问题的 问题,培养自己在嵌入式专业实际编程,和调试程序的能力。但是嵌入式专业不同于其他学科,嵌入式专业是一门综合性非常强,涉及知识面非常广的学科,对于初 学者来说,面对那么多教程,课本,那么多知识点,往往不知道从何处下手,不知道哪些是重点,哪些不是重点,这些知识点之间有什么关联,一脸的茫然,然后东 一榔头,西一棒子,折腾了几个月甚至大半年后,还是找不着学习嵌入式的方向,还徘徊在嵌入式开发的大门之外。
    那么,如何从零开始学习嵌入式开发技术, 进入嵌入式开发大门呢,笔者根据自己的嵌入式学习经历和多年的嵌入式linux教学经验,谈谈自己对嵌入式学习的一些想法和意见,希望对大家有所帮助。

    一、练好基本功
    嵌入式系统专业是综合了计算机硬件技术,计算机软件技术以及电子电路技术的一门综合学科,所涉及的内涵和知识非常广泛,包括:数字电路,模拟电路,计算机组成原理,单片机基础,C语言基础,操作系统,数据结构,编译原理,计算机控制,计算机网络等知识。
    在真正学习嵌入式开发之前,u。对于C语言,至少能单独编写调试一个3 ~ 500行的程序,能够了解C语言的基本语法规则,基本语句的使用,理解指针概念并能灵活使用各种指针。
    计算机组成原理要能理解组成一个计算机系统的几大部件,计算机系统的结构,理解系统总线,理解处理器和计算机外部设备的关系,处理器和计算机外设是如何协调工作完成某一项功能的,计算机软件和硬件是如何分工协作完成某一项任务的,理解软件是通过寄存器来控制硬件的。
    数字电路,模拟电路要了解其基本原理个概念,能看懂简单模拟、数字电路原理图。理解数字电路中的寄存器,时序的概念,能看懂芯片手册和时序图。对于其他基础课程,重点要理解其中的一些基本概念,如何使用等等。
    对 于电子,自动化,通信,计算机类专业的学生,在大二、大三开设的专业基础或专业课程中基本包含了以上的大部分课程。因为缺乏实践,可能学得不是很深入,但 是一些基本的概念和基本知识应该还是有所了解,针对一些薄弱环节,自己稍微加强学习一下,基本上已经具备了学习嵌入式开发的基础。在嵌入式基本功学习阶 段,最重要的是C语言和单片机基础,最好是能用C语言开发一个小的单片机程序,例如用C语言实现单片机和PC的串口通信,用C语言控制LED等显示,用C 语言控制数码管显示等小程序。在这个期间需要的学习工具就是单片机51学习开发板。推荐飞凌的OK-51学习开发板。详情参考:

    二、嵌入式Linux应用开发
    嵌 入式开发基础知识学习完后,这时候你已经有了一定的嵌入式开发基础了,可以进行基于单片机的嵌入式系统设计了。单片机编程本身也是属于嵌入式编程,但是在 这里我们只是把单片机开发当作嵌入式系统开发的基础,不把单片机开发作为真正的嵌入式系统开发,在这里我们的嵌入式系统开发是指在带有操作系统的嵌入式平 台上的应用和驱动开发,特别指在嵌入式linux平台上的开发。
    单片机开发在很早以前是非常热门的,现在在一些比较简单的系统上单片机也用的非常 广泛,随着硬件的成本不断降低,在一些比较复杂的嵌入式设备一般都采用嵌入式linux操作系统,在嵌入式linux平台上进行开发,这样可以极大的提高 嵌入式开发效率,提高系统的稳定性和可靠性,降低开发成本。由于linux是一个开源的操作系统,你可以通过阅读linux内核来理解内核的实现机制,如 果有需要,你甚至可以通过修改内核源码来提高系统的性能;同时,全球参与linux开发的队伍非常庞大,网上有大量的嵌入式linux开发资料和源代码, 很多你需要实现的功能在网上基本都能找到相关源码,参考一下别人写的源码,这样可以极大的提高自己的工作效率和技术能力,近几年,随着参与linux开发 的人越来越多,linux系统的稳定性、实时性有了很大的提高,linux系统无论在服务器上还是嵌入式设备平台上都应用越来越广泛,现在包括华为、中 兴、朗讯的各大通信巨头都开始把自己设备的底层平台从vxworks操作系统迁移到linux系统,可以说嵌入式linux是嵌入式技术发展一个方向,是 嵌入式技术的一面旗帜。基于以上原因,我的建议是学嵌入式开发,就学嵌入式linux开发,相对于wince等其他的嵌入式平台,你可以真正学到更多的东 西,学到嵌入式技术的精髓,同时他又符合嵌入式产业发展的方向,不容易被日新月异的技术发展所淘汰。
    有了嵌入式开发的基础,又知道了我们为什么要学习嵌入式linux开发,那我们就要开始动手开始学习了,那如何开始学习嵌入式linux开发,从哪里开始着手呢?
    很 多同学这时候就开始买linux书籍,从图书馆借了一大堆关于linux的书:什么《linux使用基础教程》、《linux源码深度分析》、 《linux情景分析等》、 《linux高级使用指南》等等。结果抱着这些图书看了10天半个月还是不知所云,当初学习的激情慢慢就消退了,最后不了了之,终究没有进入嵌入式开发大 门。究其原因,是因为没有找到合适学习嵌入式开发的方法,做任何事情都有方法可循,找对了学习方法往往就能事半功倍;否则就可能是事倍功半,甚至劳而无 功。接下来我先分析一下同学们的几种常见的嵌入式linux学习误区,然后提出一种比较合适的嵌入式linux学习方法。



    误区一、全身投入学习桌面或服务器版本linux系统
    很 多想学嵌入式linux 的同学经常问我,我不会linux系统,怎么学习嵌入式linux开发,于是他们就花费了大量的精力和时间去研究学习桌面版本linux系统的使用,什么 redhat 、federo,、ubuntu等等都用过,如何配置linux,linux的各种使用命令都背的滚瓜烂熟,linux各种服务器的配置,还原备份各种操 作非常熟悉,以为这样就学会了嵌入式linux开发。其实这是一个学习嵌入式Linux开发的误区。
    Linux桌面环境只是嵌入式linux的一 个开发工具,开发环境而已。我们的目标不是学习linux服务器的配置和使用,linux服务器的高级配置和使用那是另外一个领域,不属于嵌入式 linux讨论的范畴。我们进行嵌入式linux开发,只是把linux桌面环境当作一个工具,在linux桌面环境下运行嵌入式linux开发工具,例 如gcc 编译器,make工具来开发我们的嵌入式linux应用程序而已,对于嵌入式开发工程师来说,没有必要花费那么多的精力和时间去研究linux桌面版和服 务器的应用,只要能了解最基本的操作即可。现在的桌面linux系统的图形化界面做的也相当好,跟window具有相同的易用性能,例如ubuntu很多 操作都可以在图形界面下完成,就没有必要去记每个linux命令了。熟悉linux桌面系统的使用和基本操作命令,安排1~2天时间学习基本就可以掌握 了。

    误区二、直接阅读linux内核源代码
     很多想学linux,在连linux是什么东西,一点都还不会使用的情况下去就阅读linux内核源代码,花了大量时间去阅读《linux源码深度分 析》、《linux情景分析等》等书。这样的结果很可能就是看的头昏眼花,不知所云,最后只能放弃了。这也是同学们学习嵌入式linux的一个误区,在有 一定嵌入式linux开发基础后,带着一定的目的去阅读linux源代码,这样可以极大的提高你的技术能力,但是你在没有任何基础,对linux一点都不 了解的情况下就去阅读linux内核源代码,无异于以卵击石,最后只能是撞个头破血流。

    以上分析了同学们学习嵌入式linux 开发的2个误区,那么如何正确的嵌入式linux开发呢?

    u,学习嵌入式linux也一样。在u, 学习嵌入式linux开发比较适合的切入点是从嵌入式linux应用程序开发开始,即暂时先不去关心嵌入式硬件平台,不去关心linux的底层驱动,先把 精力集中在现有的嵌入式linux平台上进行嵌入式linux应用程序设计开发。学习嵌入式linux开发绝不是看看书就可以学好的,需要多实践,编程调 试;因为嵌入式开发不同于普通的基于PC机或服务器的应用程序开发,嵌入式开发的应用程序是要烧写到嵌入式板卡或开发板上运行的,所以首先你要给自己购买 一块开发板,现在普遍流行的嵌入式开发板都是基于u星的ARM9 CPU S3C2440,性价比极高,在这里我推荐使用飞凌公司FL-2440 高性价比ARM9学习开发板,开发板资源丰富,稳定,同时配有大量的实验源码,视频教程和实验指导书。
     有了开发板后 先后开始学习嵌入式linux开发环境搭建、嵌入式linux开发模型、linux内核移植和文件系统、嵌入式linux应用程序移植、嵌入式linux 多进程,多线程应用程序设计、嵌入式linux网络编程,如果对嵌入式数据库或图形软件开发有兴趣的,可以进一步学习嵌入式linux数据库开发或基于 QT的嵌入式linux图形应用软件设计。每学一章节都要通过相关实验来来验证你从书上学到的东西,同时提高自己编写代码,调试程序的能力。这个过程根据 不同学员的基础不同,大概要花上1 ~ 2个月时间。学完这些课程后,你就有了在现有的嵌入式linux平台上进行应用程序设计开发的能力,到一些嵌入式软件公司去,能够胜任在现有的嵌入式 linux平台上进行上层的应用程序开发工作。但是目前你还不能进行嵌入式linux系统和驱动的开发,也就是说,你现在只能在一个已经构建好的嵌入式 linux平台上进行应用程序开发,而自己还没有能力根据实际需要去重新构建一个嵌入式linux平台。要让自己有能力根据实际需要重新构建一个嵌入式 linux软硬件平台,这时候就需要进行下一阶段的学习了,即嵌入式linux系统和驱动开发。

    三、嵌入式Linux系统和驱动开发


    有 了嵌入式linux平台上开发应用程序的基础,你已经对linux的功能、linux对应用程序提供的接口和系统调用有了一定的了解,知道如何利用 linux提供的功能来进行应用程序开发,知道如何来使用设备驱动来进行应用程序设计,有了这些知识后,你就可以更深入的去学习Linux系统原理和基于 Linux驱动的开发,Linux内核的裁剪,文件系统构,bootloader等等底层的知识了。
    想要更深入学习嵌入式Linux系统和驱动开发,要学的内容非常多包括计算机软件、硬件、操作系统知识。这时候你可以参照以下的学习思路,u包括:ARM体系架构、S3C2440微处理器接口设计、时钟系统、LCD屏接口、存储控制器及系统的存储空间分配、NAND FLASH接口和NOR FLASH接口等。u。 学完这些知识点并通过相关实验验证后,嵌入式Linux系统和驱动的开发就算掌握了差不多了,能够胜任绝大部分基于linux平台的驱动开发工作了。学完 这些知识点,根据学员的不同情况,一般需要花三个月到半年时间。通过这一阶段的学习,你在嵌入式Linux开发领域已经算是有了一定的功底,已经不再被人 称为菜鸟了,已经进入嵌入式linux开发高手行列了。

    四、更上一层楼
     深入理解了嵌入式内核和驱动开发,这时候写个什么驱动对你已经没有什么问题了,开发过程中一些基本问题都难不倒你了。这是你可能想优化一下系统的性能,比 如实时性,提高系统的启动速度,或者优化系统的内存管理机制,要达到修改内核核心机制的境界,你就需要去深入去研读linux内核源码了,参考 《linux源码深度分析》、《linux情景分析等》等linux源码分析的书籍,深入理解linux各部分的实现机制和原理,以及可能存在的问题。你 只有在深入理解现有代码和实现机制的基础上,才能提出更好的改进方案。如果你能达到这个境界,那你已经是高手中的高手,可以笑傲群雄了。

    以 上是笔者结合自己的嵌入式学习经历和嵌入式培训经验总结的一些嵌入式学习方法和步骤,这只是笔者对嵌入式学习的一些看法,希望对那些有兴趣学习嵌入式 linux又不知道从哪开始学的同学们有所帮助。当然,每个人,每个同学的基础,各方面的情况都不一样,每个人都有自己适合的学习方式,本文章总结的一些 学习方法和思路仅供参考,希望大家能找到适合自己的学习嵌入式开发的方式,早日进入嵌入式开发大门。
    万丈高楼平地起,心动不如行动,有志从事嵌入式开发的同学不要再犹豫了,赶紧拿出实际行动,好好学习,为实现自己的伟大梦想而努力奋斗吧

    展开全文
  • 【嵌入式】基于ARM的嵌入式Linux开发总结

    千次阅读 多人点赞 2019-06-14 20:04:39
    前言嵌入式知识点复习一嵌入式知识点复习二 --体系结构嵌入式知识点复习三 --ARM-LINUX嵌入式开发环境嵌入式知识点复习四 --arm-linux文件编程嵌入式知识点复习五 --arm-linux进程编程嵌入式知识点复习六 --arm-...

    嵌入式知识点复习一

    1、 嵌入式系统的一般组成结构

    在这里插入图片描述

    2、嵌入式硬件系统的结构
    (1)嵌入式处理器+外围硬件
    (2)常见的外围硬件:电源、时钟、内存、I/O、通信、调试;
    3、嵌入式处理器
    (1)ARM、S3C6410、STM32单片机、华为海思、高通骁龙等
    (2)Intel /AMD 都不是嵌入式处理器
    4、嵌入式操作系统
    功能:
    种类:嵌入式linux;WinCE;Vxworks;μC/OS-II;Android;IOS。注意:linux不是嵌入式操作系统;MAC OS WINDOWS XP/7/8/10都不是

    嵌入式知识点复习二 --体系结构

    1、ARM:ADVANCED RISC MACHINES,是一款嵌入式微控制器,也是一家嵌入式处理器设计厂商。设计高性能、低功耗的嵌入式处理器。
    2、ARM微处理器工作状态:两种指令对应两种状态(通常情况)
    (1)Thumb状态、ARM状态;
    (2)32位定长ARM指令,16位定长Thumb指令。
    (3)ARM1176支持ARM指令、Thumb指令、Jazelle指令,故有三种状态:ARM状态、Thumb状态、Jazelle状态。
    3、异常:
    (1)处理器执行某些区别于用户指令的任务,如中断处理、复位、调试等;为了区分用户指令,因此称为异常;
    (2)异常的种类与类型(1176为例):7种,中断(IRQ)、快中断(FIQ)、未定义(Undef)、数据中止(DABT)、预取指中止(PABT)、软中断、复位(reset)
    4、工作模式:根据系统执行正常或异常指令不同,分为8种工作模式:用户模式、系统模式、中断模式、快中断模式、未定义模式、中止模式(对应数据中止异常、预取指中止)、SVC管理模式(软中断、复位)、SM安全监视器模式。
    5、寄存器:
    (1)ARM处理器均为32位寄存器;
    (2)ARM1176寄存器数量:40个
    (3)ARM1176寄存器包括:未分组寄存器、分组寄存器、CPSR、SPSR;
    (4)未分组寄存器(所有模式通用):9个,R0~R7;R15(PC)
    (5)分组寄存器(不同工作模式下专用,不同模式稍有不同):
    ① R8~R14;
    ② 6个不同模式下的SPSR寄存器:SPSR_irq,SPSR_fiq,SPSR_abt,
    SPSR_und,SPSR_svc,SPSR_mon
    (6)可复用寄存器:
    ① SP堆栈指针寄存器-R13,用于保存子程序调用或异常处理的临时数据;
    ② LR连接寄存器-R14,用于保存子程序调用或异常处理时,主程序调用指令/中断跳转指令的下一条指令的入口地址,以便于恢复主程序;
    ③ PC程序计数器-P15,用于保存要执行的指令的地址。
    (7)PSR程序状态寄存器:
    ① 包括CPSR当前程序状态寄存器和SPSR备份的程序状态寄存器;
    ② CPSP用于保存当前模式下处理器模式、状态、中断使能、大小端模式及条件位等信息;
    ③ SPSR用于备份异常发生前的CPSR寄存器的值,以便异常处理结束时能返回用户程序状态。
    6、ARM支持两种中断:IRQ和FIQ
    7、ARM数据存储格式:大端(big endian)和小端(little endian)
    8、采用RISC架构的ARM微处理器一般具有如下特点:
     
    ① 体积小、低功耗、低成本、高性能;
    ② 支持Thumb(16位)/ARM(32位)双指令集,能很好地兼容8位/16位器件;
    ③ 大量使用寄存器,指令执行速度更快;
    ④ 大多数数据操作都在寄存器中完成;
    ⑤ 寻址方式灵活简单,执行效率高;
    ⑥ 指令长度固定;
    ⑦ 指令支持按 条件执行;
    ⑧ 内存访问采用load/store实现。

    嵌入式知识点复习三 --ARM-LINUX嵌入式开发环境

    一、交叉开发模式
    1、组成结构
    (1)宿主机:开发主机,一般由PC、发行版linux系统、开发工具(本地及交叉编译)(代码编辑器Vi,编译器GCC、调试器GDB、工程管理器MAKE、NFS等)组成;
    (2)目标机:嵌入式系统,一般由ARM硬件、BOOTLOADER、内核、根文件系统构成;
    (3)连接工具:串口线、网线、USB线等。
    2、理解编译工具链与交叉编译工具链的异同
    (1)相同点:
    ① 用于支持的语言的编译、链接与调试,编译器用法相同;
    ② 通常都有编译器、链接器、调试器、库及其他二进制工具构成。
    (2)不同点:
    ① 编译工具链一般用于本机编译、本机执行的开发模式;
    ② 交叉编译工具链用于宿主机编译,目标机运行的交叉开发模式;
    ③ 编译器一般Linux发行版都配备,直接调用gcc命令即可;
    ④ 交叉编译器一般需根据宿主机软硬件环境,进行gcc、相关库、工具进行有针对性的定制。
    ⑤ 实验室使用的OK6410开发板定制的编译器为32位的,其交叉编译工具链主要arm-linux-gcc,arm-linux-g++arm-linux-gdb等构成。
    二、开发工具的用法
    1、Vi的工作模式及其切换-掌握使用Vi完成源代码编辑、保存及退出的常见按键操作;
    2、GCC:GNU Compiler Collection,GUN编译器套件,特点:
    ① 支持绝大多数高级语言的编译,既支持传统的C/C++,Fortan,Objective-C ,也支持java,python,go等语言;
    ② 支持汇编语言;
    ③ 支持绝大多数的主流处理器平台;
    ④ 便于构建交叉编译工具链。
    3、gcc/arm-linux-gcc用法:
    ① 基本用法:gcc hello.c;arm-linux-gcc hello.c;输出a.out
    ② 推荐用法:gcc hello.c -o hello/arm-linux-gcc hello.c -o hello ,可以指定输出文件名称;
    ③ 主要的编译参数
    -Wall 打印全部警告信息;
    -O{0-3,s} 支持代码优化,0无优化;
    -g 支持gdb调试;
    -lpthread 支持多线程。

    4、make及Makefile
    (1)make:工程管理器,利用执行Makefile文件实现工程管理(编译、链接、生成工程镜像、安装、清理、卸载等);
    (2)make用法:编写Makefile,在终端下执行make命令即可。
    (3)Makefile文件编写示例:
    一个工程,2个源文件testa.c ,testb.c,一个头文件testb.h,编译器为arm-linux-gcc,生成的可执行文件为test,需支持代码优化、打印警告信息,支持gdb调试等编译选项,其Makefile文件如下:
    SRC=testa.testb b.c testb.h
    EXEC=test
    CC=arm-linux-gcc
    CFLAGS=-Wall -O2 -g
    (EXEC):(EXEC):(SRC)
    $(CC) $(SRC) -o $(EXEC) $(CFLAGS)

    嵌入式知识点复习四 --arm-linux文件编程

    1、linux文件编程概述
    (1)文件描述符:Linux中文件分为4种:普通文件、目录文件、链接文件、设备文件要区分这些文件就要了解“文件描述符”;
    文件描述符是一个非负的整数,他是一个索引值,并指向内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符,当需要读/写文件时,也需要把文件描述符作为参数传递给相应的函数。
    (2)基本I/O操作
    Linux的输入/输出(I/O)操作,通常为5个方面:打开,读取,写入,和关闭
    对应的有5个系统调用:
    open,read,write,close,lseek
    所需要的头文件:
    #include <sys/types.h>
    #include <unistd.h>
    1.open函数
    open函数的原型如下:
    int open(const char *pathname, int flags, mode_t mode)
    函数传入参数含义如下:
    pathname:为字符串,表示被打开的文件名称,可以包含路径。
    flags :为一个或多个标志,表示文件的打开方式,常用标志如表所示:
    O_RDONLY 只读方式打开
    O_WRONLY 只写方式打开
    O_RDWR  读/写方式打开
    O_CREAT 如果文件不存在,就创建新的文件
    O_EXCL 如果使用O_CREAT时文件存在,则可返回错误消息
    O_TRUNC  如果文件已存在,且以只读或只写成功打开,则先全部删除文件中原有的数据
    O_APPEND  以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾、
    注意:在open函数中,flags参数可以用过“|”组合而成,O_RDONLY,O_WRONLY,O_RDWR这三种方式是互斥的,不可同时使用,因此这3个参数只能出现一个。

    mode 被打开文件的存取权限模式,可以使用八进制数来表示新文件的权限,也可以采用<sys/stat.h>中定义的符号常量,当打开已有文件时,将忽略这个参数,函数返回值:成功则返回文件描述符,出错返回-1。

    文件模式符号常量:
    S_IRWXU   00700    所属用户读。写和执行权限
    S_IRUSR   00400   所属用户读权限
    S_IWUSR   00200   所属用户写权限
    S_IXUSR   00100   所属用户执行权限

    S_IRWXG  00070   组用户读,写和执行权限
    S_IRGRP   00040   组用户读权限 
    S_IWGRP   00020  组用户写权限
    S_IXGRP   00010  组用户执行权限

    S_IRWXO  00007  其他用户读,写和执行权限
    S_IROTH  00004  其他用户读权限
    S_IWOTH  00002  其他用户写权限
    S_IXOTH  00001  其他用户执行权限
    2.read和write函数
    函数原型如下:
    ssize_t read(int fd, void *buf,size_t count)
    ssize_t write(int fd,const void *buf, size_t count)
    函数传入参数含义如下:
    fd 文件描述符
    buf 指定存储器独处数据的缓冲区
    count 指定读出或写入的字节数
    3.close函数
    当使用完文件时可以使用close关闭文件,close会让缓冲区中的数据写回磁盘,并释放文件所占的资源,close的原型如下:
    int close(int fd)
    函数传入参数:fd文件描述符
    函数返回值:若文件顺利关闭则返回0,发生错误则返回-1,并置errno,通常文件在关闭时出错是不常见的,但也不是不可能的情况,他别是在关闭通过网络访问的文件时就会出现这种情况。
    4.lseek函数
    主要用于移动文件读写指针,主要用于获取文件大小和拓展文件(先分配空间、然后再填充内容),函数原型如下:
    off_t lseek(int fd, off_t offset, int whence)
    参数 fd:文件描述符。
    offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)
    whence
    (当前位置基点): SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小。
    SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。
    SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。
    返回值 成功:文件的当前位移
    -1:出错

    实例:(1)参考实验2:linux文件编程;
    (2)网盘:/linux编程源代码/IO(readwrite、fcntl)下相关代码

    嵌入式知识点复习五 --arm-linux进程编程

    一、Linux进程编程
    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配和调度的基本单位,是操作系统结构的基础。
    1 进程控制
    子进程创建:fork()函数
    在Linux中创建一个新进程的唯一方法是使用fork()函数。fork()函数是Linux中一个非常重要的函数,和以往遇到的函数有一些区别,因为fork()函数看起来执行一次却返回两个值。
    1)fork()函数说明
    fork()函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而原进程称为父进程。
    使用fork()函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程的上下文、代码段、进程堆栈、内存信息、打开的文件描述符、符号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独有的只有它的进程号、资源使用和计时器等。
    因为子进程几乎是父进程的完全复制,所以父子两进程会运行同一个程序。这就需要用一种方式来区分它们,并使它们照此运行,否则,这两个进程不可能做不同的事。
    实际上是在父进程中执行fork()函数时,父进程会复制一个子进程,而且父子进程的代码从fork()函数的返回开始分别在两个地址空间中同时运行,从而使两个进程分别获得所属fork()函数的返回值,其中在父进程中的返回值是子进程的进程号,而在子进程中返回0。因此,可以通过返回值来判断该进程的父进程还是子进程。
    2)fork()函数语法
    在这里插入图片描述
    进程等待函数
    1)wait()函数,无条件等待,父进程阻塞直到子进程结束
    在这里插入图片描述
    2)waitpid()函数,指定等待某个子进程结束以及等待的方式(阻塞或非阻塞)
    所需头文件 #include <sys/types.h>
    #include <sys/wait.h>
    函数原型 pid_t waitpid(pid_t pid, int *status, int options)
    函数参数 pid pid>0:只等待进程ID等于pid的子进程,不管已经有其他子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
    pid=-1:等待任何一个子进程退出,此时和wait作用一样。
    pid=0:等待其组ID等于调用进程的组ID的任一子进程。
    pid<-1:等待其组ID等于pid的绝对值的任一子进程。
    status 同wait
    options WNOHANG:若由pid指定的子进程并不立即可用,则waitpid不阻塞,此时返回值为0
    WUNTRACED:若某实现支持作业控制,则由pid指定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态。
    0:同wait,阻塞父进程,等待子进程退出。
    函数返回值 正常:结束的子进程的进程号
    使用选项WNOHANG且没有子进程结束时:0
    调用出错:-1
    所需头文件 #include <sys/types.h>
    #include <sys/wait.h>

    函数原型 pid_t waitpid(pid_t pid, int *status, int options)
    函数参数 pid pid>0:只等待进程ID等于pid的子进程,不管已经有其他子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
    pid=-1:等待任何一个子进程退出,此时和wait作用一样。
    pid=0:等待其组ID等于调用进程的组ID的任一子进程。
    pid<-1:等待其组ID等于pid的绝对值的任一子进程。
    status 同wait
    options WNOHANG:若由pid指定的子进程并不立即可用,则waitpid不阻塞,此时返回值为0
    WUNTRACED:若某实现支持作业控制,则由pid指定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态。
    0:同wait,阻塞父进程,等待子进程退出。
    函数返回值 正常:结束的子进程的进程号
    使用选项WNOHANG且没有子进程结束时:0
    调用出错:-1

    进程结束:exit()和_exit()

    所需头文件 exit:#include <stdlib.h>
    _exit:#include <unistd.h>
    函数原型 exit:void exit(int status);
    _exit:void _exit(int status);
    函数传入值 status是一个整型的参数,可以利用这个参数传递进程结束时的状态。
    通常0表示正常结束;其他的数值表示出现了错误,进程非正常结束。
    在实际编程时,可以用wait系统调用接收子进程的返回值,进行相应的
    处理。

    所需头文件 exit:#include <stdlib.h>
    _exit:#include <unistd.h>
    函数原型 exit:void exit(int status);
    _exit:void _exit(int status);
    函数传入值 status是一个整型的参数,可以利用这个参数传递进程结束时的状态。
    通常0表示正常结束;其他的数值表示出现了错误,进程非正常结束。
    在实际编程时,可以用wait系统调用接收子进程的返回值,进行相应的
    处理。

    两者的区别:
    (1)_exit()函数的作用最为简单:直接使进程终止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;
    (2)exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。
    (3)exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是"清理I/O缓冲"。
    Linux下的进程间通信
    进程间通信用于实现参数传递及通信功能;Linux支持的常用的进程间通信方法:管道、消息队列、共享内存、信号量、套接口等等。
    实例:(1)实验三:Linux进程编程;
    (2)网盘linux编程源代码目录下fork文件下相关实例(FIFO、msgque、shm)。

    嵌入式知识点复习六 --arm-linux网络编程

    1、程序流程
    (1)网络通信程序架构-客户端/服务器架构
    (2)流程如下图:
    在这里插入图片描述
    TCP通信

    2、函数说明
    socket()
    Sockfd=socket(AF_INET,SOCK_STREAM,0);

    Bind()
    s_add.sin_family=AF_INET;IPV4协议
    s_add.sin_addr.s_addr=inet_addr(“192.168.1.123”);IP地址192.168.1.123
    s_add.sin_port=htons(0x8888);端口号是8888

    if(-1 == bind(Sockfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))

    listen()服务器端侦听函数
    listen(Sockfd,5)服务器侦听来自客户端的请求
    accept()服务器端接受客户端连接请求
    nfp = accept(Sockfd, (struct sockaddr *)(&c_add), sizeof(struct sockaddr);

    send()数据发送函数
    send(nfp,“hello,welcome to my server”,32,0)
    recv()数据接收函数
    recv(nfp,buffer,1024,0)
    关闭连接
    Close(nfp)
    关闭服务器
    Close(Sockfd)
    实例:(1)实验四:网络聊天室设计
    (2)网盘/linux编程源代码/socket下相关代码

    嵌入式知识点复习七 --linux字符型设备驱动初步

    一、Linux字符设备驱动初步
    1、Linux设备类型
    (1)字符设备:只能一个字节一个字节的读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序进行。字符设备是面向流的设备,常见的字符设备如鼠标、键盘、串口、控制台、LED等。
    (2)块设备:是指可以从设备的任意位置读取一定长度的数据设备。块设备如硬盘、磁盘、U盘和SD卡等存储设备。
    (3)网络设备:网络设备比较特殊,不在是对文件进行操作,而是由专门的网络接口来实现。应用程序不能直接访问网络设备驱动程序。在/dev目录下也没有文件来表示网络设备。

    2、开发流程

    3、关键函数讲解(以2.6以下版本内核为例)
    (1)驱动模块注册register_chrdev()函数
    原型:register_chrdev(unsigned int major, const char *name,const struct file_operations *fops);
    major:主设备号,该值为 0 时,自动运行分配。而实际值不是 0 ;
    name:设备名称;
    fops:操作函数,实现驱动定义的open、read、write、close等内核函数与应用程序调用的open、read、write、close间的映射;
    返回值:
    major 值为 0 ,正常注册后,返回分配的主设备号。如果分配失败,返回 EBUSY 的负值 ( -EBUSY ) 。major 值若大于 linux/major.h (2.4内核)中声明的最大值 (#define MAX_CHRDEV 255) ,则返回EINVAL 的负值 (-EINVAL) 。指定 major 值后,若有注册的设备,返回 EBUSY 的负值 (-EBUSY)。若正常注册,则返回 0 值
    (2)驱动注销unregister_chrdev()函数
    原型:
    #include <linux.fs.h>
    int unregister_chrdev (unsigned int major, const char *name)
    变量:
    major 主设备号
    name 设备文件
    返回值:
    major 值若大于 linux/major.h (2.4 内核)中声明的最大值 (#define MAX_CHRDEV 255),返回 EINVAL的负值 (-EINVAL)。指定了 major的值后,若将要注销的 major 值并不是注册的设备驱动程序,返回 EINVAL的负值 ( -EINVAL )。正常注销则返回 0值。
    (3)File_operation结构体
    file_operations结构是建立驱动程序和设备编号的连接,内部是一组函数指针,每个打开的文件,也就是file结构,和一组函数关联,这些操作主要用来实现系统调用的
    struct file_operations {
      struct module *owner;//拥有该结构的模块的指针,一般为THIS_MODULES
    loff_t (*llseek) (struct file *, loff_t, int);//用来修改文件当前的读写位置
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);//从设备中同步读取数据
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);//向设备发送数据
    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一个异步的读取操作
    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一个异步的写入操作
      int (*readdir) (struct file *, void *, filldir_t);//仅用于读取目录,对于设备文件,该字段为NULL
    unsigned int (*poll) (struct file *, struct poll_table_struct *); //轮询函数,判断目前是否可以进行非阻塞的读写或写入
      int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); //执行设备I/O控制命令
      long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); //不使用BLK文件系统,将使用此种函数指针代替ioctl
      long (*compat_ioctl) (struct file *, unsigned int, unsigned long); //在64位系统上,32位的ioctl调用将使用此函数指针代替
      int (*mmap) (struct file *, struct vm_area_struct *); //用于请求将设备内存映射到进程地址空间
      int (*open) (struct inode *, struct file *); //打开
      int (*flush) (struct file *, fl_owner_t id);
      int (*release) (struct inode *, struct file *); //关闭
      int (*fsync) (struct file *, struct dentry *, int datasync); //刷新待处理的数据
      int (*aio_fsync) (struct kiocb *, int datasync); //异步刷新待处理的数据
      int (*fasync) (int, struct file *, int); //通知设备FASYNC标志发生变化
      int (*lock) (struct file *, int, struct file_lock *);
      ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
      unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
      int (*check_flags)(int);
      int (*flock) (struct file *, int, struct file_lock *);
      ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
      ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
      int (*setlease)(struct file *, long, struct file_lock **);
    };
    实例:见网盘/linux编程源代码/ok6410ledrv

    展开全文
  • 嵌入式Linux驱动开发

    2019-05-13 10:27:28
    说到Linux驱动,尤其是嵌入式Linux驱动,大家可能会望而却步,因为入门太难!很多书上或课程基本是这样的:一上来给我们展示一大堆高深莫测的代码,感觉是C语言,又感觉不是C语言。说它是C语言,这里能找到一些C的...
  • 嵌入式Linux——学习经历

    万次阅读 多人点赞 2018-10-31 10:43:31
     本文主要介绍我学习嵌入式的经历。并结合自身的经验希望可以对大家有所帮助。 视频及教材:  郭天祥相关视频及教材,天狼星相关视频及教材,野火迷你相关视频及教材以及韦东山100ask官网所介绍的视频及教材 ...

    简介:

            本文主要介绍我学习嵌入式的经历。并结合自身的经验希望可以对大家有所帮助。

    视频及教材:

            郭天祥相关视频及教材,天狼星相关视频及教材,野火迷你相关视频及教材以及韦东山100ask官网所介绍的视频及教材

    个人简介:

            我的本科学校是一个很普通的二本,研究生也是二本。我找的是一个规模中等的公司(我个人对这份工作还是比较满意的)。而我所面试的公司也是做嵌入式Linux相关的产品。好了我的基本情况就介绍到这里了。而详细的情况我会在下面说明。

    我的大学——忙碌而充实:

            因为我所做的与单片机相关的项目都在大学时,而在研究生期间我主要研究的是量子相关的课题,所以这里我重点介绍我的大学。

            我的大学是一个很普通的二本。有时候大家可以会觉得他是一个专科,因为他是以学院命名的。而对于刚进大学的我嵌入式是一个我从来没有接触过的概念,更没有想到我的后半生都会与嵌入式相关。那时的我并没有明确的目标,只是想着要好好学习老师课上所讲的内容,而那时也是我最天真的时候。那时我所做的很多事都是因为其他人也在做,而没有真正去了解我真正想要的是什么,更没有认真的想过我的大学应该怎么过。

            这样的日子维持了一年,在这一年中我虽然也很忙碌但是回想自己走过的路,却发现并没有留下任何的痕迹。而真正出现转机是在我大二国庆节期间,那时候的我无所事事,但好的一点是我有几个要好的朋友。我们在一起聊天的时候他们聊到了自己所焊接的电路板,自己所搭建的电路,以及自己所设计的功能模块。这些都是我以前所没有接触过的。那一时刻,我突然意识到虽然我完全听不懂他们在说什么,但是感觉可以自己设计电路来实现某种特殊的功能对我来说似乎很有吸引力。所以那时候我决定要加入这个组织——第二课堂。

            不得不说第二课堂开启了我对这个世界新的认识,同时也感谢第二课堂为我提供了那么好的平台来学习各种嵌入式相关的知识。现在想想在第二课堂的两年我都觉得收获满满。我刚进第二课堂时还没有学习单片机,而是利用各种电子元器件和简单的芯片来实现一些简单的功能电路。而我们使用最多的就是NE555芯片了。虽然现在已经忘了这些芯片的功能,但是那段时间的练习却真正的让我学到了很多模电数电方面的知识,以及对各种芯片引脚和各种电子元器件的识别。这段时间一定要感谢我的好朋友礼标和吴老板。

            我接触的第一个单片机是stc89c51,也就是大家常说的51单片机。而这个单片机让我了解到,原来我们可以通过一种编程语言来控制一个机器的电平变化。而不是我在以前焊接电路板时,只能使用简单的逻辑电路搭建简单的功能。在这里,他的功能得到了足够的扩展。而51单片机的两个重点:中断和定时器,这两样功能让我十分幸喜,因为我意识到我可以使用这两个功能来完成很多的设计了。而那时的液晶屏更是让我意识到我可以将自己想表达的意思或者监控的数据显示到我的机器上了。这是多么愉快的事情(那时总是因为一些简单的功能而幸喜,而现在回想当初的行为确实有些幼稚)。依然记得当时自己用液晶在屏幕上显示内容时的高兴。

            这个之后我还用51做了很多好玩的东西,例如LED矩阵:

            学完51单片机,我就开始学习ATmage16(AVR)单片机。这个单片机还是对寄存器进行操作的,不过相对于51来说AVR的速度确实快了很多,而且功能也更加的强大。例如在引脚的模式选择方面就比51多了好几个。而其他的中断以及AD等更是51所不能及的。因此我在那段时间用AVR做了很多好玩的东西。而这期间我用这个单片机做过一个小冰箱:

            这个冰箱在当时炎热的夏季,给我们带来了不少欢乐。而我使用到的就是一个单总线的温度传感器,其将温度测出并实时的在数码管上显示,而关于温度的控制部分,我本来打算用pwm来控制电源的开关以实现控制温度的目的,但是并没有完成这部分功能,而这部分的功能我用到了后面做智能风扇中。

            而做完冰箱我做了一些更有趣的项目——智能小车,这个智能小车有三个功能:循迹,避障和蓝牙遥控。我将这三部分功能融合到一起,通过手机蓝牙选择使用哪个功能。而这里的循迹和避障功能我使用网上的红外发送和接收模块通过检测红外线是否接收到来确定是否遇到黑线或者碰到东西,从而做出反应。而对于蓝牙遥控功能,我直接使用蓝牙模块通过串口连接以实现蓝牙数据传输。这里有一个循迹的图:

            做完小车之后我感觉自己对ATmage16芯片有了一定的了解,这时候我画了一个ATmage16最小系统的板子:

            确实只有自己画了板子,才对这个芯片有一个更深入的理解。同时也可以对外围部件以及各个部件的尺寸类型有更好的了解:

            而学还习AVR有一个让我骄傲的地方就是我写了一些AVR模块的库,这个库对我十分重要,我在使用AVR后期进行编程时主要就是对这些库中的源文件和头文件进行调用。当你学会使用现有的库时,你会发现其实库调用是多么的方便。

            学完AVR之后我就开始学习stm32,对我来说32就像是一个新的大陆,之所以这么说不仅仅是因为32在性能方面远超51和AVR,而是因为32的编程方式是调用库进行编程的。在学习32之前我一直是针对寄存器进行编程(当然32也可以针对寄存器进行编程)。而寄存器编程的特定就是你要很好的了解你所编程的单片机,也就是说你要对单片机的各个引脚及接口功能都要十分的熟悉。而对于32单片机来说就相对简单,比较适合对硬件不是很熟悉的人。也就是说就算你对寄存器的操作方式不是很熟悉也可以对32单片机进行编程。因为32单片机是一个可以调用库进行编程的。由于32单片机的很多功能都已经被前辈写好,并将其封装成库。而我们只需要调用某种功能在库中的API接口就可以了。因此使用32单片机对我们来说是一个质的飞跃。同时也让我们了解了对库中API接口调用的重要性。这将帮助我以后学习嵌入式Linux打下基础。

            我用32做的是我的毕业设计,对于我所完成的功能,我使用自己当初毕业论文的简介:

            在没有家人在场的情况下,当老人不小心摔倒而且没有能力进行自救时或者老人遇到其他的突发危险而现场没有家人帮助时,如果没有及时得到救治或者帮助,这很可能会导致老人瘫痪甚至威胁老人的生命安全。在这种情况下,我们采用集三轴加速度和三轴陀螺仪于一体的MPU6050模块对老人是否跌倒进行监测。当老人跌倒时,以STM32为核心的中央控制系统将会向周围人发出发出声光警报。如果老人有能力自己站起来,可以自行解除警报。当老人没有能力自己站起来时,装置将在警报响起10 S后通过GSM模块将从GPS模块获得的经纬度信息以短信形式发送到指定联系人。该指定联系人可以通过智能手机搜索得出老人的地址。而且本装置还有一键SOS功能,当老人碰到其他危险且没有能力自救时,可以通过按下SOS按键直接将自己的地理信息通过短信形式发送给指定联系人。

            而作品的实物图为:

            好了,做完上面的设计,我的大学也就画上了完美的句号。在此我要感谢几个人,是他们在我做嵌入式的路上指导和帮助我,并为我提供各种便利。首先要感谢的是第二课堂的汪老师,可以说第二课堂的学生能有今天的成就在很大程度上要感谢汪老师,是汪老师为我们提供第二课堂的教室,并在学习的路上指导我们。而第二个要感谢的就是我的同学,吴老板和礼标,是他们在我当初学习嵌入式时不断指引我,并帮助我学习了很多的知识。而第三个要感谢的是我的师兄:林耕风。他对我以后在嵌入式方向上的提高给了很多好的建议。同时他也是一个热爱着技术,并对生活充满激情的人。他是我很敬佩也很向往的人。好了,接下来要开启的是我的研究生生涯了。

    我的研究生——迷茫中前行:

          我在研究生期间主要的课题是量子通信,而与嵌入式的关系并不是很大。而对于嵌入式的很多知识我是自学的,这里就要感谢韦东山老师的视频以及开发板,韦东山老大的开发板和视频很详细的为我们讲解了Linux在2440开发板上的运行、移植以及驱动的编写。这里还要感谢我表哥和我的同学吴老板,是他们在我当初迷茫的时候为我指引方向。

          如果用一个词来形容我的大学,我会用充实来形容,因为在大学期间我的目标明确,同时也会很有效的将自己的时间用到学习中。而对于我的研究生,我想跟多的是迷茫。初入研究生学校对很多新鲜的事物充满好奇,那时的我以为自己还可以像大学时一样有一个实验室,然后自己在其中做一些喜欢的项目。但是真实的研究生生活并不是我想象的那样,我的导师的研究课题是量子方向,因此我要学习量子的知识,而这方面知识的学习对我来说压力很大。因为在大学时我更多的时间是在实验室度过的。所以我的理论知识并不好,尤其是物理(但真正的学习下来,自己还是收获颇丰,同时也为自己在一个新的领域开启了一扇门,而相对于其他的来说,更重要的是我在这段时间证明了自己的学习能力,我发现如果你用心去学一门知识,其实也并不是那么的困难)。同时我发现我的实验室并不是我想象的实验室,我的实验室里没有示波器,没有可控电源。那时候的我十分失落,虽然比较失望但是我并没有就此放弃。在思考了一段时候之后我觉得学习Java,因为Java在那时比较火,同时也不需要任何的硬件,只要你有电脑就好了。因此我开启了Java的学习之路。现在想想那时候学的东西,似乎都已经忘记,但是那时候对于生活的态度还是很好的。我虽然不能改变我导师的方向,那么我就用课余时间去学一些东西来弥补这份失落。我记得我用GUI界面做了一个飞机大战的游戏。同时也学习了HTML,并在我女朋友生日的时候copy并修改别人的网页来为他庆生。

          我修改的网页已经找不到了,但是修改前的网页还在,这个网页是动态的,简洁但是漂亮。

          学了很多Java的知识但是总觉得心中空落落的,我知道我所学习的东西并不系统,同时也不是从底层开始做起,所以做起事来总觉的心中没有把握。同时我发现现在学习Java的人太多了,同时也发现Java似乎是每个人都可以学习的,是无门槛的,那么我的核心竞争力在哪里?这是我当时问自己的一句话,我也希望大家可以常问一下自己,你的核心竞争力是什么?

          而这时我与我哥以及吴老板的电话改变了我的学习路线。我在电话中问他们也是问自己:我应该学习什么?我的兴趣点又是什么?我要高于其他人的门槛是什么?我发现我还是对嵌入式有感情。我还是想学习有底层的东西,这样我觉得学的踏实。同时我发现学习嵌入式Linux是需要门槛的,并不是每个学过单片机的本科生就可以学习。所以我从研二的时候开始学习嵌入式Linux,而从此开始了我的嵌入式Linux之路。而也开始了我对系统的了解。我以前的博客所介绍的就是我在研究生期间学习嵌入式Linux的学习笔记和心得。

    找工作——一点优势就是很大的距离:

          由于我还是学生,所以我参加的是校招,而相对于社招,校招就简单了很多。而这时你相对于其他人一点的优势,其实你就跟他拉开了很大的距离。就像我在前面所说的门槛。

          做技术的校招大多数分为下面几个步骤:

                宣讲会——》笔试——》技术面试——》HR面——》发offer

          在各位参加宣讲会之前我想大家就对自己要应聘的岗位十分熟悉了吧。如果不熟悉你可以在宣讲会时了解也不晚,但是大致的方向应该是清楚的,例如你是要做嵌入式还是要做算法,或者是做图像你应该清楚吧。而在选择岗位时你就会发现,其实平时多学一些东西还是十分重要的,因为平时多学一些东西,那么你的选择范围就相对广一些。而宣讲会时的提问就很重要了。因为回答你问题的很可能是你的部门主管,同时也可能是你面试时的面试官,所以你要在提问时让他对你有一个好的印象十分重要。所以你在提问时要有针对性,要在你的问题中体现了你在这个方向上有了一些了解,并且很想继续学下去,而他应聘的置位正好适合你,例如你要应聘嵌入式驱动工程师岗位,你可以这样提问:您好,我是学习嵌入式Linux驱动的,目前我学习了一些驱动的框架,例如输入系统和usb驱动。我想问咱们公司在驱动上主要做那个方向?上面的问题体现出了两点,第一你确实学习了嵌入式驱动的一些知识,同时你也表示你对这个职位感兴趣。

          宣讲会之后就要笔试了,而笔试其实更多的时候是在考大家的基础,或者说是一个细节。这就要看你平时编程时是不是细心了。而对于做嵌入式驱动的岗位有时候还会考你一些简单的汇编,所以希望你在平时用汇编编程时注意一些。这里我要强调的一点就是你要在这个试卷上体现出你确实学过一些知识,也就是通过你的答案让阅卷的人知道你是他要找的(阅卷的人很可能就是要面试你的人)。例如你会碰到对寄存器中位操作的试题,对于很多人可能就是简单的使用指针对寄存器中位进行操作,而这个时候你在指针声明前加一个voliate关键字就很不一样了,阅卷的人以看就知道你不仅会这道题,同时也知道你确实写过驱动相关的代码。而在笔试中另一个要注意的地方就是当你碰到不会写的程序时,写下你的思路,这个很重要。有时候阅卷人就是要看到你的思路。而对于写出程序的题,你同样要写出思路,这样可以让阅卷人更好的了解你的思路,同时这也体现了一个好的程序员的素养。

          笔试完就要通过你的笔试内容来决定是否通知你参加面试了。而技术面就要检验大家平时的学习成果了,技术面其实更多还是喜欢问你做过什么样的项目。如果你有一些项目经验,那么你就有加分项了。因为面试官很喜欢有项目经验的人,如果你没有项目经验那么你就要向面试官证明你的学习能力很强了。而这个时候面试官的问题有时候会很难(因为他会问很多学习中的细节,以及知识点的细节)。还是那句老话,在技术面时不要不懂装懂,因为对你面试的人都是这方面的牛人,他们对这方面的知识十分熟悉,所以你会什么答什么。不会的不要乱说 。要保持谦虚。

          如果你通过了技术面试,那么可以很荣幸的通知你,你被录取的几率就很大了,因为到HR面试时,主要就是来谈工资了。

     

    展开全文
  • SQLite3嵌入式数据库arm+linux移植

    千次阅读 2016-05-10 17:58:07
    SQLite数据库是一种嵌入式数据库,他的目标是尽量简单,因此它抛弃了传统企业级数据库的种种复杂特性,只实现对于数据库而言的必备的功能。 尽管简单性是SQLite追求的首要目标,但是其功能和性能都非常出色,它...
  • 嵌入式linux Java运行环境搭建和注意事项我的开发硬件环境搭建步骤1. 下载 ORacle 公司的ejdk-8u211-linux-arm-sflt.tar.gz(软件浮点版本,这个很重要,根据自己的板子硬件选。不知到就只有一个个试试) (下载地址...
  • JVM在嵌入式linux下的移植

    千次阅读 2017-12-14 20:26:03
    jvm在嵌入式linux上的移植
  • 嵌入式Linux&Java for ARM

    千次阅读 2018-10-14 17:16:02
    首先需要了解一些概念: 浮点运算是指浮点数参与的运算,因为无法精确表示而进行近似或舍入。浮点运算就是实数运算,因为计算机只能存储整数,所以实数都是约数,这样浮点运算是很慢的而且会有误差。...
  • 基于ARM的嵌入式linux系统设计

    千次阅读 2011-02-12 16:55:00
    基于ARM的嵌入式linux系统设计摘要:本文简要介绍了ARM处理器的特点及其基本结构,详细论述了基于ARM的嵌入式linux系统的关键技术,包括引导加载程序、Linux内核、文件系统、用户应用程序。对linux系统的各部分开发...
  • 嵌入式Linux系统

    千次阅读 2019-07-15 13:40:03
    思想:先整体后局部 Pc与开发板连接方式 1、UART异步串行通信接口(串口) 2、USB串行通信接口 3、TCP/IP网络通信接口 4、Debug Jtag调试接口 PC:CentOS 7 Demoboard:Friendly arm nano pi neo4 ...
  • 嵌入式Linux系统移植

    千次阅读 2019-02-13 15:49:19
    嵌入式Linux系统移植主要由四大部分组成:一、搭建交叉开发环境二、bootloader的选择和移植三、kernel的配置、编译、和移植四、根文件系统的制作第一部分:搭建交叉开发环境 先介绍第一分部的内容:搭建交叉开发...
  • 嵌入式linux的开发流程以及linux应用层内容

    万次阅读 多人点赞 2020-10-07 22:25:40
    嵌入式linux开发流程: 1.搭建前期的开发环境,例如搭建linux主机环境,交叉编译器的安装,还有一些常用的开发辅助软件如source insight等等。 2.学习对硬件的直接操作,这里和单片机操作类似,我们需要查看原理图...
  • 嵌入式Linux应用开发完全手册 经典的Linux驱动入门书籍   http://developer.t-firefly.com/forum.php?mod=viewthread&tid=1396&page=1&extra=#pid4999
  • 朱老师带你初级学Linux

    万人学习 2019-07-01 10:36:14
    本课程是全套课程的第0.2课(基础预科部分第2课,全部课程请加QQ群或者微信公众号获取),主题是linux系统引入及shell命令,总共7小时左右的课程。该视频是我在联嵌科技代课期间随堂真实录制,学生均为根本没听说过...
  • 嵌入式软件工程师岗位要求

    万次阅读 多人点赞 2018-04-28 01:02:21
    1.嵌入式上层的软件应用开发需要:精通嵌入式Linux C语言编程、嵌入式Linux C语言数据结构、嵌入式Linux项目开发流程、嵌入式 Linux并发程序设计、嵌入式 Linux应用编程、嵌入式 Linux网络编程、嵌入式数据库开发;...
  • 课程主要面向嵌入式Linux初学者、工程师、学生 主要从一下几方面进行讲解: 1.linux学习路线、基本命令、高级命令 2.shell、vi及vim入门讲解 3.软件安装下载、NFS、Samba、FTP等服务器配置...
  • 本系列课程针对有意向学习嵌入式软件开发的童鞋,从零开始、深入浅出,内容涵盖:linux系统基础、shell、linux C编程、linux系统编程、网络编程、ARM体系结构及汇编语言、ARM裸机编程、linux系统移植、linux驱动开发...
  • Linux设备驱动开发入门

    万人学习 2018-10-22 21:38:04
    本课程讲解Linux驱动程序开发基本知识,程序架构,字符设备编程,杂项设备编程,具体硬件模块驱动开发。
  • 本课程主要讲解linux中的文件读写和IO处理,包括API的概念、open函数的重要flag、linux内核管理文件的原理、inode和vnode、文件共享、标准IO等。终目的是让大家理解并掌握在linux中使用API和库函数进行文件操作的...
1 2 3 4 5 ... 20
收藏数 155,759
精华内容 62,303
关键字:

嵌入式linux