vivi系统引导程序的网络功能扩展

摘要 vivi是MIZI公司开发的系统引导程序,原本只支持串口下载。本文以S3C2410处理器加CS8900网络芯片为例,介绍一种在vivi基础上增加网络支持的设计方法,使vivi能够通过TFTP下载文件,可以有效地缩短系统的开发周期,方便用户使用。

关键词 vivi Bootloader TFTP协议 网络功能扩展

  随着嵌入式的发展,基于ARM的系统越来越流行。在开发ARM系统时,第一步就是要选择一种合适的Bootloader。目前网络上可得到的Bootloader很多,一般几十KB,所以除非要求把Bootloader限制在几KB以内,否则没有必要自己去写一个BootloaderBootloader一般存放在Flash中。当前主流的Flash分为NOR Flash和NAND Flash。前者价格比后者高出很多,而性能相差无几。如果系统采用的是NAND Flash,那么vivi可能会是一个好的选择。

1  U-bootvivi的比较

  Uboot是由ARMboot和ppcboot结合而组成的,因为其支持的面比较广,功能强大,支持网络,因而被广泛采用;但是它主要针对那些以NOR Flash 启动的系统。NOR Flash可以直接被系统寻址,整个Flash都在系统的寻址空间内,所以在其启动时的汇编代码中是直接把Bootloader拷贝到RAM中去的。如果系统采用的是便宜的NAND Flash,那么它是不能直接被系统寻址的,对它的读写需要专门的操作。此时采用Uboot需要修改太多的代码,而vivi则针对NAND Flash作了特别处理。

vivi网络功能的扩展

  vivi来自韩国MIZI公司,源代码完全开放,可在该公司网站上下载。原始的vivi只支持从串口下载文件,而现在多数嵌入式产品都支持网络。不能从网口下载文件,不能不说是vivi的一点遗憾。vivi的整个设计都是仿照Linux系统内核设计来做的,其配置界面和Linux内核设计的一样。程序的组织也是完全仿照Linux来设计的,所以比较容易上手。其具体文件组织如下:

  arch/目录存放的是平台相关的代码,主要是系统启动时的汇编代码,vivi运行的第一程序head.s就是放在这里。

include/存放的是系统的头文件
driver/存放的是Flash和串口等的读写操作程序
lib/提供了整个vivi所共用的库函数
script/提供配置界面的程序
util/NAND Flash操作的相关程序
Documention/ 文件的说明

  可以看出,整个设计非常清楚,与Linux 内核的安排是一样的。为了能让vivi通过网络下载文件,就要在vivi中增加一条命令。这里以S3C2410处理器和CS8900网络芯片为例来增加一条命令"tftp [patition] <filename>",使vivi可以从TFTP服务器上下载程序。

3  TFTP协议简介

  TFTP(Trivial File Transfer Protocol)是一种传输文件的简单协议,是基于UDP协议实现的。它有3种传输模式。这里采用第二种“octet”,就是8位源数据类型。任何传输起自一个读取或写入文件的请求,这个请求也是连接请求。如果服务器批准此请求,则服务器打开连接,数据以定长512字节传输,每个数据包包括一块数据,服务器发出下一个数据包以前必须得到客户对上一个数据包的确认。如果一个数据包小于512字节,则表示传输结束。所以最后一个数据包为0~511字节。如果数据包在传输过程中丢失,发出方会在超时后重新传输最后一个未被确认的数据包。通信的双方都是数据的发出者与接收者,服务器传输数据接收应答,另一方发出应答接收数据。大部分的错误会导致连接中断。出错后服务器会发出一个出错信息包,这个包不会被确认,也不会被重新发送。

  TFTP支持5种类型的包:

  ①  Read request(读请求包)
  ②  Write request(写请求包)
  读/写请求包格式为:

按此在新窗口浏览图片

  读请求Opcode(操作号)为1,写请求Opcode(操作号)为2;Filename为要从服务器上读/写的文件名;Mode域指数据传输模式串一般为“octet”。
  ③  Data(数据包)
  数据包格式为:

按此在新窗口浏览图片

  数据包Opcode(操作号)为3;Block#(块号)是从1开始的自然数;Data域指数据长度,通常为512字节,最后一个包数据长为0~512字节。
  ④  Acknowledgment(确认包)
  确认包格式为:

按此在新窗口浏览图片

  确认包Opcode(操作号)为4;Block#为收到的最后一个正确包的块号。
  ⑤  Error(出错信息包)
  出错信息包格式为:

按此在新窗口浏览图片

  出错信息Opcode(操作号)为4;ErrorCode为出错代码;ErrMsg是服务器给出的出错信息提示。

4  如何给vivi增加一条命令

  vivi的命令接口是通过一个结构体来实现的:

typedef struct user_command {
  const char *name;
  void (*cmdfunc)(int argc, const char **);
  struct user_command *next_cmd;
  const char *helpstr;
} user_command_t;

其中:name是命令的名称;(*cmdfunc)(int argc,const char**)是实现该命令的具体函数;*next_cmd是指向下一条命令的指针;helpstr是命令的使用说明。

  vivi启动后调用初始化命令,把它所支持的命令通过链表连接起来。具体而言就是,main.c中调用init_builtin_cmds()函数;init_builtin_cmds在lib/cmd中给出。然后通过add_command()把命令连到链表上,例如增加一条tftp下载的命令tftp_cmd,可以这样写add_command(&tftp_cmd)。

user_command_t tftp_cmd={
"tftp",
command_tftp,
NULL,
"tftp{...}/t/t/t--get file form tftp server to RAM/Flash"
};

  在这里,函数command_tftp()就是用来提供TFTP下载功能的,使系统可以将TFTP服务器上的文件下载到系统内存中的指定地址去,实现功能的主程序如图1所示。主程序首先初始化网络芯片CS8900和定时器,定时器是用来计算接收超时的。这里考虑到移植性问题,没有采用中断的处理方式来接收数据,而直接采用查询的方式来接收数据。然后发送arp广播请求,查询主机的物理地址,得到主机地址之后就可以发送TFTP读请求包了。如果收到错包或非TFTP包,则可直接丢弃,返回收到的包长为-2;如果超时没收到包,则说明请求丢失,返回的包长为-1,要重发请求。重发3次没回音,表明网络不通。收到TFTP的服务器的第一个回应就是第一块数据或是出错信息包,如果是第一块数据则进入TFTP接收循环。

  TFTP接收循环如图2所示。初始化过程中,addr为文件下载到内存中的地址,offset为写入指针相对于addr的偏移量。偏移量每次写入数据后增加512。然后检查收到数据包的长度。如果长度为512字节,则说明是一个普通的数据包;如果长度小于512字节,则说明是最后一个数据包,应该结束循环。收到包后,把数据写入内存中。内存中的偏移地址加512,然后继续收包。当收到错误信息包或接收超时或收到坏包时,所返回的长度都是负数,所以在这里会根据收包所返回的长度作出相应的处理。如果长度大于0而且不是重包,就进行上面的循环操作。

按此在新窗口浏览图片
图1  TFTP主程序流程

按此在新窗口浏览图片
图2  数据接收循环

  CS8900读写程序的编写可参考数据手册。CS8900有两种主要的访问方式:一种是I/O空间;另一种是内存空间。前者系统把CS8900当成I/O口一样访问,所有的寄存器操作都是通过几个指定的地址来完成;后者系统可直接寻址其寄存器。前者是CS8900的默认工作方式, 这
里也采用前者。 在调用发送和接收程序之前, 首先调用eth_halt(),停止CS8900的收/发器(如果不停止将无法进行初始化),然后eth_init()来初始化。初始化过程中会读取芯片识别号,看是否为0x630e。若不为此值,则说明系统没有找到CS8900芯片,然后设置MAC地址,启动收/发器,禁止发出中断信号。这里没有用到中断。因为用中断不便于移植,所以在发送完毕之后,直接调用eth_rx()接收即可。

  CS8900发送数据的流程如下:

①  设置为收到完整frame后开始发送;
②  设置frame的长度,告诉给CS8900;
③  查看CS8900是否已为frame分配好空间;
④  如果没有分配好就返回等待;
⑤  如果已分配好空间,就把packter地址处的数据写入CS8900中;
⑥  设定时间,等待frame 发送完毕;
⑦  检查发送是否成功。

  CS8900接收数据的流程比较简单,只需要检查状态寄存器是否收到,然后进行接收就行了。做完以上工作后,可以将文件从TFTP服务器上下载到RAM中。如果需要下载到Flash中,只需要调用write_to_flash()函数即可。该函数在serial.h中给出。

  最后还需要修改include/platform下的smdk2410.h中的

  #define vBWSCON0x221ed112
  #define vBANKCON30x00007ffc

  这样可以使SC2410 可寻址到CS8900。

  编者注:源码见本刊网站www.mesnet.com.cn

结语

  本文讨论扩展vivi的一般方法,给vivi增加一条网络下的命令,使得vivi的功能更加完善,完全可以和Uboot等著名引导程序相媲美。

参考文献

[1]  CIRRUS LOGIC cs8900a 数据手册.
[2]  中国协议分析网. TFTP协议简介.
[3]  孙天泽,袁文菊,张海峰. 嵌入式设计及Linux驱动开发指南. 北京:电子工业出版社,2005.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值