- 博客(59)
- 收藏
- 关注
原创 ioctl
一、概述一个设备除了能够通过读写操作来收发数据或返回、保存数据、还应该有很多其他的操作。比如一个串口设备还应该具备波特率获取和设置、帧格式获取与设置的操作。一个LED设备甚至不应该有读写操作,而应该具有点灯和灭灯的操作。硬件设备如此众多,各种操作纷繁复杂,所以内核将读写之外的其他I/O操作都委派给了另外一个函数接口ioctl,而且文件I/O还具备多种模型,比如有非阻塞、阻塞、I/O多路复用、异步I/O和异步通知。二、IOCTL函数的原型1. 应用程序的ioctl()—>linux的系统IO
2021-02-10 16:38:47
643
原创 动态定时器
1.内核时钟操作系统的内核都需要一个系统时钟才可以工作,这个系统时钟是硬件提供的,操作系统用该时钟进行计时,如sleep()、时间片轮转。操作系统内核使用的时钟,叫内核时钟,也叫滴答时钟。STM32F407 + uC/OS-III :操作系统内核时钟频率:OS_TICKS_PER_SEC = 1000S5P6818 + linux :操作系统内核时钟频率:HZ = 1000linux的内核时钟,是由处理器的定时器提供的。二、HZ1.HZ是一个全局的常数HZ就是linux内核时钟的频率,
2021-02-10 11:29:49
2590
原创 GPIO标准函数
这里写目录标题一、GPIO的标准接口函数二、GPIO标准接口函数三、参考源码实例四、GPIO口号五 、检查 PIN 是否被其他外设使用一、GPIO的标准接口函数前面访问GPIO的方法:request_mem_region申请GPIO寄存器的物理内存区ioremap实现IO内存的动态映射,得到虚拟地址访问虚拟地址进而控制硬件后面的简单的GPIO访问方法:GPIO是嵌入式平台最常见的一个硬件模块,所以linux内核将GPIO的访问过程封装成了标准的接口函数,这些接口函数在调用的时候和平
2021-02-10 09:11:32
1743
原创 延时函数
一、内核的延时函数应用程序的睡眠函数#include <unistd.h>unsigned int sleep(unsigned int sec)int usleep(unsigned int usec)驱动程序的睡眠函数睡眠延时,会形成阻塞,导致进程调度(长延时)。优点:优点不占用CPU资源。缺点:时间精确度低#include <linux/delay.h> void ssleep(unsigned int seconds) //秒级别void
2021-02-09 22:46:23
1771
原创 IO内存
一、什么是IO内存二、IO内存的使用方法三、相关的函数四、虚拟地址访问的函数五、拓展一、什么是IO内存外设的SFR(特殊功能寄存器)编址与内存的编址是同一个地址空间,叫做IO内存。这个IO关键字,其实就是配置寄存器。root@ATK-IMX6U:~# cat /proc/iomem00905000-0091ffff : 905000.sram01804000-01805fff : /soc/dma-apbh@0180400002010000-02013fff : /soc/aips-bus@0.
2021-02-09 21:04:47
287
转载 Device Tree(二):基本概念
原文链接一、前言一些背景知识(例如:为何要引入Device Tree,这个机制是用来解决什么问题的)请参考引入Device Tree的原因,本文主要是介绍Device Tree的基础概念。简单的说,如果要使用Device Tree,首先用户要了解自己的硬件配置和系统运行参数,并把这些信息组织成Device Tree source file。通过DTC(Device Tree Compiler),可以将这些适合人类阅读的Device Tree source file变成适合机器处理的Device Tre
2021-02-07 12:40:17
237
转载 Device Tree(一):背景介绍
转载的原文链接一、前言作为一个多年耕耘在linux 2.6.23内核的开发者,各个不同项目中各种不同周边外设驱动的开发以及各种琐碎的、扯皮的俗务占据了大部分的时间。当有机会下载3.14的内核并准备学习的时候,突然发现linux kernel对于我似乎变得非常的陌生了,各种新的机制,各种framework、各种新的概念让我感到阅读内核代码变得举步维艰。 还好,剖析内核的热情还在,剩下的就交给时间的。首先进入视线的是Device Tree机制,这是和porting内核非常相关的机制,如果想让将我们的硬件平台
2021-02-07 03:17:38
218
原创 IMX6ULL uboot启动分析(七)
1、前言在前面的文章《Uboot启动流程分析(六)》中,链接如下:https://www.cnblogs.com/Cqlismy/p/12194641.html已经对board_init_r()函数进行了简单的流程分析,该函数的调用过程和board_init_f()函数类似,在init_sequence_r函数初始化序列的最后,将会调用run_main_loop()函数,使用过uboot的都知道,当uboot启动后,将会进入到倒计时,至于倒计时的时间,我们可以自行修改,当我们倒计时结束后,如过没有按下
2021-02-05 13:25:10
253
转载 IMX6ULL uboot启动分析(六)
1、前言2、board_init_r函数3、小结1、前言在前面的文章《Uboot启动流程分析(三)》和《Uboot启动流程分析(四)》,链接分别如下:https://www.cnblogs.com/Cqlismy/p/12006287.htmlhttps://www.cnblogs.com/Cqlismy/p/12147411.html已经对board_init_f函数进行了简单介绍,在这个函数当中,会调用一系列的函数去初始化一些早期的板子外设和gd结构体的成员变量,但是board_init_f.
2021-02-05 13:19:53
471
转载 IMX6ULL uboot启动分析(五)
1、前言2、uboot段相关变量3、relocate_code函数4、relocate_vectors函数5、小结1、前言在前面的文章《Uboot启动流程分析(四)》,链接如下:原文链接已经对board_init_f() 函数作出了简单的分析,该函数对一些早期的外设进行了初始化,例如调试串口,并填充了gd_t结构体中的成员变量,最主要的是对整个DRAM的内存进行了分配,以便uboot的重定位,接下来,先回顾一下_main函数的大概流程,如下:_main | board_init_.
2021-02-05 13:13:25
543
转载 IMX6ULL uboot启动分析(二)
1、前言2、_main函数3、小结1、前言在前面的文章《Uboot启动流程分析(一)》中,链接如下:点击链接已经简单地分析了low_level_init函数,其调用流程如下:save_boot_params_ret | cpu_init_crit | | | lowlevel_init | | | s_init | _main接下来,则继续往下分析_main.
2021-02-04 12:15:28
569
转载 IMX6ULL uboot启动分析(一)
转载自:原文链接@TOC1、前言Linux系统的启动需要一个bootloader程序,该bootloader程序会先初始化DDR等外设,然后将Linux内核从Flash中拷贝到DDR中,最后启动Linux内核,uboot的全称为Universal Boot Loader,Linux系统中常用的bootloader就是uboot,接下来,将会进行简单的uboot启动流程分析,uboot的源码为uboot-imx-rel_imx_4.15_2.1.0。2.调用流程这里先给出调用流程。_start -
2021-02-04 11:27:46
1472
原创 uboot
这里写目录标题1. 什么是uboot2. uboot的作用3. uboot的输出信息1. 什么是ubootuboot其实就是一个通用的引导程序——bootloader。boot,完成硬件的初始化,启动硬件平台loader,初始化硬件后,加载操作系统。支持各种硬件,例如支持ARM、MIPS、X86、AVR32、RISC-V架构…支持各种操作系统,例如支持WinCE、Linux内核、安卓操作系统…2. uboot的作用1)第一阶段初始化,CPU的初始化,用汇编语言来编写,初始化cache、MMU
2021-02-04 07:19:23
423
原创 字符设备
字符设备0.设备驱动的分类1./dev目录下设备的区分2.字符设备驱动的设计过程3.定义一个字符设备4.定义并初始化一个文件操作集5.给字符设备申请设备号6.初始化设备7.编写应用程序8.使用动态分配设备号9.驱动程序与应用程序进行数据交换10.自动创建设备节点0.设备驱动的分类设备驱动分为三大类:字符设备、块设备、网络设备。1.字符设备:该设备对数据的处理按照字节流的形式进行的,支持顺序访问(是有时间的概念),也可以支持随机访问。典型的字符设备:串口、键盘、触摸屏、摄像头、I2C、SPI、声卡、
2021-02-02 16:00:29
2224
原创 内核模块
1.为什么使用内核模块2.内核模块是什么?3.设计一个简单的内核模块4.内核模块与应用程序区别5.Makefile6.printk函数7.内核模块参数8.编译多个内核模块9.内核符号表——全局共享函数接口与变量10.多个源文件组合为内核模块1.为什么使用内核模块宏内核:简单来说,就是把很多东西都集成进内核,例如linux内核,除了最基本的进程、线程管理、内存管理外,文件系统,驱动,网络协议等等都在内核里面。优点是效率高。缺点是稳定性差,开发过程中的bug经常会导致整个系统挂掉。做驱动开发的应该经常有按.
2021-02-01 22:04:40
1280
原创 内核编译
为啥需要内核编译电脑的开发环境源码编译过程(用户快速体验)内核源码目录与重点文件1.目录2.根目录下的一些单独文件:为啥需要内核编译内核源码的\Documentation\kbuild\modules.txt说明文档有以下英文描述:=== 2. How to Build External ModulesTo build external modules, you must have a prebuilt kernel availablethat contains the configurati.
2021-02-01 16:58:05
534
原创 驱动是什么
驱动是什么定义驱动的基本要素驱动的核心思想定义驱动是 Linux 系统中设备和用户之间的桥梁,Linux 系统中,访问设备必须通过设备驱动进行操作,用户程序是不能直接操作设备的。Linux 系统中硬件、驱动和用户程序的关系如下图。驱动程序运行与内核空间,用户程序只能通过内核提供的系统调用,由经 VFS 以及驱动程序才能访问和操作硬件,硬件设备传递的数据也必须经过驱动、VFS 和系统调用才能被用户程序接收。所以说,设备驱动是应用程序访问系统设备以及进行数据传递的桥梁和通道。驱动的基本要素Linux
2021-02-01 16:24:46
2184
转载 C++中STL用法超详细总结
1 什么是STL?STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常
2020-12-24 00:56:05
9122
原创 C++笔记(九)
模板代码一律写在头文件中,不能写到cpp文件原因链接类模板的例子:a.h// 类模板template <typename T1, typename T2>class node{ T1 a; T2 b;public: node(){cout << "通用版本" << endl;}};// 类模板的特化1template <typename T1>class node<T1, string> // 特化
2020-12-23 18:51:35
59
原创 C++笔记(八)
智能指针模板类:智能指针是行为类似于指针的类对象。但这种对象还有其他功能。void remodel(std::string &str){ std::string *ps=new std::string(str); ... str=ps; retrun;}有缺陷。每当调用时,该函数都分配堆中的内存,但从不收回,从而导致内存泄漏。解决:在return 语句前加上delete ps;即可智能指针的思想:当函数退出时,本地变量都将从栈内存中删除—因此指针ps占据的内存将被释放。如果ps
2020-12-23 11:45:00
53
原创 C++笔记(七)
友元C++控制对类对象私有部分的访问。通常,公有类方法提供唯一的访问途径,但是有时候这种限制太严格,以至于不适合特定的编程问题。在这种情况下,C++提供了另外一种形式的访问限权:友元的种类:友元函数友元类友元成员函数通过让函数成为类的友元,可以赋予函数与类的成员函数相同的访问权限。1.为何需要友元看一个例子:A=B*2.75其中A,B是同一类型的类。被转换为下面的成员函数调用:A=B.operator*(2.75)但是如果这样的语句该如何操作呢?A=2.75*B从概念上看
2020-12-22 21:58:01
49
原创 C++笔记(六)
1.运算符函数重载#include <iostream>using namespace std;class ComplexNumber // 复数{ float real; // 实部 float image;// 虚部public: // 无参构造函数、析构函数、赋值操作符函数、拷贝构造函数 ComplexNumber(float r=0, float i=0):real(r), image(i){} // 对加法运算符+的重写
2020-12-22 13:43:15
76
原创 C++笔记(五)
1.深浅拷贝如果一个类中有指针,那么就意味着有类外资源(内存)存在需要考虑深浅拷贝的问题必须重写析构函数2. 默认浅拷贝:. 只复制指针,没复制真正的内存class A{ int size; int *p;public: A(const A &r) { size=r.size; // 默认浅拷贝: 只复制指针,没复制真正的内存 p = r.p; } // 3,赋值
2020-12-22 10:51:41
91
原创 C++笔记(四)
1.纯虚函数在基类中仅仅给出声明,不对虚函数实现定义,而是在派生类中实现。这个虚函数称为纯虚函数。普通函数如果仅仅给出它的声明而没有实现它的函数体,这是编译不过的。纯虚函数没有函数体。语法:纯虚函数需要在声明之后加个=0;class <基类名>{virtual <类型><函数名>(<参数表>)=0; ......};2.抽象类含有纯虚函数的类被称为抽象类。抽象类只能作为派生类的基类,不能定义对象,但可以定义指针。在派生类实现该纯虚函数后
2020-12-17 18:47:37
90
原创 tslib 移植与使用
tslib 是一个开源的第三方库,用于触摸屏性能调试,使用电阻屏的时候一般使用 tslib 进行校准。虽然电容屏不需要校准,但是由于电容屏加工的原因,有的时候其不一定精准,因此有时候也需要进行校准。最主要的是 tslib 提供了一些其他软件,我们可以通过这些软件来测试触摸屏工作是否正常。最新版本的 tslib 已经支持了多点电容触摸屏,因此可以通过 tslib 来直观的测试多点电容触摸屏驱动,这个要比观看 eventX 原始数据方便的多。tslib 的移植很简单,步骤如下:1 、获取 tslib 源码
2020-12-16 22:37:43
3837
转载 C++笔记(三)
多态性与虚继承面向对象程序设计语言有封装、继承和多态三种机制,这三种机制能够有效提高程序的可读性、可扩充性和可重用性。多态(polymorphism)”指的是同一名字的事物可以完成不同的功能。多态可以分为编译时的多态和运行时的多态。前者主要是指函数的重载(包括运算符的重载)、对重载函数的调用,在编译时就能根据实参确定应该调用哪个函数,因此叫编译时的多态;而后者则和继承、虚函数等概念有关。请看下面代码:#include <iostream>using namespace std;//
2020-12-15 23:44:35
69
原创 C++笔记(二)
1、三种继承关系公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。(最常见)保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。(子类对象不可能直接访问到基类的成员) class Derived : protected Bas
2020-12-15 23:04:02
115
原创 C++笔记(一)
1.构造函数一般而言,是公有权限,否则无法创建对象无返回值,名称与类类名一致每个类必有,如果没写那么系统会自动产生一个无参的空版本跟普通函数一样可以重载,可以有默认参数等等每当定义一个对象,对应版本的构造函数会被自动调用主要功能就是初始化类成员2.析构函数一般而言,是公有权限,否则无法正确释放对象资源无返回值,名称前有~且名称与类名一致每个类必有,如果没写那么系统会自动产生一个空版本不可重载,析构函数的接口是固定的每当一个对象被释放,对应的析构函数会被自动调用主要功能就是释放
2020-12-15 20:25:21
55
转载 C++的const类成员函数
函数解释类成员函数类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类访问修饰符类成员可以被定义为 public、private 或 protected。默认情况下是定义为 private。构造函数 & 析构函数类的构造函数是一种特殊的函数,在创建一个新的对象时调用。类的析构函数也是一种特殊的函数,在删除所创建的对象时调用。C++拷贝构造函数拷贝构造函数,是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来...
2020-12-15 12:10:30
686
转载 C语言的那些秘密之---函数返回局部变量
原文链接一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。总结如下:返回指向字符串常量的指针不能返回以局部
2020-12-13 00:52:32
227
转载 函数 scanf 前世今生
原文链接C语言初学者,最常用的函数当属 printf() 和 scanf() ,前者无用多言,毕竟鼎鼎大名的 HelloWorld 也要仰仗它出手,printf()函数只管将数据输出至屏幕,基本没有什么出错的机会,而后者 scanf() 则隐晦许多,甚至有些自称编程老鸟也未必深谙其内涵,这篇小文,作为初级出门装,建议初学者们第一时间买上。先来一段白痴式代码(idiot.c),由易入难,以体现我一贯的思维严谨性:int age;scanf("%d", &age);printf("哇!您
2020-12-11 14:38:04
185
转载 C++ 类的静态成员详细讲解
原文链接在C++中,静态成员是属于整个类而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。静态成员的定义或声明要加个关键字static。静态成员可以通过双冒号来使用即<类名>::<静态成员名>在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象。希望阅读本文可以使读者对
2020-12-11 01:38:09
245
1
转载 cosnt成员数据的初始化
原文链接const可以用来声明常量也就是说他的值不能被修改;const成员必须在定义的时候同时初始化,不能进行赋值 如 const int a;a的值不能修改,不能给它赋值,如何才能让它一开始就拥有一个值?1、在声明的时候对他进行初始化const int a=1;2、在函数中声明的形参,在函数被调用时会得到实参的值。但是如果在类中呢?class Demo{ const int ci;public: void get_ci() { return ci
2020-12-11 01:05:52
255
转载 C++初始化列表
原文链接何谓初始化列表与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。在C++中,struct和class的唯一区别是默认的访问性不同,而这里我们不考虑访问性的问题,所以下面的代码都以struct来演示。struct foo{ string name ; int id ; foo(string s, int i):name(s), id(i){} ; // 初始化列表};构造函数的两个
2020-12-10 14:20:31
141
原创 C++函数重载
函数重载定义:可以有多个同名的函数。可以使用函数重载来设计一系列函数-----它们完成相同的工作,但使用不同的参数列表。函数重载的关键是函数的参数列表----也称为函数特征标(funtion signature).如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。C++允许定义名称相同额函数,条件是它们的特征标不同。如果参数数目或者参数类型不同,则特征标也不同。【示例】定义一组原型如下的printf()函数: void printf(const ch
2020-12-10 12:26:36
108
转载 C/C++引用和指针的联系和区别
原文链接为什么C/C++语言使用指针?1. 一方面,每一种编程语言都使用指针。不止C/C++使用指针。每一种编程语言都使用指针。C++将指针暴露给了用户(程序员),而Java和C#等语言则将指针隐藏起来了。1. 另一方面使用指针的优点和必要性:指针能够有效的表示数据结构能动态分配内存,实现内存的自由管理能较方便的使用字符串便捷高效地使用数组指针直接与数据的储存地址有关,比如:值传递不如地址传递高效,因为值传递先从实参的地址中取出值,再赋值给形参代入函数计算;而指针则把形参的地址直接指向实
2020-12-10 02:21:16
146
转载 using声明与using编译指令
原文链接内容全部参考自:c++ Primer Plus 第九章命名空间:C++中允许用户创建自己的用户空间。可以通过关键字namespace 声明即可需要注意的事项:名称空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中(我的理解是函数中)。示例代码如下:#include <iostream> using namespace std;void funtion(void){ namespace Jill{ double bucket(double a){
2020-12-09 00:19:49
886
转载 大端序、小端序、网络字节序
原文链接关于字节序(大端法、小端法)的定义《UNXI网络编程》定义:术语“小端”和“大端”表示多字节值的哪一端(小端或大端)存储在该值的起始地址。小端存在起始地址,即是小端字节序(Little-Endian);大端存在起始地址,即是大端字节序(Big-Endian)。也可以说:1.小端法就是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端。2.大端法就是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端。举个简单的例子,对于整形0x1234567
2020-12-08 02:33:55
388
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人