自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(67)
  • 资源 (1)
  • 收藏
  • 关注

原创 LED入门

点亮一个LED灯一直是单片机或者嵌入式的一个入门程序了 不管是在哪来 只要一问 怎么入门嵌入式或者单片机 大家都会相看两不厌的回答:从点亮一个LED开始 在这里就主要的分析一下点亮一个led有多复杂最基本的硬件操作: 1.选择GPIO引脚 2.配置GPIO引脚为输出模式 3.让GPIO输出0/1点亮ledstm32单片机上点亮一个led的操作:#define LED_ON GP...

2018-04-16 19:06:56 1378

原创 gcc编译器

通常我们都是使用的是的vim+gcc编译 编译一个c文件的命令是 gcc hello.c -o hello 殊不知气质这个编译语句包括 预处理 编译 汇编 链接预处理主要的作用就是头文件的扩展 宏定义 条件编译等 打印出预处理后的结果 gcc -E hello.c gcc 在这里调用了 cpp(虽然通过 gcc -v 仅看到 cc1),cpp 即 The C Preprocessor,主

2017-11-15 14:27:22 387

原创 uboot和spl的区别

使用的是通用的同一份代码 前面的arch的初始化都是一样的 最主要的区别就是spl代码部分会用 CONFIG_SPL_BUILD来选择编译 以am335x而言,前期arch的初始化流程基本上是一致的,出现本质区别的是在board_init_f开始的。 spl中board_init_f是自己实现的 使用CONFIG_SPL_BUILD选择编译的 主要是做ddr pinmx之类的初始化 d:

2017-11-15 14:26:20 3183

原创 uboot中命令行模式以及命令处理

AM335X中的宏定义 1、需要打开哪些宏 CONFIG_CMDLINE 表示是否支持命令行模式,定义如下: configs/am335x_evm_defconfig :CONFIG_CMDLINE=y CONFIG_SYS_GENERIC_BOARD 用于定义板子为通用类型的板子。打开这个宏之后,common/board_f.c和common/board_r.c才会被编译进去,否则

2017-11-15 14:25:40 4823 1

原创 cache的工作方式

带有cache的CPU一般是先从cache中取出数据 而不是从内存里取数据而CPU是怎么访问cache的cache访问cache使用的类似的地址编码方式。处理器访问存储器时 会把地址传递给TLB和cache cpu把虚拟地址 页帧号传递给TLB 行索引(index)传递给cache匹配到相关的cache line TLB里是一个用于存储虚拟地址到物理地址转换的小缓存 处理器先使用EPN在

2017-11-15 14:22:52 4927

原创 am335x uboot参数 说明

1、U-Boot启动参数解析: 进入U-Boot命令行使用printenv命令可以看到U-Boot启动参数,如使用默认参数,类似如下: 默认的U-boot启动参数设置的启动顺序为: (1) SD卡启动脚本 (2) SD卡 (3) EMMC 若检测到 SD 卡已插入,则加载 SD 卡 boot 分区中的 zImage 内核镜像和 rootfs 分区文件系统。 若没有检测到 SD 卡插入

2017-11-15 14:20:21 3381

原创 armv7A 架构的页表

当cpu访问cache时 会发送虚拟地址到TLB上 TLB是一个TLB 是一块高速缓存,用于缓存页表转换的结果,从而 减少内存访问的时间。一个完整的页表翻译和查找的过程叫作页表查询(Translation table walk),页表查询的过程由硬件自动完成,但是页表的维护需要软件来完成。页表查询是一 个相对耗时的过程,理想的状态下是TLB 里存有页表相关信息。当TLB Miss 时,才会去

2017-11-15 14:17:10 5702 1

原创 CP15协处理器详解以及操作

我相信对很多驱动工程师而言 对于bootloader这部分还是有很多研究的 但是我相信大部分的工程师都是简要的看下bootloader的初始化流程 对于一些具体的操作还是不懂 比如cp15协处理的操作 而且大部分的博客都也是简单的详细的介绍下这句话实现了什么功能 而并不懂这行代码是怎么操作的 比如这里的CP15协处理器的操作在arch/arm/cpu/armv7/Start.S 对于uboot一

2017-11-15 14:12:29 4441

原创 内核定时器

内核的软中断提供了定时器软中断的类型 TIMER_SOFTIRQ 所以我们可以使用这个软中断来实现定时运行我们的程序 内核提供的API和数据结构如下 struct timer_list { /* * All fields that change during normal runtime grouped to the * same cacheline

2017-11-15 14:10:31 253

原创 编译乱序和执行乱序

编译乱序也就是编译器对访存的执行进行乱序 减少逻辑上不必要的访存 已经尽量提高cache命中率和cpu的load/store单元的工作效率 因此在打开编译器优化以后 看到生成的汇编码并没有严格按照代码的逻辑顺序 怎么解决这个问题 设置编译屏障 barrier(); 这样的话就能解决编译乱序所造成的问题 那么你可能会说 volatile也可以实现这个功能啊 其实在编译乱序的问题上 volatil

2017-11-15 14:09:47 1701

原创 原子变量

原子变量适用在共享资源是一个简单的整数值的情况下使用的 完整的锁机制对一个简单的整数来讲就有些浪费 数据定义 atomic_t v; 原子变量保存一个int值 但是不能记录大于24位的整数 使用的是ldrex和strex指令 适用于多核间的并发具体的API如下 void atomic_set(atomic_t *v, int i); atomic_t v = ATOMIC_INIT(

2017-11-14 20:48:12 2921

原创 自旋锁

自旋锁主要是为了解决对临界资源的互斥访问 也就是适合在smp或者单cpu可抢占的系统中比如在SMP 多核处理器中的情况 现在的处理器大多是这种类型的 可以使用自旋锁来解决对临界资源互斥访问 当一个CPU在访问自旋锁保护的临界区时 临界区锁被锁上 也就是spin_lock(lock) 将自旋锁置0 这时其他访问此临界区的CPU 或者本地CPU的其他进程想要访问此临界区时会忙等待 直到第一个访

2017-11-14 20:47:51 390

原创 线程间同步机制之完成量

完成量主要是用来完成线程间的同步机制 而信号量是为了完成某一资源临界区的同步而使用struct completion { unsigned int done; wait_queue_head_t wait; };这个结构体有两个成语 一个是done 表示已完成 一般初始化为0 还有一个是等待队列 表示一个完成量未唤醒的时候 加入等待队列 struct completion

2017-11-14 20:47:04 386

原创 mutex互斥体

linux内核也有正宗的互斥体 并且新的内核多使用mutex互斥体我们这里只介绍怎么使用互斥体定义一个互斥体并且初始化它 struct mutex my_mutex; mutex_init(&my_mutex);然后获取互斥体 extern void mutex_lock(struct mutex *lock); extern int __must_check mutex_lock_int

2017-11-14 20:46:28 398

原创 信号量

linux上有很多地方可能导致并发竞态的现象 比如smp多核的时候 不同的处理器上同时执行我们的代码 多个用户进程也能在一起访问我们的代码 还要很多可延迟机制 比如workqueue tasklet以及timer都可能会使得代码在任何时候执行 所以就会导致并发执行代码 访问公共资源导致出现很多问题 对这个问题最明显的应用就是避免使用全局变量 所以为了只能让一个操作在一个时间内只能有一个执行线

2017-11-14 20:45:57 288

转载 中断管理之下半部软中断

Linux中断管理中有个非常重要的设计理念就是上下半部机制 上半部就是硬件中断管理 中断设计为上下半部的原因如下 1.硬件中断处理程序以异步方式进行 它会打断其他重要的代码执行 因此为了避免被打断的程序停止时间太长 硬件中断处理程序必须尽快完成 2.硬件中断处理程序通常在关闭中断的情况下执行 关闭中断就是关闭本CPU的所有中断响应 关闭中断后 本地CPU就不能响应所有的中断响应 因此硬件中断处

2017-11-14 20:32:17 294

转载 中断上下文简要概述

中断上下文主要是硬件中断上下文 软件中断上下文 和 BH临界区上下文中断上下文你主要分为以下两种情况 (1)执行该中断的处理函数(我们一般称之interrupt handler或者叫做top half),也就是hard interrupt context (2)执行软中断处理函数,执行tasklet函数,执行timer callback函数。(或者统称bottom half),也就是softwa

2017-11-14 20:30:52 884

原创 创建进程

进程:处于执行期的程序 相当于“进程=程序+执行” 但是进程不局限于一段可执行代码(代码段) 还包括进程需要的其他资源 例如打开的文件 挂起的信号量 内存管理 处理器状态 一个或者多个线程 数据段之类的 进程控制块就是task_struct进程和线程的区别 :线程是操作系统调度的最小单位 进程拥有独立的资源空间而线程则共享进程的资源空间 但是linux内核并没有特别的调度算法或定义特别的数据结构来标

2017-11-14 20:22:46 273

原创 软中断机制之tasklet机制

tasklet也是利用软中断实现的一种下半部机制 软中断的一种变种 运行在软中断上下文中 struct tasklet_struct { struct tasklet_struct *next;//多个tasklet串成一个链表 unsigned long state;//代表此刻tasklet的状态,一般为TASKLET_STATE_SCHED,表示此tasklet已被调

2017-11-14 20:18:44 563

原创 workqueue机制

workqueue和其他的bottom half最大的不同是它是运行在进程上下文中的,它可以睡眠,这和其他bottom half机制有本质的不同,大大方便了驱动工程师撰写中断处理代码。当然,驱动模块也可以自己创建一个kernel thread来解决defering work,但是,如果每个driver都创建自己的kernel thread,那么内核线程数量过多,这会影响整体的性能。因此,最好的方法就

2017-11-14 20:18:08 5352

原创 TI-RTOS-SPI深度解析

开发板:AM335X编译环境:cssqq:956465349gdut15级本科最近在移植rtos的spi-loopback的测试程序到am335x开发板上 顺便把相关的操作函数源码给分析了下 移植的是pdk_am335x_1_0_5\packages\ti\drv\spi\example\mcspiLoopbackApp的测试程序 spi的基础知识可以看我觉得不错的博客 http://b

2017-08-10 16:10:06 3853

原创 usb驱动之设备驱动

这里所说的设备驱动是指从主机角度来看,怎么访问被插入的USB设备,而不是指USB设备内部本身运行的固件程序。USB 设备内的固件称为“设备用户固件” , “设备用户固件”完成设备内部的控制任务,并在 USB 传输中对接收到的设备请求做出解释并予以正确响应。 Linux 系统实现了几类通用的 USB 设备驱动,划分为如下几个设备类。 音频设备类。 通信设备类。 HID(人机接口)设备类。 显

2017-07-31 14:38:49 662

原创 USB驱动之主机控制器驱动

USB 主机驱动的整体结构: USB 主机控制器有 34种规格:OHCI (Open Host Controller Interface)、UHCI(Universal Host ControllerInterface) 和 EHCI (Enhanced Host Controller Interface)。OHCI 驱动程序用来为非 PC 系统上以及带有 SiS 和 ALi 芯片组的 PC 主板

2017-07-31 14:11:55 1602

原创 USB驱动之基础的概念和数据结构

liunx usb 驱动层次 linux系统中 可以从两个角度看usb 分别是是主机侧和设备侧视角 主机侧大致如下 …………………………………….. usb设备驱动 mass storage/CDC/HID …………………………………….. USB核心 …………………………………….. USB主机控制器驱动OHCI/EHCI/UHCI …………………………………….. USB主

2017-07-28 10:45:40 388

原创 uboot启动第二阶段之x-load分析

开发板:DM3730虚拟机:ubuntu 14.04编译器:arm-none-linux-gnueabix-loader:这几天小小的研究了一下linux的启动机制 所里这里做个小小的总结吧现在一般的芯片的linux启动机制是这样的 上电自运行ROMCODE也就是在rom里固化的代码 ROMCODE启动后会根据SYS_BOOT[5:0]的值来去选择从nand,nor,mmc,usb,uar

2017-07-28 09:46:01 1770

原创 dm3730之支持Peripheral 启动系统

开发板:DM3730虚拟机:ubuntu 14.04编译器:arm-none-linux-gnueabiuboot:U-Boot 2010.06-00166-gbf92a97开发板内核:Linux-2.6.37文件系统:ext3一般芯片的启动机制都在芯片手册上有讲解 比如我这款a8的dm3730的启动机制大致如下 romcode->x-load(MLO)->u-boot.bin->uIm

2017-07-27 16:21:11 814 1

转载 uboot命令之bootm详解

开发板:DM3730 cortex-a8虚拟机:ubuntu 14.04编译器:gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf开发板内核:linux 4.4.12bootm 用于将内核镜像加载到内存的指定地址处,如果有需要还要解压镜像,然后根据操作系统和体系结构的不同给内核传递不同的启动参数,最后启动内核。 一、arm 架构处理器对 lin

2017-07-25 16:18:49 18649

原创 armlinux开发板用户自动登录

开发板:AM335虚拟机:ubuntu 14.04编译器:gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf开发板内核:linux 4.4.12设置开发板自动登录目前而言就两种方法 1.修改/etc/inittab文件 2.systemd方法 1.要是文件系统有/etc/inittab文件的话就可以修改/etc/inittab文件 找到如下

2017-07-13 15:14:51 2914

原创 arm-linux之为开发板写上电自启动程序之方法

开发环境开发板:AM335虚拟机:ubuntu 14.04编译器:gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf开发板内核:linux 4.4.12首先开发板的文件使用的是systemd 并没有/etc/rc.local文件 所以要想修改rc.local这一简单的操作已经不存在 但是也是可以用systemd和initd两种方式解决这个问题

2017-07-13 09:58:20 6574 1

原创 常见linux驱动面试题

1、驱动中操作物理绝对地址为什么要先ioremap? 因为在内核中操作的都是虚拟地址,内核访问不到物理地址,只能通过ioremap映射为虚拟地址 内核才能访问此内存空间2、设备驱动模型三个重要成员是?platform总线的匹配规则是?在具体应用上要不要先注册驱动再注册设备?有先后顺序没? 设备驱动模型的三个重要成员是总线,驱动,设备。 platfoem总线的匹配规则是:要匹配的设备和驱动都要注

2017-07-12 14:36:07 7086

转载 关于char, wchar_t, TCHAR, _T(),L,宏 _T、TEXT,_TEXT、L

char :单字节变量类型,最多表示256个字符,wchar_t :宽字节变量类型,用于表示Unicode字符,它实际定义在 wchar_t c = `A' ;wchar_t * p = L"Hello!" ;wchar_t a[] = L"Hello!" ;其中,宽字节类型每个变量占用2个字节,故上述数组a的sizeof(a) = 14TCHAR / _T( ) : 如果在程序中既包括

2017-06-30 03:19:04 259

转载 不容错过:Linux定时器的使用

用定时器的目的无非是为了周期性的执行某一任务,或者是到了一个指定时间去执行某一个任务。要达到这一目的,一般有两个常见的比较有效的方法。一个是用 linux内部的三个定时器,另一个是用sleep, usleep函数让进程睡眠一段时间,使用alarm定时发出一个信号,还有那就是用gettimeofday, difftime等自己来计算时间间隔,然后时间到了就执行某一任务,但是这种方法效率低,所以不常用。

2017-06-30 03:16:08 524

转载 POSIX定时器:timer_settime()

最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:timer_create()(创建定时器)、timer_settime()(初始化定时器)以及timer_delete(销毁它)。创建一个定时器:int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)进

2017-06-30 03:13:59 603

转载 C语言结构体的字节对齐原则

为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开

2017-06-30 03:10:24 706

转载 Linux网络编程入门

(一)Linux网络编程–网络知识介绍Linux网络编程–网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的–客户端和服务器端.客户端 在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序。 比如我们使用ftp程序从另外一个地方获取文件的时候,是我们的ftp程序主动同外面进行通信(获取文件)

2017-06-30 03:01:00 6628

转载 C语言,获得堆栈增长方向的一种方法

static int stack_dir; static void find_stack_direction (){ static char *addr = NULL; auto char dummy; if (addr == NULL) { addr = &dummy; find_stack_direction(); }

2017-06-29 15:52:36 691

原创 Linux设备驱动模型之platform总线深入浅出(加入设备树)

在Linux2.6以后的设备驱动模型中,需关心总线,设备和驱动这三种实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成。 对于依附在USB、PCI、I2C、SPI等物理总线来 这些都不是问题。但是在嵌入式系统里面,在Soc系统中集成的独立外设控制器,挂接在Soc内存空间的外设等却不依附在此类总线。基

2017-06-25 17:03:37 9807 1

原创 嵌入式中断(stm32+linux)详解

一开始学单片机时 就知道中断这一个概念 看些视频学了大半天 也是似懂非懂 看代码也就是设置下寄存器写下中断服务程序而已 学的不是很深入 一直到现在 经过了<微机原理>这门课的学习 才对中断有了一定的深入了解 发现中断也就是一门说复杂也能很复杂 只要封装好了api 使用也很简单的事 但是身为一名学习者 还是有必要学习中断的使用和原理身为一个学习嵌入式的小白 一开始我学习的当然是单片机 所学的单片机是

2017-06-22 16:37:19 4807

原创 Linux0.01内核三之轮转到子进程执行

#define switch_to(n) {\struct {long a,b;} __tmp; \__asm__("cmpl %%ecx,_current\n\t" \ "je 1f\n\t" \ "movw %%dx,%1\n\t" \ "xchgl %%ecx,_current\n\t" \ "ljmp %0\n\t" \ "cmpl %%ecx,_

2017-06-19 16:38:20 410

转载 Linux驱动程序之阻塞和非阻塞IO

所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回。也就是说在执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作。被挂起的进程进入睡眠状态,被从调度器的运行队列移走,直到等待的条件被满足 所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯

2017-06-08 08:51:47 818

u-boot-1.1.6

2016-03-28

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除