嵌入式Linux
阳光下的咖啡
这个作者很懒,什么都没留下…
展开
-
嵌入式Linux应用调试【2】—— 打印用户态oops
修改内核,使得应用程序出错时,也能打印oops。1 pc值1.1 源码打印的oops,有“Unable to handle kernel paging request”等描述,在内核代码中搜索,找到在arch/arm/mm/fault.c中,__do_kernel_fault()static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *re原创 2020-09-22 20:31:37 · 289 阅读 · 0 评论 -
嵌入式Linux应用调试【1】—— strace、gdb
1 stracestrace可记录执行过程中的系统调用、接收到的信号。(1)移植tar -xjf strace-4.5.15.tar.bz2cd strace-4.5.15/patch -p1 <../strace-fix-arm-bad-syscall.patch //在arm./configure --host=arm-linux CC=arm-linux-gcc make //生成strace命令文件将生成的stra原创 2020-09-22 20:27:50 · 331 阅读 · 0 评论 -
嵌入式Linux驱动学习——串口
1 框架1.1 概念终端:只有输入、显示部件并能连接到计算机的设备,早期设备,现在没有了。虚拟终端:由硬件终端演化出来的软件概念,用计算机的软件来模拟以前硬件的方式。控制台:console, 一种特殊的终端,能够显示系统信息,一般只有一个。1.2 终端驱动框架tty核心:对整个tty设备的抽象,对用户提供统一的接口tty线路规程:对传输数据的格式化tty驱动:面向tty设备的硬件驱动当从用户空间进行读写时,流程如下:2 源码分析由上述框架,关注tty核心、tty线路规程和tty驱动原创 2020-09-22 11:17:43 · 390 阅读 · 0 评论 -
嵌入式Linux驱动学习 —— IIC
1 IIC IIC,串行总线,两条数据线:数据线SDA,时钟线SCL。多主机的半双工通信方式。 传输波形示意图: 信号类型: (1)空闲信号:SDA和SCL同时处于高电平。 (2)起始信号:SCL为高,SDA由高到低的跳变。 (3)结束信号:SCL为高,SDA由低到高的跳变。 (4)响应信号:在第9个时钟接收方接收该字节成功,便会输出一个ACK应答信号,当SDA为高电平,表示为非应答信号NACK,当SDA为低电平,表示为有效应答信号ACK。2 AT24C08 MINI24原创 2020-09-12 13:12:08 · 538 阅读 · 0 评论 -
嵌入式Linux驱动学习 ——USB
1 USB基本概念1.1 传输类型(1)控制传输(control) 是每一个USB设备必须支持的,通常用来获取设备描述符、设置设备的状态等等。一个USB设备从插入到最后的拔出这个过程一定会产生控制传输(即便这个USB设备不能被这个系统支持)。(2)中断传输(interrupt) 支持中断传输的典型设备有USB鼠标、 USB键盘等等。中断传输不是说我的设备真正发出一个中断,然后主机会来读取数据。它其实是一种轮询的方式来完成数据的通信。USB设备会在设备驱动程序中设置一个参数叫做interval,原创 2020-09-10 13:36:41 · 966 阅读 · 0 评论 -
嵌入式Linux驱动学习——按键定时器防抖
1 定时器(1)全局变量 jiffies:记录了系统启动以来,经过了多少tick,初始值为0。一个tick代表多长时间,在内核的CONFIG_HZ中定义。比如CONFIG_HZ=200,则一个jiffies对应5ms时间。 HZ:系统定时器每秒产生中断的频率,/arch/arm/include/asm/param.h中定义。(2)函数//include/linux/timer.hstruct timer_list { struct list_head entry; unsigned lo原创 2020-09-10 09:53:14 · 302 阅读 · 0 评论 -
嵌入式Linux驱动学习——同步互斥、阻塞
学习原子操作和互斥信号量的使用、阻塞/非阻塞在驱动中的应用。1 问题 当多个应用程序同时对一个设备文件进行写操作时,可能出现问题。修改程序,使得只有一个应用程序使用驱动程序。2 原子操作2.1 原子操作函数 保证了变量操作的原子性。atomic_t v = ATOMIC_INIT(0); atomic_read(atomic_t *v); void atomic_inc(atomic_t *v); void atomic_dec(atom原创 2020-09-10 09:52:23 · 172 阅读 · 0 评论 -
嵌入式Linux驱动学习—— 异步通知
1 异步通知机制 之前的按键处理,使用阻塞和poll方式,这样应用层需要等待事件到来。而异步方式,应用层可以去处理其他事情,当有事件发生时,主动通知应用层。 例如:kill -9 pid,发信号9给pid对应的进程,杀死进程。 写一个测试程序,主函数一直处于休眠状态,当接收到信号后,打印。#include <stdio.h>#include <signal.h>void my_signal_run(int signum) //信号处理函数{ s原创 2020-09-10 09:51:22 · 148 阅读 · 0 评论 -
嵌入式Linux驱动学习 —— poll机制
1 IO模式Linux下的五种IO模型:1)阻塞IO(blocking IO):读数据,若没有,一直阻塞,直到有数据后返回;2)非阻塞IO (nonblocking IO):读数据,不管有没有,直接返回;3)IO复用(select 和poll) (IO multiplexing):同时监听多路数据,只要有一路有数据或超时返回;4)信号驱动IO (signal driven IO (SIGIO)):很少用;5)异步IO (asynchronous IO (the POSIX aio_functio原创 2020-09-10 09:50:09 · 270 阅读 · 0 评论 -
嵌入式Linux项目实践——数码相框1
文章目录1 框架2 显示文字2.1 文字编码方式2.2 英文字母显示2.2.1 概述2.2.2 程序2.3 freetype理论2.3.1 介绍2.3.2 在PC上运行2.3.3 在LCD上运行1 框架(1)需求分析 1)上电,LCD显示界面 2)根据配置文件,停留在当前界面,或者自动播放下一幅 3)点击,出现对话框,选择手动/自动播放 4)滑动:上——放大,下——缩小,左——上一幅,右——下一幅 5)左右移动速度较快,显示下下一幅(2)包含进程 1)输入进程: 主控线原创 2020-08-24 20:50:34 · 1173 阅读 · 0 评论 -
嵌入式Linux驱动学习【17】—— 驱动调试之僵死问题
1 问题 假设在驱动中,写入while(1),则加载模块后,一直无log输出,无法定位问题。2 定时器 当内核中断产生时,会做以下几步: 1)pc-4(计算返回地址值),然后将各个寄存器值存到sp栈里 2)获取中断号,获取sp地址,然后调用asm_do_IRQ() 为了解决上述问题,在定时中断中,若发现一个进程10s内不断获取的进程,则打印PC值等。在asm_do_IRQ中加入#ifdef 1 static pid_t pre_pid;原创 2020-08-24 10:30:42 · 191 阅读 · 0 评论 -
嵌入式Linux驱动学习【16】—— 驱动调试oops
1 问题在led驱动中,制造错误,在open中加入unsigned long * gpfcon = (unsigned long *)0x56000050;*gpfcon = 1;装载模块,并用测试程序打开时,出错,记录log。其中可以看到提示、PC值、栈回溯等信息。Unable to handle kernel paging request at virtual address 56000050pgd = c3ae0000[56000050] *pgd=00000000Internal原创 2020-08-24 09:54:21 · 404 阅读 · 0 评论 -
嵌入式Linux驱动学习【15】—— 驱动调试printk
1 设置打印 在uboot命令行设置打印的显示设备:(1)LCD:console=tty1(2)串口UART0:console=ttySAC0,1152002 源码分析2.1 命令行传参 内核/kernel/printk.c中__setup("console=", console_setup); 根据命令行传入的参数,调用console_setup。static int __init console_setup(char *str){ char buf[sizeof(conso原创 2020-08-23 21:44:38 · 341 阅读 · 0 评论 -
嵌入式Linux驱动学习【14】—— U盘自动挂载
1 源码流程 实现U盘的自动挂接,在/etc/mdev.conf文件里加入一行语句就能实现自动装载u盘。 如何调用到/etc/mdev.conf,以之前的驱动为例,创建设备device_create ---> device_create_vargs ---> device_register ---> device_add ---> kobject_uevent ---> kobject_uevent_envint kobject_ue原创 2020-08-23 12:16:45 · 311 阅读 · 0 评论 -
嵌入式Linux驱动学习【13】—— DMA
1 DMA1.1 概述 DMA(Direct Memory Access),不需要CPU控制,直接进行数据传输。S3C2440有4个DMA通道,源地址和目的地址可以是系统总线或外设总线,因此传输可以有4种情况: 系统总线/外设总线 <===> 系统总线/外设总线 请求源: 工作模式: 1)查询模式:当DMA请求XnXDREQ为低电平时,则DMA会一直传输数据,直到DMA请求拉高,才停止。 2)握手模式:如果 XnXDREQ 为高电平,DMA XnXDAC原创 2020-08-22 12:30:05 · 323 阅读 · 0 评论 -
嵌入式Linux驱动学习【12】—— 声卡
1 硬件 硬件原理图 与mini2440连接示意图2 音频基础(1)采样频率(sample rate):录音设备在一秒钟内对声音信号的采样次数。(2)通道数(channel):分为单声道mono;立体声stereo。两个声道,说明只有左右两边有声音传过来。(3)比特率(bitrate):也叫码率。针对编码格式,表示压缩编码后每秒的音频数据量大小。计算公式:比特率 = 采样率 x 采样精度 x 声道数。单位kbps。(4)量化位数:指每个采样点里传输的数字信号次数,一般有8位、16位、3原创 2020-08-21 18:23:03 · 925 阅读 · 0 评论 -
嵌入式Linux驱动学习【11】—— RTC
1 字符设备注册(1)2.4之前register_chrdev(unsigned int major, const char *name,const struct file_operations *fops); 缺点:注册字符设备,还会连续注册0~255个次设备号,使它们绑定在同一个file_operations。(2)2.4之后 静态注册(指定设备编号来注册)、动态分配(不指定设备编号来注册),以及有连续注册的次设备编号范围区间。/*指定设备编号来静态注册一个字符设备*/int reg原创 2020-08-21 11:49:05 · 218 阅读 · 0 评论 -
嵌入式Linux驱动学习【10】—— 虚拟网卡
1 网络设备驱动结构1.1 结构 (1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议为 ARP 还是IP,都通过 dev_queue_xmit()函数发送数据,并通过 netif_rx()函数接收数据。这一层的存在使得上层协议独立于具体的设备。发送接收都需要sk_buff,sk_buff 结构体非常重要,定义于 include/linux/skbuff.h 文件,它的含义为“套接字缓冲区” ( 2) 网络设备接口层向协议接口层提供统一的用于描述具体网络设备属性和操作的结构体n原创 2020-08-18 16:44:05 · 500 阅读 · 0 评论 -
嵌入式Linux驱动学习【9】—— Nor Flash
1 Nor Flash 原理图 与Nand Flash不同,Nor Flash有地址线、数据线,能直接读取数据,但是不能直接写入数据,需要有命令才行。当进行写时,一般要解锁->命令->数据,当写完毕,要reset,退出当前模式。 Nor Flash规范: 1)jedec:用来帮助程序读取Flash的制造商ID和设备ID,通过读ID来匹配linux内核中drivers/mtd/chips/jedec_probe.c里的jedec_table[]数组,来确定norflash的各个参原创 2020-08-18 11:26:42 · 479 阅读 · 0 评论 -
嵌入式Linux驱动学习【8】—— Nand Flash
1 Nand Flash 原理图。 引脚:引脚功能IO0~IO7数据输入输出CLE命令锁存ALE地址锁存nCE芯片使能nRE读使能nWE写使能R/nB就绪/忙 操作nand flash基本流程,传输命令–>地址–>数据,以读操作为例,时序图: 读操作主要有以下步骤: 1)选中芯片(NFCONT寄存器第1位) 2)清除RnB(NFSTAT寄存器第4位) 3)发出命令0x00(NFCMMD寄存原创 2020-08-17 18:49:17 · 494 阅读 · 0 评论 -
嵌入式Linux驱动学习【7】——块设备
1 块设备读取 对于机械硬盘,若是如图中所示,请求1->2->3,由于机械探头移动速度慢,按这样的顺序会比较慢,所以需要进行优化。若是能调整为1->3->2,则可提高性能。优化: 1)把读写请求放入队列。 2)优化后再执行。2 框架(1) 框架(2)结构体 1)block_device_operations:块设备操作集合。 2)gendisk:表示一个独立的磁盘设备。 3)request:表示等待进行的IO请求。 4)bio:正在现场执行的IO原创 2020-08-15 11:32:38 · 217 阅读 · 0 评论 -
嵌入式Linux驱动学习【6】—— 触摸屏
1 触摸屏原理 四线电阻式触摸屏,即根据欧姆定律,利用分压原理,获取x、y的ADC采样值,转化为坐标。 S3C2440数据手册描述了触摸屏接口示意图。 外接XP、XM、YP、YM,INT_TC表示触摸屏被按下,INT_ADC便是A/D转换完成。 工作过程中,触摸屏控制器的4种模式: (1)等待中断模式:S3C2440,设置ADCTSC寄存器,表示等待Pen Down或Pen Up中断。 (2)分离的x/y转换:分别获取x、y值。 (3)自动模式:自动转换,x、y值分别写入ADC原创 2020-08-13 18:30:02 · 358 阅读 · 0 评论 -
嵌入式Linux驱动学习【5】——LCD
1 LCD概念 LCD类型:STN、TFT、LIPS等。对于TFT LCD外接信号有信号名称描述VSYNC垂直同步HYSNC像素时钟HCLK像素时钟VD[23:0数据LEND行结束PWREN电源开关 LCD时序 LCD控制器支持256色(8PBPD)、64K(16BPP)、16M(24BPP)等。2 帧缓存 为显示设备的抽象,在RAM中开辟一段缓存,直接向其中写入图像,LCD控制器不断的从这段缓存中取数据显示到LCD上。原创 2020-08-12 16:08:05 · 309 阅读 · 0 评论 -
嵌入式Linux驱动学习【4】—— platform
1 platform机制虚拟总线:通常设备和驱动都挂接在总线上,例如USB、SPI等,但是对于挂接在 SoC内存空间的外设等确不依附于此类总线,因此,linux提供了platform总线。关注3个实体:设备 platform_device、驱动platform_driver、总线。目的:设备和驱动分离,便于移植。2 源码(1)结构体设备struct platform_device { const char * name; int id; struct device dev; u32原创 2020-08-12 13:01:22 · 177 阅读 · 0 评论 -
嵌入式linux驱动学习【3】——输入子系统
1 简介 输入设备(如按键、键盘、触摸屏、鼠标等)是典型的字符设备,其一般的工作机理是底层在按键、触摸等动作发送时产生一个中断(或驱动通过 timer 定时查询),然后 CPU 通过 SPI、 I2C或外部存储器总线读取键值、坐标等数据,放入一个缓冲区,字符设备驱动管理该缓冲区,而驱动的 read()接口让用户可以读取键值、坐标等数据。 显然,在这些工作中,只是中断、读键值/坐标值是设备相关的,而输入事件的缓冲区管理以及字符设备驱动的 file_operations 接口则对输入设备是通用的。基于此原创 2020-08-12 09:37:29 · 218 阅读 · 0 评论 -
嵌入式Linux驱动学习【2】—— 按键驱动
1 中断流程trap_init设置异常处理相量,发生异常后,根据所在的模式,查找异常相量,跳转到异常处理程序。以用户模式下irq异常为例__irq_usr —>irq_handler —>asm_do_IRQs3c24xx_init_irq -->set_irq_handler在s3c24xx_init_irqfor (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {irqdbf(“registering irq %d原创 2020-08-10 16:49:38 · 240 阅读 · 0 评论 -
嵌入式Linux驱动学习【1】——LED驱动
1概述Linux中外设可分为3类: 1)字符设备:按字节访问 2)块设备:以块形式存取,例如Nand flash以页为单位。 3)网络设备:数据流大小不固定。2 字符设备(1)设备号区分: 主设备号:标识与设备文件相连的驱动 次设备号:辨别操作哪个设备描述: dev_t:高12位为主设备号,低20位为次设备号 取主设备号:MAJOR(dev_t dev) 取次设备号:MINOR(dev_t dev)分配: 静态分配:Documentation/devices.原创 2020-08-10 09:39:48 · 278 阅读 · 0 评论 -
嵌入式Linux学习——构建根文件系统
1 内核启动 内核启动最后调用init_post(),如果从uboot中指定了的ramdisk_execute_command或execute_command,则执行对应的程序。否则,执行配置文件。若没有配置文件,则启动失败。 ramdisk_execute_command——对应“rdinit=…” execute_command——对应“init=…”static noinline int init_post(void) __releases(kernel_lock){ ...原创 2020-08-09 18:59:06 · 261 阅读 · 0 评论 -
Linux内核移植
1 环境 内核版本:linux-2.6.32.2.tar.gz 开发板:MINI24402 基本操作 解压:tar xvzf linux-2.6.32.2.tar.gz 打补丁:patch -pl < ../patch-x.y.z 配置:#(1)自己配置make menuconfig#(2)默认配置#在arch/arm/configs目录下找相似的,然后修改make xxx_defconfigmake menuconfig#(3)直接使用修改好的cp co原创 2020-08-09 11:52:37 · 188 阅读 · 0 评论 -
uboot移植-自己写BootLoader
1 概述 参考韦东山视频教程。 写一个最小的BootLoader,从nand flash或nor flash都能够启动内核。参考uboot源码两阶段的启动流程,自己写的uboot各阶段功能应该包括: 1)第一阶段:初始化,包括看门狗、时钟、SDRAM、nand flash等;为第二阶段准备RAM空间。 2)第二阶段:串口初始化,启动内核。2 第一阶段 文件:start.s#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01&l原创 2020-08-08 13:06:52 · 217 阅读 · 0 评论 -
uboot流程简单分析
1 配置过程 执行make smdk2410_config。 在uboot顶层目录的Makefile中看到smdk2410_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0 此时实际执行:./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0 这里执行mkconfig,最终会生成一些配置信息,并创建开发板相关的配置头文原创 2020-08-07 18:13:06 · 168 阅读 · 0 评论 -
构建嵌入式Linux系统初体验
1 启动过程 在PC上的启动流程为: BIOS–>windows系统–>C、D盘等–>应用程序。 在嵌入式linux中,与PC启动流程类似: BootLoader–>Linux内核–>根文件系统–>应用程序。 所以要构建一个嵌入式linux系统,需要烧录bootloader、Linux内核和根文件系统。 所用开发环境: 开发板:mini2440 虚拟机:ubuntu142 uboot1)解压文件tar xvzf u-boot-2010原创 2020-08-07 12:11:58 · 226 阅读 · 1 评论