20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告 20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告

20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告
20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告

一、设计方案及可行性分析

  1. 熟悉 Linux 开发环境
  2. 多线程应用程序设计
  3. 串行端口程序设计
  4. 中断实验

二、详细设计思路

1. 熟悉 Linux 开发环境

1)建立工作目录

  • 在终端输入代码建立工作目录
    [root@zxt smile]# mkdir hello
    [root@zxt smile]# cd hello

2)编写程序源代码

  • 在终端输入
    [root@zxt hello]# vi hello.c

  • 打开hello.c,编写实验代码

    #include <stdio.h>

       main()
    
       {
    
            printf(“hello world 
    ”);
    
       }
    
  • 按Esc键后,输入:wq保存代码并退出。

3)编写 Makefile

  • 为了让 hello.c 程序能够运行,我们需要编写一个 Makefile 文件,Makefile文件定义了一系列的规则,它指明了哪些文件需要编译,哪些文件需要先编译,哪些文件需要重新编译等等更为复杂的命令。

  • 编写Makefile文件,在终端输入
    [root@zxt hello]# vi Makefile

  • Makefile文件打开,按i键进入输入状态编写Makefile文件

        CC= armv4l-unknown-linux-gcc       
              EXEC = hello
              OBJS = hello.o
              CFLAGS +=
              LDFLAGS+= –static
              all: $(EXEC)
              $(EXEC): $(OBJS)
              $(CC) $(LDFLAGS) -o $@ $(OBJS)
              clean:
              -rm -f $(EXEC) *.elf *.gdb *.o
    

4)编译应用程序

  • Makefile文件编写完成后,需要在 hello.c的文件目录下运行“make”来编译我们的程序了。如果进行了修改,重新编译则运行:
    [root@zxt hello]# make clean
    [root@zxt hello]# make

5)下载调试

  • 在本地PC 机上启动 NFS 服务,并设置好共享目录。在建立好 NFS 共享目录以后,我们就可以进入 MINICOM 中建立开发板与本地PC 机之间的通讯。
    [root@zxt hello]# minicom
    [/mnt/yaffs] mount -t nfs -o nolock 本地PC机IP地址:/arm2410cl /host
  • 如果不想使用我们提供的源码的话,可以再建立一个 NFS 共享文件夹。如/root/share,我们把我们自己编译生成的可执行文件复制到该文件夹下,并通过 MINICOM 挂载到开发板上。
    [root@zxt hello]# cp hello /root/share
    [root@zxt hello]# minicom
    [/mnt/yaffs] mount -t nfs -o nolock 192.168.0.56:/root/share /host
  • 再进入/host 目录运行刚刚编译好的 hello 程序,查看运行结果。
    [/mnt/yaffs] cd /host
    [/host] ./hello
    hello world

2.多线程应用程序设计

1)实验源代码与结构流程图

  • 本实验为著名的生产者-消费者问题模型的实现,主程序中分别启动生产者线程和消费者线程。生产者线程不断顺序地将 0 到 1000 的数字写入共享的循环缓冲区,同时消费者线程不断地从共享的循环缓冲区读取数据。流程图如图所示:
    20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告
20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告
    本实验具体代码见四

2)主要函数分析:

  • 下面我们来看一下,生产者写入缓冲区和消费者从缓冲区读数的具体流程,生产者首先要获得互斥锁,并且判断写指针+1 后是否等于读指针,如果相等则进入等待状态,等候条件变量 notfull;如果不等则向缓冲区中写一个整数,并且设置条件变量为 notempty,最后释放互斥锁。消费者线程与生产者线程类似,这里就不再过多介绍了。流程图如下:
    20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告
20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告

3)阅读源代及译应用编程序

  • 进入 exp/basic/02_pthread 目录,使用 vi 编辑器或其他编辑器阅读理解源代码。运行 make 产生 pthread 可执行文件。

4)下载和调试

  • 切换到 minicom 终端窗口,使用 NFS mount 开发主机的/arm2410cl 到/host 目录。
    进入/host/exp/basic/pthread 目录,运行 pthread,观察运行结果的正确性。运行程序最后一部分结果如下:

      wait for not empty
      put-->994
      put-->995
      put-->996
      put-->997
      put-->998
      put-->999
      producer stopped!
      993-->get
      994-->get
      995-->get
      996-->get
      997-->get
      998-->get
      999-->get
      consumer stopped!
      [/host/exp/basic/02_pthread]
    

3.串行端口程序设计

1)原理

异步串行

  • I /O 方式是将传输数据的每个字符一位接一位(例如先低位、后高位)地传送。数据的各不同位可以分时使用同一传输通道,因此串行 I/O 可以减少信号连线,最少用一对线即可进行。接收方对于同一根线上一连串的数字信号,首先要分割成位,再按位组成字符。为了恢复发送的信息,双方必须协调工作。在微型计算机中大量使用异步串行 I/O方式,双方使用各自的时钟信号,而且允许时钟频率有一定误差,因此实现较容易。但是由于每个字符都要独立确定起始和结束(即每个字符都要重新同步),字符和字符间还可能有长度不定的空闲时间,因此效率较低。
    20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告
20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告

  • 图中给出异步串行通信中一个字符的传送格式。开始前,线路处于空闲状态,送出连续“1”。传送开始时首先发一个“0”作为起始位,然后出现在通信线上的是字符的二进制编码数据。每个字符的数据位长可以约定为 5 位、6 位、7 位或 8 位,一般采用 ASCII 编码。后面是奇偶校验位,根据约定,用奇偶校验位将所传字符中为“1”的位数凑成奇数个或偶数个。也可以约定不要奇偶校验,这样就取消奇偶校验位。最后是表示停止位的“1”信号,这个停止位可以约定持续 1 位、1.5 位或 2 位的时间宽度。至此一个字符传送完毕,线路又进入空闲,持续为“1”。经过一段随机的时间后,下一个字符开始传送才又发出起始位。每一个数据位的宽度等于传送波特率的倒数。微机异步串行通信中,常用的波特率为 50,95,110,150,300,600,1200,2400,4800,9600 等。

  • 接收方按约定的格式接收数据,并进行检查,可以查出以下三种错误:

奇偶错:在约定奇偶检查的情况下,接收到的字符奇偶状态和约定不符。
帧格式错:一个字符从起始位到停止位的总位数不对。
溢出错:若先接收的字符尚未被微机读取,后面的字符又传送过来,则产生溢出错。每一种错误都会给出相应的出错信息,提示用户处理。一般串口调试都使用空的

  • MODEM 连接电缆,其连接方式如下:

20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告
20155235 王玥 《基于Arm实验箱的接口测试和应用》 课程设计报告

2)编译应用程序

  • 运行 make 产生 term 可执行文件

      [root@zxt root]# cd /arm2410cl/exp/basic/03_tty/	
      [root@zxt 03_tty]# make			
      armv4l-unknown-linux-gcc	-c -o term.o term.c	
      armv4l-unknown-linux-gcc	-o ../bin/term term.o	-lpthread
      armv4l-unknown-linux-gcc	-o term term.o	-lpthread
      [root@zxt 03_tty]# ls			
      Makefile  Makefile.bak  term  term.c  term.o	tty.c
    

3)下载调试

  • 切换到 minicom 终端窗口,使用 NFS mount 开发主机的/arm2410cl 到/host 目录。进入 expasic 3_tty 目录,运行 term,观察运行结果的正确性。

      [root@zxt root]#	minicom
      [/mnt/yaffs]	mount -t nfs -o nolock 192.168.0.56:/arm2410cl	/host
      [/mnt/yaffs]cd /host/exp/basic/03_tty/
      [/host/exp/basic/03_tty]./term
    
      read modem
    
      send data
    
      123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX
    
  • 由于内核已经将串口 1 作为终端控制台,所以可以看到 term 发出的数据,却无法看到开发主机发来的数据,可以使用另外一台主机连接串口 2 进行收发测试;这时要修改一下执行命令,在 term 后要加任意参数。

  • Ctrl+c 或者 ESC 可使程序强行退出。

4.中断实验

1)S3C2410 中断处理

  • ARM920T 的异常向量表有两种存放方式,一种是低端存放(从 0x00000000 处开始存放),另一种是高端存放(从 0xfff000000 处开始存放)。ARM920T 能处理有 8 个异常,他们分别是:
    Reset,Undefined instruction,Software Interrupt,Abort (prefetch),Abort (data),Reserved,IRQ,FIQ

  • 下面是某个采用低端模式的系统源码片段:

      /************************************************************************
    
      _start:
    
      b        Handle_Reset
    
      b        HandleUndef
    
      b        HandleSWI
    
      b        HandlePrefetchAbort
    
      b        HandleDataAbort
    
      b        HandleNotUsed
    
      b        HandleIRQ
    
      b        HandleFIQ
    
      …..
    
      …
    
      ..
    
      other codes
    
      …
    
      ..
    
      .
    
      *****************************************************************************/
    
  • 上面这部分片段一般出现在一个名叫“head.s”的汇编文件的里,b Handle_Reset这条语句就是系统上电之后运行的第一条语句。也就是说这部分代码的二进制码必须位于内存的最开始部分(这正是低端存放模式),因为上电后 CPU 会从SDRAM 的 0x00000000处取第一条指令并执行。

2)编译应用程序

  • 运行 make 产生 int-driver 可执行文件 int-driver

      [root@BC basic]# cd	10_init/
      [root@BC 10_init]# make
      armv4l-unknown-linux-gcc -c -I.. -Wall -O -D__KERNEL__ -DMODULE -I/home/kernel/linux-2.4.18-2410cl/include s3c2410-int.c -o s3c2410-int.o
    
      s3c2410-int.c: In function `s3c2410_IRQ3_fun':
    
      s3c2410-int.c:83: warning: unused variable `byte'
    
      s3c2410-int.c: In function `s3c2410_interrupt_init':
    
      s3c2410-int.c:190: warning: implicit declaration of function `set_external_irq' [root@BC 10_init]# ls
    

3)下载调试

  • 切换到 minicom 终端窗口,使用 NFS mount 开发主机的/arm2410cl 到/host 目录,然后进入/host/exp/basic/ 10_int 目录,用 insmod int-driver.o 命令插入 s3c2410-int 驱动,并用 lsmod 命令查看是否已经插入。

      [/mnt/yaffs]mount -t nfs -o nolock 192.168.0.189:/arm2410cl /host
      [/host/exp/basic]cd 10_int/
      [/host/exp/10_init]ls
      Makefile	s3c2410-int.c	s3c2410-int.o
      [/host/exp/10_init ]insmod s3c2410-int.o
      [/host/exp/10_init]lsmod
    
    
      Module        Tainted: P
              Size	Used by
      s3c2410-int        0 (unused)
              2048
    

三、设计特色

  • 见小组报告

四、源代码及注释

  • 见小组报告

五、个人报告

  1. 小组贡献排序及依据(每个人的工作量):
    付颖卓:完成实验的主要人员,实验代码调试,与指导老师联系。
    聂小益:辅助完成实验,实验箱操作,报告的编写。
    王玥:辅助完成实验,实验箱操作,报告的编写。
  2. 个人报告(20155235 王玥):
    1)个人贡献:

在课设中,我主要是负责最终报告的编写和记录实验问题以及实验步骤,期间遇到的接口问题和串口问题我们也有及时和老师求助、沟通,实验箱的保存工作我也出了一份力。

2)设计过程中遇到的主要问题:

Makefile编译不成功:下载其他编译器并修改PATH等,使用心得编译器进行编译。
minicom:更改串口设置,换用超级终端。
主机与实验箱ping不通:更改虚拟机的网络设置,将实验箱与虚拟机配置到同一网段并关闭所有防火墙,即可ping通。

3)调试过程中遇到的主要问题:

由于使用的编译器不同,部分操作要换用不同的指令。
设置共享文件夹:
安装NFS server软件;
创建共享目录并将目录的权限改为777;
配制文件vi /etc/exports:添加/home/lisp/share*(rw,sync,no_root_squash)
开启nfs服务:sudo /etc/init.d/nfs-kernel-server start
将写好的文件拷贝至共享文件夹后,即可在超级终端云顶命令

4)设计体会及收获:
本次课程设计是一个锻炼我们动手能力和合作能力的好机会,不管是我们在实践中遇到的问题,还是我们对于ARM实验箱从陌生到逐渐熟悉,都给了我们很大的学习经验。