i.MX6ULL嵌入式Linux开发5-根文件系统完善
上篇文章,使用BusyBox构建了基础的嵌入式Linux系统的根文件系统,基本的功能可以正常运行,但在个基础功能上,还要许多地方需要完善。
[TOC]
1 完善根文件系统上篇说道,Linux系统运行起来后,可以正常的执行”ls”等基础命令,但仔细观察系统运行后的打印信息,有一条提示:
1can't run '/etc/init.d/rcS': No such file pngor directory
说是无法运行“/etc/init.d/rcS”这个文件,因为根文件系统(rootfs)里没有这个文件。这个rcS是什么呢?它其实是一个shell脚本, 在Linux内核启动以后,需要启动一些服务, 而rcS就是规定启动哪些文件的脚本文件。
1.1 创建/etc/init.d/rcS文件在rootfs中创建/etc/init.d/rcS文件(前两级目录不存在,要先创建文件夹,再创建文件),然后在rcS中输入如下所示内容:
123456789101112#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PAT ...
i.MX6ULL嵌入式Linux开发4-根文件系统构建
前面几篇介绍了uboot的移植与内核的移植,本篇进行根文件系统的构建,这是Linux移植三大组成部分的最后一步,根文件系统构建好后,就构成了一个基础的、可以运行的嵌入式Linux最小系统。
[TOC]
1 根文件系统简介Linux的根文件系统一般也叫做 rootfs,Linux的根文件系统更像是一个文件夹或者叫做目录,在这个目录里面会有很多的子目录。根目录下和子目录中会有很多的文件,这些文件是Linux运行所必须的,比如库、常用的软件和命令、设备文件、配置文件等等。
根文件系统的这个“根”字就说明了这个文件系统的重要性,它是其他文件系统的根,没有这个“根” ,其他的文件系统或者软件就别想工作。比如我们常用的 ls、mv、ifconfig 等命令其实就是一个个小软件,只是这些软件没有图形界面,而且需要输入命令来运行。这些小软件就保存在根文件系统中。
在构建根文件系统之前,先来看一下根文件系统里面都有些什么内容,根文件系统的目录名字为‘/’ ,就是一个斜杠:
根文件系统的各个文件夹的作用如下:
目录
描述
/bin
此目录下存放着系统需要的可执行文件,一般都是一些命令,比 ...
i.MX6ULL嵌入式Linux开发3-Kernel移植
本文进行Linux内核的移植。
[TOC]
1 Linux内核简介官网:https://www.kernel.org/
NXP 会从linux内核官网下载某个版本,然后将其移植到自己的 CPU上,测试成功后就会将其开放给NXP的CPU开发者。开发者下载 NXP 提供的 Linux 内核,然后将其移植到自己的产品上。
本文我们就使用NXP提供的Linux源码,文件名为:linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
2 Linux内核编译 编译内核之前需要先在ubuntu上安装lzop库,另外,图形化配置工具还需要ncurses库支持,安装命令为:
123sudo apt-get install lzopsudo apt-get install build-essential sudo apt-get install libncurses5-dev
在Ubuntu中新建一个文件夹,然后将linux内核压缩包拷贝到文件夹中并解压,解压命令为:
1tar -vxf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar. ...
i.MX6ULL嵌入式Linux开发2-uboot移植实践
上篇文章,我们介绍了如何使用NXP原厂的uboot进行编译和烧写,将uboot运行在自己的开发板上。NXP原厂的uboot,直接烧录到我的开发板中,LCD的驱动是不正常的,需要进行修改。本篇我们就来继续研究uboot,使得uboot能匹配我们自己的开发板。
[TOC]
修改uboot以匹配开发板的方式有两种,一种是在NXP原厂开发板i.MX 6ULL EVK的文件上进行修改,另一种仿造NXP的开发板文件,添加自己的开发板文件。
为了能更多的了解uboot,我们使用代码改动较大的第二种方式进行uboot的移植。
在修改uboot之前,先来看一下uboot的源码结构。
1 uboot源码结构分析uboot的源码如下,这里是源码编译后的结果,包含编译后的文件。
这里文件的含义如下:
2 uboot移植实践2.1 添加开发板配置文件首先是创建自己开发板的配置文件,该文件可参考原厂开发板的配置文件,在configs文件夹下,将原来的默认配置文件mx6ull_14x14_evk_emmc_defconfig复制一份,并重命名为mx6ull_myboard_defconfig,该文件即用于作 ...
i.MX6ULL嵌入式Linux开发1-uboot移植初探
本系列教程以i.MX6ULL处理器的ARM开发板为实验基础,学习记录嵌入式Linux开发的各种知识与经验,主要内容包括嵌入式Linux移植,嵌入式Linux驱动开发,嵌入式Linux应用开发等。
本系列教程将以野火的i.MX6ULL eMMC开发板为硬件基础,以野火EBF6ULL Pro开发板教程和正点原子i.MX6ULL阿尔法开发板教程为参考,进行学习实践。
[TOC]
1 嵌入式Linux移植概述Linux 的移植主要包括3部分:
移植bootloader 代码, Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段bootloader程序。 这段bootloader程序会先初始化DDR等外设, 然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。 bootloader有很多,常用的就是 U-Boot。
bootloader 和 Linux 内核的关系就跟 PC 上的 BIOS 和 Windows 的关系一样,bootloader 就相当于 BIOS。
移 ...
电机控制进阶3--PID串级控制(附全套代码下载)
前两篇文章,分别介绍了PID速度控制和PID位置控制,分别用来控制电机以期望的速度持续转动以及以期望的位置(圈数)转动,这里的期望值都只有一个,但是,如果想要以期望的速度转动到期望的位置(启动与停止的加减速过程不考虑),该怎么控制呢?那就要将两者结合起来了,即PID的串级控制来控制电机。
串级PID结构图PID串级控制的典型结构为位置环+速度环+电流环,如下图。
PID串级控制中,最外环是输入是整个控制系统的期望值,外环PID的输出值是内环PID的期望值。
能够使用三环控制的前提是要硬件支持,比如位置环和速度环需要实时的电机转动位置和转动速度作为反馈,这就需要电机需要配有编码器用于测速与测量转动的位置;电流环需要有电流采样电路来实时获取电机的电流作为反馈。
如果没有电流采样电路,可以将电流环去掉,只使用位置环+速度环,系统的期望仍是转动的位置,内环可以调节转动的速度。
另外,如果只是想控制电机转速实现电机调速,可以使用速度环+电流环,系统的期望仍是转动的位置,内环可以调节电机的电流,增强系统转动调节的抗干扰能力。
位置环+速度环实践由于我的电机没有电流测量电路,所以,本文以位 ...
电机控制进阶2--PID位置控制
上篇文章讲解了电机的速度环控制,可以控制电机快速准确地到达指定速度。
本篇来介绍电机的位置环控制,实现电机快速准确地转动到指定位置。
1 位置控制与速度控制的区别回顾上篇,电机速度PID控制的结构图如下,目标值是设定的速度,通过编码器获取电机的转速作为反馈,实现电机转速的控制。
再来看电机位置PID控制,其结构图如下,目标值是设定的位置,通过编码器获取电机累计转动的脉冲数作为反馈,实现电机位置的控制。
所以:对比两张图,速度控制与位置控制的主要区别,就是控制量的不同。
2 核心程序了解了速度控制与位置控制的区别后,下面就可以修改程序。
2.1 编码器相关
2.1.1 电机与编码器参数编码器部分,需要根据自己电机的实际参数进行设定,比如我用到的电机:
编码器一圈的物理脉冲数为11
定时器编码器模式通过设置倍频来实现4倍频
电机的减速齿轮的减速比为1:34
所以,电机转一圈总的脉冲数,即定时器能读到的脉冲数为11*4*34= 1496。
1234567#define ENCODER_RESOLUTION 11 /*编码器一圈的物理脉冲数*/#define ENCODE ...
电机控制进阶1--PID速度控制
之前的几篇文章(电机控制基础篇),介绍的电机编码器原理、定时器输出PWM、定时器编码器模式测速等。
本篇在前几篇的基础上,继续来学习电机控制,通过PID算法,来进行电机的速度控制,并进行实验测试。
PID基础PID即:Proportional(比例)、Integral(积分)、Differential(微分)的缩写。
PID是经典的闭环控制算法,具有原理简单,易于实现,适用面广,控制参数相互独立,参数的选定比较简单等优点。
凡是需要将某一个物理量“保持稳定”的场合(比如维持平衡,稳定温度、转速等),PID都会派上大用场。
PID算法分类PID算法可分为位置式PID与增量式PID两大类。
在实际的编程应用中,需要使用离散化的PID算法,以适用计算机的使用环境,下面以电机转速控制为例,来看一下两种PID算法的基本原理。
位置式PID位置式PID是当前系统的实际位置,与想要达到的预期位置的偏差,进行PID控制
比例P:e(k) 此次误差
积分I:∑e(i) 误差的累加
微分D:e(k) - e(k-1) 此次误差-上次误差
因为有误差积分 ∑e(i),一直累加,也就是当前的输出 ...
C文件操作2:如何随机的进行文件读取?
上篇介绍了C语言文件操作的基本函数,fopen、fwrite、fread、fclose。这些只能从文件头读写或文件尾追加写入。
本篇介绍文件中随机位置读写的方法,会介绍fseek、ftell、rewind。
此外,再介绍几个字符读写函数:fputs、fgets、fpritf、fscanf,用于编写测试代码时用。
文件随机位置读写基础函数对于文件的随机位置读写,可以通过 fseek 、ftell与rewind 函数来完成
fseek
fseek用于设置流stream的文件读写位置为给定的偏移
seeK的中文含义是“寻找”
函数原型:
123456789/** @func: fseek* @brief: 设置流stream的文件读写位置为给定的偏移* @para: [fp]:文件指针* [offset]:偏移量,表示移动的字节数,正数表示正向(结尾)偏移,负数表示负向(开头)偏移* [from]:表示设定从文件的哪里开始偏移,取值范围如下表所示* @return:执行成功,返回0 (fp将指向以from为基准,偏移offset个 ...
C文件操作1:如何写入读取?fopen的6种组合参数怎么用?
C语言中文件操作,即文件打开,文件写入、文件读取、文件关闭等。
在使用这些功能时,需要了解其基本的使用规则,如:
文件读写前,必须先使用fopen函数打开文件。
使用fopen打开时,还要指明文件的打开的参数,是要读呢还是写呢?这些参数如果不注意,比如直接使用”w”参数打开一个已存在的文件,则里面的内容会先被清空,如果还想要之前的文件中的内容,那也已经被清空了!
文件操作基础函数fopen
若要对文件进行读写操作,第一步需要使用fopen()函数
fopen()函数用于打开指定路径的文件,获取指向该文件的指针
函数原型:
12345678/** @func: fopen* @brief: 打开文件* @para: [path]:文件路径,如:"E:\Test\test.txt"* [mode]:文件打开方式(r w a r+ w+ a+ rb wb ab ...具体见下面表格)* @return:文件打开成功,则指向该流的文件指针就会被返回* 文件打开失败,则返回NULL,并把错误代码存在errno中*/ ...