Raspberry Pi 上的 Java® SE Embedded 入门
作者:Bill Courington 和 Gary Collins
2012 年 8 月发布
如何在一小时内让 Linux 和 Java SE Embedded 在 Raspberry Pi 上运行
它只有信用卡大小,价格约等于一本 Java 编程书。
它就是 Raspberry Pi 计算机,可以支持适用于无头嵌入式应用程序的完整 Java SE 运行时。本文带您了解 Raspberry Pi 上的 Java 编程,包括以下主题:
注:此处所给出的说明可以有多种变化,特别是在主机(台式或便携式)计算机上执行的操作,以及在 Raspberry Pi 上执行的操作。请根据您的知识和喜好(可能还包括
可选的 Linux 调优和调整
一节中的某些主题)创建适合自己的工作流。
Raspberry Pi
Raspberry Pi 是一款小型、低功耗的主板,采用 700mHz ARMv6 CPU,在单一芯片上集成了硬件浮点和图形处理器。图形处理器和 CPU 共享 256MB RAM。提供了 USB、以太网、高清图形、音频、SD 卡以及通用 I/O 接口。图 1 显示的 Raspberry Pi B 型插入了 SD 卡进行扩展。SD 卡有着特殊的作用:Raspberry Pi 将从 SD 卡启动。本文主要介绍如何创建和修改可启动的 SD 卡上的文件。
图 1. Raspberry Pi B 型
可以通过 USB 键盘和鼠标以及 HDMI 监视器或电视(最高 1080p)与 Raspberry Pi 交互。该板上的以太网连接提供了另一种选择:通过
ssh
从联网主机交互。本文的
可选的 Linux 调优和调整
一节介绍如何启用
ssh
登录。
前提条件
要设置 Raspberry Pi B 型使其运行 Java SE Embedded,您需要:
-
有线网络,让您可以通过以太网电缆连接 Raspberry Pi。网络必须提供 DHCP IP 地址。
-
Linux 主机,与 Raspberry Pi 位于相同的有线以太网网络。您可以在 Windows 或 Mac 主机上执行相应的操作,但细节不尽相同,本文不再赘述。您需要主机的 root 密码。在主机上,您还需要:
-
从网站下载文件的办法,如 Web 浏览器或
wget
实用程序。
-
磁盘分区工具。在本文中,我们使用简单、有效的 GParted。如果没有 GParted,可以自行获取并在主机上安装,如下所示:
$ sudo apt-get install gparted
-
Web 浏览器和电子邮件客户端,用于从 Oracle 下载 Java SE Embedded
-
SD 卡读写器。如果主机在虚拟机中运行 Linux,请确保它可以读写 SD 卡。
-
监视器,可以直接连接或通过适配器连接到 Raspberry Pi 的 HDMI 端口。
-
USB 键盘和鼠标,通过有源 USB 集线器连接到 Raspberry Pi。
-
SD 卡,用于存放 Raspberry Pi 的操作系统和 Java 运行时。一张 4GB 卡,足以容纳 Linux、Java SE Embedded 和大多数嵌入式应用程序。
注:并非所有 SD 卡都与 Raspberry Pi 兼容。高速卡可能超出 Raspberry Pi 总线容许的速度极限。我们成功使用了 Transcend 4GB Micro 和 Patriot 4GB 4 类卡。http://elinux.org/RPi_VerifiedPeripherals#SD_cards 列出了适用和不适用 Raspberry Pi 用户的卡。
-
5V DC Micro USB 电源,700mA 以上都可以。根据 Raspberry Pi 网站上的信息,请勿使用 USB 集线器或计算机作为电源。
必需的 Linux 安装
通电时,Raspberry Pi 固件从 SD 卡槽启动。Java SE Embedded 在 Linux 上运行,因此首先要在 SD 卡上安装 Linux。
下载适合 Raspberry Pi 的 Debian Squeeze Linux 映像
注:这些说明适用于 Debian Squeeze。其他适用于 Raspberry Pi 的 Linux 实现也可以使用,但
必须
针对 ARM 芯片的软件浮点计算进行了构建。Raspberry Pi 网站上链接的映像可能已针对硬件浮点计算进行了构建;不适用于 Java SE for Embedded。
可以在此处找到适用于 Raspberry Pi 的压缩 Debian Squeeze 映像:http://elinux.org/RPi_Distributions#Debian_ARM。文件大小约 450MB。以下说明假定已下载到新目录
~/RaspberryPi/
。要验证下载的文件,请遵循下载开始时显示的页面上的 SHA-1 校验和说明。
按如下所示解压缩映像:
$ cd ~/RaspberryPi
$ unzip *.zip
解压缩过程创建一个名称类似
debian6-19-04-2012
的子目录。
将 Debian Squeeze 映像复制到 SD 卡
在主机上找出 SD 卡设备句柄,如下所示(如果您愿意,也可以采用其他方式):
-
在 Linux 终端窗口中,运行
dmesg | tail
,这将显示与设备挂载有关的消息。我们只对消息的末尾部分感兴趣。
-
将 SD 卡插入读写器。
-
在另一个终端窗口中,再次运行
dmesg | tail
。与第一个窗口相比,此窗口多出一些与新挂载的 SD 卡有关的行。具体细节可能不尽相同,但应如下所示:
[ 110.084625] sdb:detected capacity change from 0 to 3963617280
[ 118.055249] sd 2:0:0:0:[sdb] 7741440 512-byte logical blocks:(3.96 GB/3.69 GiB)
[ 118.059409] sd 2:0:0:0:[sdb] Assuming drive cache:write through
[ 118.064547] sd 2:0:0:0:[sdb] Assuming drive cache:write through
[ 118.066015] sdb:sdb1
线索是
sdb
,它表示设备句柄为
/dev/sdb
。
sdb1
指示例卡的单个分区。您的卡可能有多个分区。
在以下说明中,假定 SD 卡设备句柄为
/dev/sdb
,它只有一个分区:
sdb1
。如果需要,可根据您的环境调整说明。
-
卸载 SD 卡分区:
$ sudo umount /dev/sdb1
-
使用
dd
将 Debian 映像复制到 SD 卡。
注:在以下命令中,
确保
正确输入
of
(输出文件)参数值。您将调用低级磁盘复制,这将覆盖所有数据。指定错误的设备会破坏数据。
$ cd ~/RaspberryPi/debian6-19-04-2012
$ sudo dd if=yourDebian.img of=/dev/sdb bs=1M
1859+1 records in
1859+1 records out
1950000000 bytes (2.0 GB) copied, 212.344 s, 9.2MB/s
dd
到 SD 卡是一个缓慢的操作。4GB 4 类卡可能需要 5-10 分钟。
dd
不提供进度指示,因此请耐心等待它慢慢完成工作。
如果现在想确定 SD 卡 Linux 已起作用,请跳到
首次启动
一节,然后返回
调整 SD 卡分区大小
。
调整 SD 卡分区大小
SD 卡现在包含三个分区和未分配空间。现在我们将未分配空间添加到 Linux 文件系统,为 Java SE Embedded 和应用程序提供更多空间。为了向文件系统分配未分配空间,我们修改 SD 卡上的分区,删除并重新创建一个分区,然后调整另一个分区的大小。
-
启动 GParted:
$ sudo gparted
Gparted 首先显示主机磁盘的分区。您
不
希望更改这些分区。
-
选择 GParted -> Devices 显示
/dev/sdb
上的分区和未分配空间:
图 2. 初始 SD 卡分区
三个分区分别是:
-
/dev/sdb1
:引导分区
-
/dev/sdb2
:Linux 根文件系统。它分配的 1.5GB 空间大部分已使用。
-
/dev/sdb3
:Linux 交换区。
大约一半的卡空间未分配。最大一块可用空间跟在
/dev/sdb3
分区后面。为了将此空间添加到
/dev/sdb2
(文件系统),我们临时删除
/dev/sdb3
,扩展
/dev/sdb2
,然后重新创建
/dev/sdb3
。
首次启动
注:针对这些步骤,以下组件必须连接到 Raspberry Pi:监视器、键盘以及确知有效的以太网电缆。
-
断开 Raspberry Pi 电源,将 Linux SD 卡插入插槽,然后接通电源。数秒钟后,监视器上应显示启动进度消息。如果未出现,可能是 SD 卡类型错误或格式不正确。
首次启动过程中出现错误消息很正常,因为有些服务尚未配置。首次启动还可能看似挂起,等待端口映射关闭。正如控制台消息所指示的,可以任其运行(通常需要数分钟),也可以断开 Raspberry Pi 电源,还可以选择重新启动。后续启动相对较快。
-
收到登录提示后,使用 Raspberry Pi 用户名和密码登录。撰写本文时,用户名和密码分别为“pi”和“raspberry”。
注:不兼容的键盘可能会妨碍登录,例如,因为重复字符。如果无法登录,可尝试其他键盘。
如果使用“pi”和“raspberry”不能登录,请咨询 Linux 发行网站。
-
获取并记录 Raspberry Pi 的 IP 地址,如下所示:
$ sudo /etc/rc.local
RaspberryIP
-
使用以下命令允许
ssh
登录:
$ sudo update-rc.d -f ssh defaults 20
-
重新启动以实际启用
ssh
登录:
$ sudo sync; sudo shutdown -r now
如果关闭耗时过长,可以关闭 Raspberry Pi 电源,然后再打开。
现在,我们可以通过网络从主机读写 Raspberry Pi SD 卡。
Java SE Embedded 安装
在本节中,我们使用主机下载 Java SE Embedded,通过网络将其复制到 Raspberry Pi 的 Linux 文件系统。然后,还是通过远程方式解压缩下载文件并启动 Java。
获取 Java SE Embedded 评估版软件
-
在主机的 Web 浏览器中,转到 http://www.oracle.com/technetwork/java/embedded/downloads/javase/index.html。网页细节在本文撰写后可能已改变。
图 7. 第一个下载链接
-
在 Java SE Embedded 7 列中,单击 EABI, VFP, SoftFB ABI, Little Endian。
将出现一个调查页面。
-
填写调查表,单击 Submit。将出现一个验证页面。
-
检查验证页面,看是否正确(尤其是电子邮件地址),然后单击 Submit。
不久,您的收件箱中将收到一封来自 JavaSE-Embedded-LinkNotify 的电子邮件。
-
单击电子邮件中的链接。将出现另一个下载页面(有些细节可能在本文撰写之后发生更改):
图 8. 第二个下载链接
-
选择 Accept License Agreement,然后单击 ARMv6/7 Linux - Headless 行中的链接。
注:本文撰写时,尚未在 Raspberry Pi 上测试 ARMv7 Linux - Headful 软件。ARMv7 Linux - Headless - Server Compiler 软件不能在 Raspberry Pi 上工作,因为它需要 ARM v7 芯片。
-
将
.gz
文件保存到
Downloads
目录。
-
通过网络以 pi 用户身份登录 Raspberry Pi,创建一个用于下载 Java 的目录:
$ ssh pi@
RaspberryIP
mkdir /home/pi/java
-
将 Java 下载复制到 Raspberry Pi 上的新目录:
$ scp ~/Downloads/*.gz pi@
RaspberryIP
:/home/pi/java
-
解压缩 Java 下载文件:
$ ssh pi@
RaspberryIP
$ cd /home/pi/java
$ tar -zxvf *.gz
...
-
启动 Java:
$ ls ejre*
ejre1.7.0_04
$ cd ejre*
$ ./bin/java -version
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment for Embedded (build 1.7.0_04-ea-b20, headless)
Java Hotspot(TM) Embedded Client VM (build 23.0-b21, mixed mode)
有些细节(如版本号和内部版本号)可能在本文撰写后发生更改。
-
也可以删除下载文件:
$ rm /home/pi/java/*.gz
可选的 Linux 调优和调整
本节中的命令可以让您的 Raspberry Pi 系统运行地可靠、响应更即时、更方便。根据自己的喜欢进行选择,然后在 Raspberry Pi 上运行。为了简化诊断问题,请在每次更改后重新启动。
在本节中:
设置静态 IP 地址
如果您的网络重用动态 IP 地址,您可以跳过更改静态 IP,因为 Raspberry Pi 的 IP 地址实际上将保持不变。如果每次启动时 Raspberry Pi 的动态 IP 地址可能不同,对于
ssh
来说,使用静态 IP 地址会更方便。在以下说明中,假定希望为 Raspberry Pi 分配主机名
raspberrypi
。
首先以超级用户身份在文本编辑器中打开
/etc/hosts
(例如,
sudo vi /etc/hosts
)。为 Raspberry Pi 添加一行,包括网络中的有效静态 IP 地址、可选的域名以及别名。以下是一个假设示例,其中将 Raspberry Pi 指定为
raspberrypi
:
127.0.0.1 localhost?192.168.0.100 raspberrypi.yourDomain raspberrypi loghost
保存文件,退出编辑器。
以超级用户身份在文本编辑器中打开
/etc/hostname
。添加一行,如下所示:
raspberrypi
保存文件,退出编辑器。
以下说明可以防止过载网络中导致操作系统更改 Raspberry Pi 静态 IP 地址的问题。这一问题会使
ssh
或其他使用静态 IP 地址的操作停止工作。
发现以太网端口的硬件地址,如下所示。
首先,确定以太网控制器的名称(
x
代表地址数字):
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1488 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether b8:27:eb:b5:e8:90 brd ff:ff:ff:ff:ff:ff
inet xx.xxx.xxx.xx/xx brd xx.xxx.xxx.xxx scope global eth0
在此例中,名称为
eth0
。硬件地址是
link/ether
之后的十六进制数字,本例中为
b8:27:eb:b5:e8:90
。
得到以太网控制器的硬件地址之后,以超级用户身份在文本编辑器中打开
/etc/network/interfaces
,并添加(替代网络详细信息)类似下面所示
# New entries
注释之后的内容。
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or?
# /usr/share/doc/ifupdown/examples for more information.
auto lo
iface lo inet loopback
# New entries to support static IP follow:
auto eth0
iface eth0 inet static
hwaddress ether b8:27:eb:b5:e8:90
address 192.168.0.100
network 192.168.0.0
netmask 255.255.255.0
255.255.255.0
broadcast 192.168.0.255
gateway 192.168.0.1
启用交换和优化文件系统访问时间
默认情况下,Debian Linux 中禁用交换。如果操作超出 Raspberry Pi 的 256KB RAM 大小,系统就会崩溃。还有一种情况没这么严重,即默认情况下,文件系统要花时间维护每个文件的上次访问时间,这对嵌入式应用程序基本没有用处。维护上次访问时间还可能缩短 SD 卡的生命周期。这两种默认行为均在
/etc/fstab
文件中指定。
以超级用户身份在编辑器(如
vi
)中打开
/etc/fstab
。该文件如下所示:
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 0
#/dev/mmcblk0p3 none swap sw 0 0
要启用交换,请取消第三行的注释。
注:SD 卡上的交换很慢。对于嵌入式应用程序,您可能希望管理内存以避免出现此问题。
为避免维护上次访问信息产生的开销,请在
p1
与
p3
之间插入一个
p2
挂载点。
noatime
和
nodiratime
选项可完成此任务。当文件如下面所示时,保存文件,退出编辑器:
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 0
/dev/mmcblk0p2 / auto rw,noatime,nodiratime,errors=remount-ro 0 1
/dev/mmcblk0p3 none swap sw 0 0
现在,为交换空间分配
p3
(在主机上创建的交换分区
/dev/sdb3
):
$ sudo mkswap /dev/mmcblk0p3
设置时区和语言环境
默认情况下,Raspberry Pi 配置为使用欧洲/伦敦时区和 en_GB_UTF-8 语言环境。要实现计算机本地化,请遵循以下说明。
要更改时区,请输入以下命令:
$ sudo dpkg-reconfigure tzdata
将出现一个伪图形界面。
图 9. 时区用户界面
使用上下箭头键在地区和城市间移动选择光标。使用左右箭头键选择 <Ok> 或 <Cancel>。按 Return 输入选择。
按如下所示设置语言环境:
$ sudo dpkg-reconfigure -p low locales
用户界面与设置时区的界面类似。
设置时间服务器
许多操作(包括软件包更新)依赖于正确的日期和时间。要自动设置日期和时间,请了解网络时间服务器的身份,然后运行以下命令:
$ sudo ntpdate yourNTPServer
要在每次启动时设置时间,请以超级用户身份编辑
/etc/rc.local
,并在脚本退出前添加以下代码行:
ntpdate yourNTPServer
设置互联网代理
Ping 某个知名的互联网主机,如
www.lego.com
。如果主机不响应,则确定网络是否位于代理后面,如有需要,还可根据网络约定设置环境变量
http_proxy
,例如(假设):
$ sudo export http_proxy =’http:192.168.0.1:3128’
要在每次登录时设置代理,请在
~/.bash_profile
中添加 export 命令,或等效命令(如果使用其他 shell)。
重新映射键盘
如果键盘键解释错误或者希望更改键盘布局,请使用以下命令:
$ sudo dpkg-reconfigure keyboard-configuration
用户界面类似于本文
设置时区和语言环境
一节中描述的内容。
更新 Debian 软件包
更新随 Debian 发布的软件包之前,以超级用户身份在文本编辑器中打开
/etc/apt/sources.list
。此文件包含新/更新软件包的信息库位置。发行时,位置 URL 中含 ftp.uk。如果您不在英国,将这些条目更改为物理上离您更近的位置可以提高性能。例如,如果您在美国,可以将 ftp.uk 全局更改为 ftp.us。以下站点包含有关 Debian 信息库位置的信息:http://ftp.debian.org/debian/README.mirrors.html。
要更新已安装的软件包,请在验证 Raspberry Pi 可以连接到互联网连接之后,输入以下命令:
$ sudo apt-get update
$ sudo apt-get upgrade
如果收到消息,指示软件包列表中有重复项,则在编辑器中再次打开
/etc/apt/sources.list
,注释掉其中一个重复的条目。通常最好保留包含信息较多的条目。
自动启动图形用户界面
如果希望窗口系统在您本地登录 Raspberry Pi 时自动启动,则需更改默认的运行级别,如下所示。以超级用户身份在文本编辑器中打开
/etc/inittab
。找到以下条目:
# The default runlevel.
id:2:initdefault:
将它更改为 5:
# The default runlevel.
id:5:initdefault:
注:图形会使用大量 Raspberry Pi RAM,大约 90MB。
添加其他 Web 浏览器
如果使用默认 midori 浏览器遇到困难,可以尝试 iceweasel:
$ sudo apt-get update
$ sudo apt-get install iceweasel
启用声音
默认情况下,Raspberry Pi 声音输出不起作用。要想启用,以超级用户身份在文本编辑器中打开
/etc/modules
。在文件末尾添加以下代码行:
snd_bcm2835
保存并关闭文件。重新启动 Raspberry Pi 时就会启用声音。
Integrated Cloud Applications & Platform Services