- 博客(31)
- 收藏
- 关注
原创 C_C++嵌入式知识点
1、程序编译的四个阶段阶段功能预处理(引用头文件、宏定义、条件编译)编译进行词法分析和语法分析,确认所有指令符合语法规则后,将其翻译成汇编代码。汇编把汇编代码翻译成目标机器指令,生成一系列目标文件。链接将目标文件按照链接规则链接成可执行文件。分为静态链接和动态链接,静态链接把静态链接库的代码拷贝到可执行文件中;动态链接不把链接库的代码拷贝到可执行文件中,而是在执行时才到动态库中找到对应代码。2、volatile关键字告诉编译器变量可能会意想不到地发生改
2021-07-27 09:27:22
816
原创 24_块设备驱动
一、块设备驱动框架1、block_device结构体 linux 内核使用 block_device 表示块设备,结构体定义在 include/linux/fs.h 中:struct block_device { dev_t bd_dev; /* not a kdev_t - it's a search key */ int bd_openers; struct inode * bd_inode; /* will die */ struct super_block * bd_s
2021-07-27 09:26:30
1076
原创 23_开发板创建ftp服务器
1、移植vsftpd 将 vsftpd 源码解压:tar -vxzf vsftpd-3.0.3.tar.gz 进入解压后的文件夹,修改 Makefile 使用的编译器:CC = arm-linux-gnueabihf-gcc 编译 vsftdp 源码,然后得到 vsftpd 和 vsftpd.conf 两个文件,然后将两个文件拷贝到开发板中:sudo cp vsftpd ~/linux/nfs/rootfs/usr/sbin/ //拷贝 vsftpd sudo cp vsftp
2021-07-27 09:25:54
553
原创 22_多点电容触摸屏驱动
一、linux电容触摸屏驱动简介1、多点触摸屏(MT)简介 电容多点触摸屏驱动由以下几种类型的驱动组成:IIC 设备驱动,电容触摸 IC 基本都是 IIC 接口。通过中断引脚 (INT) 向内核上报触摸信息,坐标的上报在中断服务函数中完成。触摸屏的坐标信息、屏幕按下和抬起信息都属于 input 子系统,向内核上报触摸屏坐标信息要使用 input 子系统。内核中有一份文档详细的讲解了多点电容触摸屏协议,文档路径为:Documentation/input/multi-touch-pr
2021-07-27 09:25:17
2207
原创 21_串口驱动
一、linux串口简介 串口驱动芯片厂商已经编写好,当系统启动以后驱动和设备匹配成功,相应的串口就会被驱动起来,生成 /dev/ttymxcX(X=0…n) 文件。1、uart_driver注册与注销 uart_driver 结构体表示 UART 驱动,结构体定义在 include/linux/serial_core.h 中:struct uart_driver { struct module *owner; /* 模块所属者 */ const char *driver_name
2021-07-26 13:44:20
732
原创 20_spi驱动
一、SPI驱动框架简介1、spi主机驱动1)spi_master 结构体 spi 主机驱动就是 spi 控制器驱动,内核使用 spi_master 表示 spi 驱动,结构体定义在 include/linux/spi/spi.h 中:struct spi_master { struct device dev; struct list_head list; /* other than negative (== assign one dynamically), bus_num is ful
2021-07-26 13:44:07
906
原创 19_i2c驱动
一、linux I2C 驱动框架简介 I2C 驱动分为总线驱动和设备驱动。 总线驱动:SOC 的 I2C 控制器驱动,也叫 I2C 适配器驱动。 设备驱动:针对具体的 I2C 设备编写的驱动。1、I2C总线驱动 I2C 总线驱动一般由 SOC 厂商编写。1)i2c_adapter 结构体 I2C 总线驱动重点是 I2C 适配器(SOC的 I2C 接口控制器)驱动,内核将 I2C 适配器抽象成 i2c_adapter 结构体,结构体定义在 include/linux/i2c.
2021-07-26 13:43:02
385
1
原创 18_linux_LCD驱动
一、LCD驱动简析1、Framebuffer linux 应用程序通过操作 LCD 的显存来实现在 LCD 上显示信息,显存不能随意申请,驱动程序设置的显存和应用程序访问的显存要是同一片物理内存,因此 Framebuffer 机制诞生。 fb 将系统中所有跟显示有关的硬件和软件集合起来,,虚拟出一个 fb 设备。编写好 LCD 驱动以后会生成一个名为 /dev/fbX 的设备,应用程序通过访问这个设备就可以访问 LCD。 fb 的 file_operations 操作集定义在 drive
2021-07-26 13:42:21
241
原创 17_input子系统
一、input子系统简介 input 子系统用于管理输入,系统框架如下: 编写驱动时,只要向核心层上报输入的事件,核心层会为用户提供一个存储了输入信息的设备节点。1、核心层简介 核心层文件定义在 drivers/input/inut.c 。 核心层会向内核注册一个 input 类,系统启动后可以在 /sys/class 目录下找到一个 input 的子目录。 核心层注册了一个字符设备,主设备号为 INPUT_MAJOR(13),因此所有 input 子系统的设备的主设备号都
2021-07-26 13:41:41
337
原创 16_misc驱动
一、MISC驱动简介 MISC 驱动叫杂项驱动,当外设无法分类时,可以使用 MISC 驱动。 所有的 MISC 驱动的主设备号都是 10,不同的设备使用不同的次设备号。MISC设备会自动创建 cdev。只需要注册 MISC 结构体就能完成驱动的设备号处理到自动创建设备节点。1、miscdevice结构体struct miscdevice { int minor; /* 子设备号 */ const char *name; /* 设备名字,在/dev目录下的设备名字 */
2021-07-26 13:40:42
289
原创 ARM内核与架构
1、ARM架构分类ARM架构发展至今分为 ARMv1~ARMv8 ,不同架构之间指令集存在差异。根据架构类型又开发出不同内核,常用的 ARMv7 架构有三种类型的内核:1)Cortex-A:用于高性能应用,主要支持分页内存管理单元MMU,linux需要MMU的支持才能运行。2)Cortex-R:侧重于实时性应用,如汽车系统。3)Cortex-M:侧重于微控制器,常用的STM32就是此内核。2、Cortex-A7 处理器运行模式 不同模式之间可通过软件、中断和异常进行切换。大多数程序运行在用户
2021-07-26 13:40:17
5406
原创 Linux内核进程调度基本概念
明确:进程是资源分配的最小单位,线程是 CPU 调度的最小单位。 线程是轻量级的进程,因此在 Linux 中,线程是按照进程调度的方式进行调度的。调度时的上下文切换进程上下文切换: 保存上一个进程的寄存器和程序计数器于内核堆栈中,加载下一个进程的寄存器和程序计数器,跳转到程序计数器指向的新位置,执行新的进程。线程上下文切换: 前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上下文切换是一样。前后两个线程属于同一个进程。此时,因为虚拟内存是共享的,.
2021-07-26 13:39:40
558
原创 四种进程通讯方式总结
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程 A 把数据从用户空间拷到内核缓冲区,进程 B 再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。1、管道1.1 匿名管道1)创建管道 匿名管道只能用于有亲缘关系的父子进程之间,且只能单向通讯。 管道随进程,进程在管道在,进程消失管道对应的端口也关闭,两个进程都消失管道也消失。#include <unistd.h>in.
2021-07-26 13:38:49
878
原创 15_内核led
一、内核led简介 linux 内核集成了 LED 的驱动(采用 platform框架),因此只要在设备树文件中添加相应的 LED 节点即可。1、使能内核led驱动(配置图形化界面) 打开图形化配置界面,按照以下路径配置内核:make menuconfig -> Device Drivers -> LED Support (NEW_LEDS [=y]) ->LED Support for GPIO connected LEDs 保存
2021-07-26 13:38:11
296
原创 14_platform设备驱动
一、platform总线1、bus_type结构体 Linux 系统内核使用 bus_type 结构体表示总线,结构体定义在文件 include/linux/device.h:struct bus_type { const char *name; /* 总线名字 */ const char *dev_name; struct device *dev_root; struct device_attribute *dev_attrs; /* use dev_groups inste
2021-07-25 15:40:46
502
1
原创 13_linux异步通知
一、异步通知简介 异步通知:驱动程序可以主动发送信号给应用程序,通知应用程序自己可以访问了,应用程序获取到信号以后就可以从驱动设备中读取或者写入数据。 异步通知的核心是信号,在 arch/arm/include/uapi/asm/signal.h 文件中定义了 linux 所支持的所有信号:#define SIGHUP 1#define SIGINT 2#define SIGQUIT 3#define SIGILL 4#define SIGTRAP 5#defin
2021-07-25 15:40:09
339
原创 12_linux阻塞和非阻塞IO
一、阻塞和非阻塞IO简介1、阻塞IO简介 当应用程序对驱动设备进行输入/输出操作时,如果不能获取到设备资源,那么阻塞式IO会将应用程序对应的线程挂起,直到设备资源可以操作为止。 应用程序使用如下示例代码实现阻塞访问:int fd;int data = 0;fd = open("/dev/xxx_dev", O_RDWR); /* 阻塞方式打开 */ret = read(fd, &data, sizeof(data)); /* 读取数据 */2、非阻塞IO简介 使用非
2021-07-25 15:38:55
229
原创 11_linux内核中断
一、linux中断简介1、中断API函数1)request_irq函数 在 linux 内核中要想使用某个中断是需要申请的, request_irq 函数用于申请中断, request_irq 函数可能会导致睡眠,因此不能在中断上下文或者其他禁止睡眠的代码段中使用 request_irq 函数。 request_irq函数会激活 (使能 )中断,所以不需要我们手动去使能中断,函数原型如下:int request_irq(unsigned int irq, irq_handler_t handle
2021-07-25 15:38:22
3194
原创 10_linux内核定时器实验
一、linux时间管理和内核定时器简介1、内核时间管理简介1)宏HZ 硬件定时器产生的周期性中断,中断频率就是系统频率(拍率)。系统拍率可以设置,单位是HZ,可在编译内核时通过图形化界面设置,设置路径如下:Kernel Features -> Timer frequency([=y]) 配置完以后,可在内核源码根目录下的 .config 文件找到 CONFIG_HZ 的值为所设置的系统频率。而文件 include/asm-generic/param.h 中的宏:#define HZ
2021-07-25 15:37:40
376
原创 9_linux按键实验
一、创建工程1、添加设备树节点1)添加设备节点 在根节点下创建设备节点:gpioled { compatible = "gpioled_test"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&gpioled>; gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; };key_input { compatible = "key_test
2021-07-25 15:37:03
129
原创 8_linux并发与竞争
一、并发与竞争简介 并发与竞争:对于多核 CPU,多线程同时运行时,有可能访问同一个共享资源,可能会相互覆盖这些共享资源,导致内存数据混乱,因此要保证共享资源的有序访问。 临界区:指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问的特性。当有线程进入临界区段时,其他线程或是进程必须等待。 linux 系统并发与竞争产生原因: 1、多线程并发访问 2、抢占式并发访问 3、中断程序并发访问 4、SMP(多核)间并发访
2021-07-25 15:36:30
102
原创 7_led驱动开发pinctrl&gpio子系统
一、创建工程1、添加设备树节点1)添加设备节点 在根节点下创建 led 设备节点:gpioled { compatible = "gpioled_test"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&gpioled>; gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; };2)添加pinctrl节点 在 iomuxc 节点下的子
2021-07-25 15:35:57
194
原创 6_pinctrl子系统&gpio子系统
一、pinctrl子系统1、pinctrl子系统简介pinctrl子系统的主要作用: 1)获取设备树的 pin 信息; 2)根据获取到的 pin 信息来设置 pin 的复用功能; 3)根据获取到的 pin 信息来设置 pin 的电气属性。2、设备树中的 pin 配置信息 设备树中的 iomuxc 节点是 IOMUXC 外设对应的节点,用来描述各外设 pin 配置信息的。在 .dtsi 文件中定义了该节点:iomuxc: iomuxc@020e0000 { compat
2021-07-25 15:35:26
446
1
原创 嵌入式应用开发
1、文件IO基础1)文件描述符 用 open 函数打开一个文件时,会返回一个非负整数的文件描述符,对文件的操作都是通过文件描述符来索引的。 一个进程有打开文件数量的最大限制,通过 ulimit -n 命令查看。 0、1、2 这三个文件描述符被系统占用,分别为:系统标准输入、系统标准输出、标准错误。2)open 函数#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
2021-07-25 15:29:47
2349
1
原创 多线程死锁
1、死锁现象void thread1_func(void){ pthread_mutex_lock(mutex1); //获取互斥锁1 pthread_mutex_lock(mutex2); //获取互斥锁2,阻塞}void thread2_func(void){ pthread_mutex_lock(mutex2); //获取互斥锁2 pthread_mutex_lock(mutex1); //获取互斥锁1,阻塞} 当线程1
2021-04-14 20:33:01
433
原创 STM32无系统移植CanFestival小白教程
最近需要用到CANOPEN来通讯,网上资料很多,可是感觉没有很小白的教程,东看西看看了好久,才算是能用起来。我这边用的是STM32,不跑系统移植了CanFestival,最后实现从站接收报文并修改一些变量的值。移植参考了一些文章,在这里感谢分享资料的老哥们。按照下面的步骤应该能成功通讯获取到想要的变量值。1、下载CanFestival源码:https://hg.beremiz.org/CanFestival-3,选择bz2格式下载就行。2、解压下载的CanFestival源码备用。3、在STM32工程
2021-03-26 17:36:41
7406
3
原创 led驱动开发(设备树)
一、创建工程1、知识前提 一般编写驱动很少直接操作寄存器来初始化外设,但是不排除要调试时要读取或置位寄存器的某些位。 在linux系统下操作寄存器不能直接按照芯片手册的寄存器物理地址来操作,因为linux内核启动的时候会初始化MMU,MMU的作用是将物理内存和虚拟内存映射起来,也就是地址映射:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xo1k6g...
2020-03-13 18:41:15
517
原创 linux设备树
一、设备树基础1、什么是设备树 描述设备树的文件叫做DTS文件,DTS文件采用树形结构描述板级设备(开发板上的设备信息)。 在以前的linux内核中,ARM架构没有采用设备树,在内核源码中有大量的arch/arm/mach-xxx和arch/arm/plat-xxx文件夹,这些文件夹里的文件就是对应平台下的板级信息。 如果不使用设备树来描述板级设备信息,则这些信息的.h和.c文...
2020-03-11 21:16:21
638
原创 常用字符设备入口出口框架_自动创建节点
一、设备号处理及设备注册1、创建设备结构体 驱动设备号除了直接指定外,还可以让linux内核分配。首先创建设备结构体,结构体内包含的设备的属性:struct newchrled_dev{ struct cdev cdev; //字符设备 int major; //主设备号 int minor; //次设备号 dev_t devid; //设备号 struct class ...
2020-03-06 18:29:02
216
原创 led驱动开发(直接操作寄存器)
一、创建工程1、知识前提 一般编写驱动很少直接操作寄存器来初始化外设,但是不排除要调试时要读取或置位寄存器的某些位。 在linux系统下操作寄存器不能直接按照芯片手册的寄存器物理地址来操作,因为linux内核启动的时候会初始化MMU,MMU的作用是将物理内存和虚拟内存映射起来,也就是地址映射:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0BQGUb...
2020-03-03 21:32:16
803
原创 字符设备驱动开发框架
一、创建工程 创建驱动文件夹,然后创建 VSCode 工程,创建 xx.c 驱动源码文件,xx为驱动名。一般编写驱动的框架都是参考 linux 内核写好的驱动。1、添加头文件路径 因为是编写 linux 驱动,因此会用到 linux 源码中的函数。我们需要在 VSCode 中添加 linux 源码中的头文件路径。按下 “Ctrl + Shift + P” 打开控制台,然后输入 “C/...
2020-03-03 21:31:40
222
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人