我的时光,停在了你的角落…~
Posts tagged ARM
Linux指针函数追踪方法
Mar 3rd
以下方法适合于arm平台,其它平台类似。
查看指针函数实际调用了哪个函数:
1. 在内核中放置打印函数,打印出函数的地址。
2. arm-linux-addr2line 0xXXXXXXXX -e vmlinux -f
查看谁调用了这个函数:
1. 在被调用函数里放置打印函数,加参数:__builtin_return_address(0)
2. arm-linux-addr2line 0xXXXXXXXX -e vmlinux -f
C语言在arm应用中的具体操作
Jan 25th
0×20其实与(1<<5)是一个数,因为 1<<5表示1向左移5位,即为100000,这个数代表16进制的20.
所以在对arm芯片的引脚赋值或者输入输出操作时,一般用这种方式
GPGDAT &= ~(1<<5);
GPBCON = (1<<(5*2)); //其实就是指定GPB口的第5位,由于每个位都是由2个字节操作,所以才*2.
ADC0CN &= ~0×20是什么意思?
首先ADC0CN &= ~0×20是一个复合赋值表达式而不是语句。ADC0CN &= ~0×20;才是语句。
这个表达式等价于ADC0CN = ADC0CN & ~0×20。其中&是位与运算,~是按位取反运算。其中~的优先级最高,~0×20的结果是0xffffffdf,也就是二进制11111111111111111111111111011111(作为对比,0×20等于0×00000020,二进制表示为00000000000000000000000000100000)。&运算的结果是当且仅当两个运算数的对应二进制位为1时才为1,因此~0×20参与运算后只有~0×20中为0的这一个二进制位的对应位置设置为0,其它的合原来的ADC0CN一致。也就是ADC0CN & ~0×20的结果是ADC0CN的第5个二进制位(最低位为第0位)修改为0后得到的值。最后再把这个值赋给原来的ADC0CN。所以整个ADC0CN &= ~0×20的结果是把ADC0CN的第5个二进制位修改为0。
ARM体系的各种异常的分析
Jan 20th
1.复位异常
(1)当内核的nRESET信号被拉低时,ARM处理器放弃正在执行的指令,当nRESET信号再次变高时,ARM处理器进行复位操作;
(2)系统复位后,进入管理模式对系统进行初始化,复位后,只有PC(0×00000000)和CPSR(nzcvqIFt_SVC)的值是固定的,另外寄存器的值是随机的。
2.IRQ异常
(1)当CPSR中的相应的中断屏蔽被清除时,内核的nIRQ信号被拉低时可产生IRQ异常;
(2)由于ARM处理器的三级流水线结构,当异常发生时,PC的值等于当前执行指令的地址+8(即正确的中断返回地址+4),因此R14保存的值是 中断返回地址+4 ,所以当异常要返回时须执行以下指令:
SUBS PC,R14_irq,#4 ;PC=R14 – 4
注意:在SUB指令尾部有个S,并且PC是目标寄存器,所以程序返回时CPSR将自动从SPSR寄存器中恢复;
(3)将用户模式下的CPSR保存到SPSR_irq中;
(4)设置PC为IRQ异常处理程序的中断入口向量地址,在IRQ模式下该向量地址为0×00000018。
3.FIR异常
(1)当CPSR中的相应F位被清零时,内核的nFIR信号被拉低时可产生FIR异常,FIQ异常是优先级最高的中断;
(2)FIQ异常的进入和退出与IRQ异常类似;
(3)快速中断模式有8个专用的寄存器,可用来满足寄存器保护的需要,因此从其他模式进入FIQ模式时这些寄存器不用压栈了,提高程序运行的速度,且在中断入口地址的安排上,FIQ处于所有异常入口的最后,这是为了让用户可以从FIQ异常入口处(0x1c)就开始安排中断服务程序,而不需要再次跳转。
4.未定义指令异常
(1)当ARM在对一条未定义指令进行译码时,发现这是一条自己和系统内任何协处理器都无法执行的指令时,就会发生未定义指令异常;
(2)由于是在对未定义指令译码时发生异常,所以PC的值等于未定义指令的地址+4(即刚好为中断返回地址),因此R14保存的值是 中断返回地址 ,所以当异常要返回时可执行以下指令:
MOVS PC,R14_und
5.中止异常
中止表示当前存储器的访问不能完成,是由外部的ABOUT输入信号引起的异常,分为两类:
(1) 预取指中止:由程序存储器引起的中止异常;
(2) 数据中止:由数据存储器引起的中止异常;
5.1预取指中止异常
当程序发生预取指中止时,ARM内核将预取的指令标记为无效,但在指令到达流水线的执行阶段时才进入异常,因此当前PC的值为当前执行指令的地址+8(即正确的中断返回地址+4),因此R14保存的值是 中断返回地址+4 ,所以当修复了产生中止的原因后,不管在什么操作状态,处理器都会执行以下指令:
SUBS PC,R14_abt,#4 ;PC=R14 – 4
5.2数据中止异常
当发生数据中止异常时,异常会在“导致异常的指令”执行后的下一条指令时才发生,因此当前PC的值为“导致异常的指令”执行后的下一条指令的地址+8(即正确的中断返回地址+8),因此R14保存的值是 中断返回地址+8,所以当修复了产生中止的原因后,不管在什么操作状态,处理器都会执行以下指令:
SUBS PC,R14_abt,#8 ;PC=R14 – 8
注意:LPC2000系列ARM是基于ARM7TDMI内核的,不具有MMU,所以不应该发生中止异常,初学者时常会发生中止异常,大多数是因为编写的程序的问题。
6.SWI软件中断异常
(1)所有的任务都是运行在用户模式下的,因此任务只能读CPSR而不能写SPSR。任务切换到特权模式下唯一的途径就是使用一个SWI指令调用,SWI指令强迫处理器从用户模式切换到SVC管理模式,并且IRQ自动关闭,所以软件中断方式常被用于系统调用。
(2)系统调用的具体过程还是看有关uc/os-II等操作系统书,那里比较详细。
(3)SWI处理程序通过执行下面的指令返回:
MOVS PC,R14_svc
具体为什么偏移量为0,我现在也还没有搞懂,请看到的大虾多多指点,留个言,谢谢了!!!
经高手指点后明白了原来这么多异常的返回地址问题只要一句话:除了数据中止以外,所有异常发生时R14保存的值都是跳转时的PC-4,只是软件原因引起的异常时执行时(PC为该指令地址+8)就发生异常跳转了,而硬件引起的异常为了保证程序安全必须等到当前指令完成后(执行目标已经指向下一个指令,即PC为该指令地址+12)才会发生跳转。
from:21ic.com
ARM开发板如何挂载NFS开发环境的方法步骤
Sep 26th
首先介绍一下我的开发环境:
PC环境是Fedora 10,开发板为友善之臂的MINI2440
主机IP:192.168.50.72 网关:192.168.50.1 子网掩码:255.255.255.0
开发板IP:192.168.50.168 网关:192.168.50.1 子网掩码:255.255.255.0
为了能和主机建立起连接我必须得把开发板IP改成和主机一个网段的 .
这里首先要说明的是Fedora 10的静态IP设置问题:
默认安装完成后,右上角的网络配置上 wired ..和eth0为灰色。不能点选 。
然后禁用networdmanager启动network以太网设置静态IP的时候,不管怎么设置, 子网掩码都和网关一样,
比如说:地址:192.168.0.22
子网掩码: 192.168.0.1 //不管怎么输入255.255.255.0 ,都不行!
网关: 192.168.0.1 //这里改了255.255.255.0的话,上面就也成255.255.255.0了。(auto ethernet是可以联上网的)。所以就上GG找答案,找解决方法。
进入FC10,执行终端命令(也可以用VI修改)
$ su -c ‘gedit /etc/sysconfig/networking/devices/ifcfg-eth0′
直接修改文件中的子网掩码信息就可以
代码为:
# Broadcom Corporation NetXtreme BCM5752 Gigabit Ethernet PCI Express
DEVICE=eth0
HWADDR=00:16:e6:db:c2:96
ONBOOT=yes
BOOTPROTO=static //这个应该是“static”,而不是“dhcp”或“none”;
USERCTL=yes
PEERDNS=yes
IPV6INIT=no
NM_CONTROLLED=yes//这个应该是“yes”,如不修改,链接仍是disconnected;
TYPE=Ethernet
NETMASK=255.255.255.0
IPADDR=192.168.50.72
GATEWAY=192.168.50.1
然后重新激活下网卡就可以了.
#service network restart
设置完成后,右上角的网络配置上System eth0与auto ethernet就可以点选了.
需要说明的是因为我之前没有设置静态IP之前通过 NFS 启动系统启动不了.
连接主机和开发板
我选择了串口线和网线连接起了主机和开发板
连接好电源,串口线,网线,打开串口终端
配置minicom(在FC10终端输入命令minicom -s)
进入到minicom配置界面后选择 :Serial port setup
然后按照下面的设置下就OK了
A – Serial Device : :/dev/ttyS0
B – Lockfile Location : /var/lock
C – Callin Program :
D – Callout Program :
E – Bps/Par/Bits : 115200 8N1
F – Hardware Flow Control : No
G – Software Flow Control : No
建立和配置 NFS 服务
(1)设置共享目录
运行命令
#gedit /etc/exports
编辑 nfs 服务的配置文件(注意:第一次打开时该文件是空的),添加以下内容:
/opt/FriendlyARM/mini2440/root_qtopia *(rw,sync,no_root_squash)
其中:
/opt/FriendlyARM/mini2440/root_qtopia 表示 nfs 共享目录,它可以作为开发板的根文件系统通过 nfs 挂接;
* 表示所有的客户机都可以挂接此目录
rw 表示挂接此目录的客户机对该目录有读写的权力
no_root_squash 表示允许挂接此目录的客户机享有该主机的 root 身份
(2)通过命令启动和停止 nfs 服务
在命令行下运行:
#/etc/init.d/nfs restart
这将启动 nfs 服务,可以输入以下命令检验 nfs 该服务是否启动。
# mount -t nfs 192.168.50.72: /opt/FriendlyARM/mini2440/root_qtopia /mnt/
如 果 没 有 出 现 错 误 信 息 , 您 将 可 以 浏 览 到 /mnt 目 录 中 的 内 容 和
/opt/FriendlyARM/mini2440/root_qtopia 是一致的。
使用这个命令可以停止 nfs 服务:
#/etc/init.d/nfs stop
检查nfs服务器是否开启: #service nfs status
重启对应的2个服务: #service portmap restart
#service nfs restart
检查防火墙看是否屏蔽了nfs端口
#service iptables stop
#service iptables status
通过 NFS 启动系统
当 NFS 服务设置好并启动后,我们就可以把 NFS 作为根文件系统来启动开发板了。通过使用 NFS 作为根文件系统,开发板的“硬盘”就可以变得很大,因为您使用的是主机的硬盘,这是使用 linux 作为开发经常使用的方法,
设置目标板启动模式为 Nand Flash 启动,连接好电源,串口线,网线;打开串口终端,在开机或者复位的时候迅速按下 PC 机的空格键,这样我们就进入了 vivi 模式,输入以下命令:
Supervivi> param set linux_cmd_line “console=ttySAC0 root=/dev/nfs
nfsroot=192.168.50.72:/opt/FriendlyARM/mini2440/root_qtopia
ip=192.168.50.168:192.168.50.72:192.168.50.1:255.255.255.0:mini2440:eth0:off”
(1,如果通过minicom监控串口,如出现乱码,可将波特率调高点,我调的是115200 2,输入命令过长的话,发现minicom没法换行,其实也可以设置一下:同时按下CTRL+A 松开后按 W换行开关)
其中 ,param set linux_cmd_line 是设置启动 linux 时的命令参数。其各参数的含义如下:
nfsroot 后面是自己开发主机的 IP 地址。
“ip=”后面:
第一项(192.168.50.168)是目标板的临时 IP(注意不要和局域网内其他 IP 冲突);
第二项(192.168.50.72)是开发主机的 IP;
第三项(192.168.50.1)是目标板上网关(GW)的设置;
第四项(255.255.255.0)是子网掩码;
第五项是开发主机的名字(一般无关紧要,可随便填写)
eth0 是网卡设备的名称
然后输入 boot,按回车就可以通过 nfs 启动系统了。
在开发板上挂载NFS网络文件系统(Linux 中最常用的方法就是采用 NFS 来执行各种程序,这样可以不必花费很多时间下载程序,虽然在此下载 hello 程序用不了多久,一旦您的应用程序变得越来越大,您就会发现使用 NFS 运行的方便所在。)
通过NFS启动系统后,在开发板终端输入
[root@FriendlyARM /]# mount -t nfs -o nolock 192.168.50.72:/opt/FriendlyARM/mini2440/root_qtopia /mnt/
这里我刚开始遇到了一个问题,以为为什么开发板不能mount,因为提示如下错误信息: mount: mounting 192.168.50.72:/opt/FriendlyARM/mini2440/root_qtopia on /mnt/ failed: No such file or directory
于是我就ls看了一下,发现没有mnt文件夹,所以就自己创建了一个.再次mount就没有问题了.
[root@FriendlyARM /]# ls
bin etc home linuxrc proc sbin tmp var
dev hello lib opt root sys usr www
[root@FriendlyARM /]# mkdir mnt
[root@FriendlyARM /]# ls
bin hello linuxrc proc sys var
dev home mnt root tmp www
etc lib opt sbin usr
[root@FriendlyARM /]# mount -t nfs -o nolock 192.168.50.72:/opt/FriendlyARM/mini
2440/root_qtopia /mnt/
[root@FriendlyARM /]# cd /mnt/
[root@FriendlyARM /mnt]# ls
bin hello linuxrc proc sys var
dev home mnt root tmp www
etc lib opt sbin usr
mount成功后你进入到/mnt目录下就可以看到你主机root_nfs目录下的内容了.
至此我成功在ARM开发板上挂载NFS网络文件系统.

最新评论