my嵌入式学习笔记

 

开发环境 linux

Realview mdk  ARM开发工具

Eclipse  java开发工具

Android sdk  安卓软件开发工具

H-JTAG     烧写工具

嵌入式开发环境的搭建:

       命令行:

       1,sudo apt-get install build-essential    基本的开发环境

       2,sudo apt-get install bison flex        安装bison,flex分别是语法,词法分析器

       3,sudo apt-get install manpages-dev              安装c函数库的man手册

   http://www.kernel.org/

   http://www.arm.linux.org.uk/

   http://gcc.gnu.org/

 http://sourceware.org/gdb/download/

 http://www.busybox.net/

 http://www.linux-mtd.infradead.org/index.html

       Makefile文件: 编译规则

       安装交叉编译器:

       toolchains_for_s3c2410.tar.bz2

       基于gcc和glibc来制作工具链,可使用crosstool来进行编译

       基于gcc和uClibc来制作工具链,可以使用bulidroot来进行编译

gcc编译成共享库:

       gcc –shared –fpic –o libtest.so libtest.c

      cp libtest.so /lib 

-fpic产生位置无关的代码(pic)

Arm-linux交叉编译工具链介绍

       1,arm-linux-gnu-gcc –O2 –c –o crt0.o crt0.s  将汇编文件编译成目标文件

       2,arm-linux-gnu-gcc –O2 –c –o led.o led.c    将.c文件编译成.o文件

       3,arm-linux-gnu-gcc-ld –Ttext 0x00000000 –O2 crt0.o led.o –o led-elf  将.o文件链接成为lef文件,-Ttext 0x00000000 指定当前运行地址

       4,arm-linux-gun-objcopy –O binary –S led-lef led.bin  将elf文件转换成.bin文件

   5,arm-linux-gnu-objdump –D –m arm led_elf > len.dis     将led_elf反汇编成为.dis文件

注意:cc1命令路径在/usr/lib/gcc/i486-linux-gnu/4.1.2/cc1

size :列出目标文件每一段的大小以及总体的大小。

readelf :显示elf格式的可执行文件的信息

strip :丢弃目标文件中的全部或者特定的符号,减少文件体积。

nm  :列出目标文件的符号。

objcopy :文件格式转换。

objdump :显示一个或者更多目标文件的信息,主要用来反编译。

编译内核:

                    make zImage 

                    make bzImage

                    编译好的内核位于:arch/<cpu>/boot/目录下

编译内核模块:

                    Make modules

                    Make modules__install

清除临时文件、中间文件和配置文件:

             make clean (保留config文件)

             make mrproper

          make  distclean(取消与体系结构的链接)

内核配置:make config :基于文本模式的交互式配置

                    make menuconfig :基于文本模式的菜单型配置。

                    Make modules_install

u-boot移植与编译

u-boot从tftp服务器下载zImage/uImage 应该设置参数为:

setevn bootcmd tftp 30800000 zImage\;go 30800000  

setevn bootcmd tftp 30800000 uImage\;bootm

 

setenv serverip 192.168.7.X   设置主机ip

setenv ipaddr x 192.168.7.Y   设置目标板ip

saveenv    保存环境变量

内核烧写:

tftp 30008000 zImage.2.6.35(将zImage 下载到0x30008000)

nand erase 40000 200000

nand read addr off size :从nandflash偏移地址off处的size个字节数据存放在开始地址为addr的内存中。

nand write addr off size :把开始地址为addr的内存中的size个字节数据写到flash的偏移地址off处。

例如:nand write 30008000 40000 200000

文件系统烧写

tftp 30008000 rootfs.cramfs

nand erase 240000 800000(文件大小)

nand write 30008000 240000(起始地址) 800000

 

按键驱动led灯亮: (平台基于fs2410开发板,arm920t,s3c2410)

       必须对硬件相关的信息要很熟悉,知道它是怎么去控制电路的信息。然后从软件方面去分析。GPIO编程,GPG3 设为input模式 ,GPE11设为output模式,

GPE11引脚output = 0状态,设GPG3引脚状态。

GPIO至少有两个寄存器:即GPIO控制寄存器,GPIO数据寄存器。

GPxCON: 选择引脚的功能。因为大多数的引脚都复用。

GPxDAT: 读写引脚数据。即若引脚被配置为输出模式,写此寄存器相应位可另此引脚输出高电平或低电平;若引脚被设置为输入模式,读此寄存器可知相应的电平状态是高还是低)

GPxUP :  确定是否使用内部上拉

 

用c语言写驱动,须有启动代码:禁看watchdog,初始化堆栈(ldr sp,=4096,因为代码一般是烧写到nandflash内,容量是4KB,ARM中的栈是满递减堆栈,sp须初始),设置跳转到main函数。

 

嵌入式系统相关存储器:

寄存器(37个包括31个通用寄存器,6个状态寄存器): 读写数据最快,但是数量有限。

SRAM(4KB):0x40000000~0x40001000

SDRAM(64MB):0x30000000   它是栅列形式,行地址线13根,列地址线9根,ADDR25和ADDR24。所以64MB = 213+9+2 *  32/8  32为数据线。

Norflash(2MB):又22根地址总线(其中2根为NC状态),16根数据总线,所以2M = 222-2 * 2。特点是芯片内执行(XIP,Execute In Place),jffs2文件系统。

Nandflash(64MB): 没有相关的地址总线,不能够寻址。当程序烧写到Nandflash中,它自动读取4KB数据到SRAM,若数据大于4KB时,首先拷贝4KB到SRAM中(包括一些copysdram程序),由它完成将剩下数据拷贝到SDRAM,yaffs文件系统。

Nandflash一页分为A、B、C三个区:A区位0~255字节,B区为256~511字节,C为512~527字节。命令00h让地址指针指向A区,命令01h让地址指针指向B区,命令50h让地址指针指向C区。

       1 block = 32 page,  1 page = 512 byte (main area)+ 16 byte(spare area,存放校验的数据);Nandflsh (k9f1028)有4096 block。 528MB = 4096 * 32 * 512 byte。Nandflash 以页为单位读写数据,以块为单位擦除数据。

       命令、地址、数据都通过8个I/O口输入/输出。写入数据、命令、地址时,都需要将WE#、CE#信号拉低。数据在WE#信号的上升沿被锁存,命令锁存使能CLE,地址锁存使能ALE信号,用来分辨、锁存命令或地址。

Flash存储器件的可靠性因素:位反转,坏块,可擦除次数。

 

存储控制器

它对外引出27根地址线(ADDR0-ADDR26,227  = 128MB),对外又引出8根片选信号线(nGCS0 – nGCS7,分别对应于BANK0 – BANK7)。当访问BANKx地址空间时,nGCSx输出低电平来选择外接设备。

128MB * 8 = 1GB。8表示bank区域的个数,每个bank的容量为128MB。

注意:S3C2400使用2片16位的SDRAM芯片并联成32位的带宽,与CPU

的32跟数据线相连。

存储控制器共有13个寄存器:

BWSCON (位宽等待), BANKCON0 – BANKCON5,BANKCON6,BANKCON7,REFRESH,BANKSIZE,MRSR6 – MRSR7

 

ARM体系异常/中断

ARM指令集:ARM,Thumb,Jazelle指令集。

       ARM体系的CPU的七种工作模式:用户模式,fir模式(快速中断请求处理),irq模式(中断请求处理),svc模式(保护模式),abt模式(虚拟内存或存储器保护),sys模式,und模式。

       特权模式 : 处理中断、异常或者访问被保护的系统资源。

       中断是指cpu在正常执行程序的过程中,遇到外部或内部的紧急事件需要处理,暂时中断当前程序的执行,转去为事件服务,待事件处理完毕,再返回继续执行原有的程序。

注意:中断或异常时,需保存现场,即cpsr->spsr_mode,pc->lr 。异常/中断处理结束时,spsr->cpsr ,lr->pc。

异常向量表:

复位异常(0x00~0xffff0000),主要功能:设置异常中断向量表,初始化堆栈和寄存器,初始化存储系统,改变处理器模式或状态,使能中断等。

未定义指令异常(0x04)

软中断(swi,0x08):处理器处于特权模式(supervisor)。

预取指令异常(0x0c) 若系统中不包含MMU时,指令预取异常中断只是简单的报告异常错误并退出;若包含MMU,则引起异常的指令的物理地址被存储到内存中。

数据访问终止异常(0x10):返回地址寄存器r14的值只与发生数据异常的指令地址有关,与pc值无关。

注意:0x14 为保留地址

外部中断异常(0x18)

快速中断异常(0x1c)

vector table 的入口是一些跳转指令,跳转到专门处理某个异常或中断的子程序。

 

ARM异常的优先级:

从高到低依次是:复位异常,数据终止,快速中断请求,外部中断请求,预取指令异常,swi,未定义指令(swi和未定义异常享有相同的优先级。但不能同时发生)

 

中断响应:保护断点,即保存下一将要执行的指令的地址,也就是压栈保存地址;寻找中断入口;执行中断处理程序;中断返回。

本人个人理解:保护现场(寄存器压栈:stmfd sp!,{r0-r3,r12,lr}),恢复现场(恢复寄存器:ldmfd sp!,{r0-r3,r12,lr})。

恢复现场指令如下:

                                  movs pc,lr

                 subs pc,lr,#4

                                  ldmfd sp!,{pc}!

异常和返回地址:

三级流水线:

取指   译码   执行

PC     PC-4  PC-8

五级流水线:

取指   译码   执行  防存(Memory)  回写(write)       

注意:PC指向正被读取的指令,而非正在执行的指令。

ARM哈佛架构,实现对指令和数据存储器的同时访问。

 

UART串口通信

发送数据时,cpu先将数据写入发到FIFO中,然后URTA会自动将FIFO中的数据复制到发送移位器(Transmit Shifter)中,发送移位器将数据一位一位地发送到TxDn数据线上(添加上开始位,校验位和停止位)。

接受数据时,接受移位器(Receive Shifter)将RxDn数据线上的数据一位一位接受进来,然后复制到接受FIFO中,cpu可从中读取数据。

IPC通信机制

信号量

Semget(key_t key,int num_sems,int sem_flags):创建信号量或取得一个已有的信号量的键。

Semop(int sem_id,struct sembuf *semops,size_t num_sem_opt):改变信号量的值。

Struct sembuf{

       short sem_num;    信号量的编号

       short sem_op;     0 等待;1释放资源;-1 分配资源

       short sem_flag;   常被设置为SEM_UNDO

}

Semctl(int semid,int semnum,int cmd,...):用来直接控制信号量的值。

eg :semctl(sem_id,0,SETVAL,sem_union)

command: GETVAL: 获取信号量的值

          SETVAL:设置信号量的值

          IPC_RMID: 删除信号量。

 

共享内存

Shmget(key_t key,size_t size,int shmflg): 创建共享内存

Shmat(int shm_id,const void *shmaddr,int shmflg):建立映射

Shmdt(const void *shmaddr) :  解除映射

Shmctl(int shmid,int cmd,struct shmid_ds *buf) 控制内存映射

 

       CMD: IPC_STAT(获取对象属性)

            IPC_SET(设置对象属性)

            IPC_PRIM(删除对象)

Buf:用来指定IPC_STAT/IPC_SET时用以保存/设置属性。

 

消息队列

Msgctl() 控制消息队列

Msgget() 创建和访问一个消息队列

Msgrcv() 从消息队列中获取信息

Msgsnd() 向消息队列中添加信息

 

linux kernel(linux 内核)

GPL(GNU General Public License) 通用公共许可证

内核的模块化,主要由文件系统模块,进程调度/控制模块,进程间通信模块,内存管理模块,网络接口模块等:

 

       内核编译:

       内核配置、裁剪、编译:make menuconfig  make uImage。

内核系统最关键的组成元素是各个目录下的Kconfig和Makefile文件。

进程由可执行的指令代码,数据和堆栈区组成。

分时技术:把cpu的运行时间划分成一个个规定长度的时间片,让每个进程在一个时间片内运行。当进程的时间片用完时系统就调度程序切换到另一个进程去运行。

Linux系统中,进程可以在内核态或用户态下执行,因此linux系统的内核堆栈和用户堆栈是分开的。

task_struct 任务数据结构

内核通过进程表来管理进程,每个进程在进程表中占有一项。PCB(process control block)进程控制块

 

进程上下文:一个进程在执行时,cpu的所有寄存器中值、进程的状态、堆栈中的内容。进程切换时,须保存当前进程的上下文。

 

内核的初始化:

 

init进程:

 

文件系统:

 

内存管理机制:控制多个进程安全地共享内存。

 

Linux内存管理采用页式管理,通过伙伴算法管理和分配页。

内存映射,将cpu的虚拟地址空间映射到系统的物理内存。通常由MMU来完成。

X86地址空间:物理地址空间,逻辑地址空间,线性地址空间。

逻辑地址是cpu所能处理的地址空间的总和,对32位cpu来说,它的逻辑地址空间是4GB = 232byte。

进程线性地址被分为:页目录索引,页表索引和偏移量。Page directory是一个指向页表的指针数组,page table 是一个指向页面的指针数组。因此地址映射就是一个跟踪指针链的过程。一个页目录能够确定一个页表,继而得到一个页面,然而页面中的偏移量(offset)能够指出该页面的地址。

内存区域zone,由一个自己的伙伴系统来管理。

      

TLB(Translation Lookaside Buffer)转换旁视缓冲区/页表缓冲,它负责将虚拟地址翻译成为实际的物理内存地址,cpu寻址时会优先在TLB中寻址。

 

ARM虚拟地址转换为物理地址:以段的方式进行转换时只用到一级页表;以页的方式进行的转换时要用到两级页表。

 

条目也称为“描述符”:段描述符,大页/小页/极小页描述符,它们保存了相应的起始物理地址。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值