1.搭建开发环境
开发环境(主要指linux、虚拟机的安装和交叉编译环境的搭建)完全按照mini6410用户手册4.3节操作,在此不再赘述。
2.根文件系统的目录说明
根文件系统是Linux启动的时候使用的第一个文件系统,没有它系统将无法正常的启动,然而在这个根文件系统中又包含了一系列的目录,接下来对这些目录做一个简单的介绍。
bin 存放所有用户都可以使用的、基本的命令。
sbin 存放的是基本的系统命令,它们用于启动系统、修复系统等。
Usr 里面存放的是共享、只读的程序和数据。
proc 这是个空目录,常作为proc 文件系统的挂载点。
dev 该目录存放设备文件和其它特殊文件。
etc 存放系统配置文件,包括启动文件。
lib 存放共享库和可加载块(即驱动程序),共享库用于启动系统、运行根文件系统中的可执行程序
boot 引导加载程序使用的静态文件。
home 用户主目录,包括供服务账号锁使用的主目录,如FTP。
mnt 用于临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目录。
opt 给主机额外安装软件所摆放的目录。
root root 用户的主目录
tmp 存放临时文件,通常是空目录。
var 存放可变的数据,如日志等。
3 建立根文件系统的目录
进入到自己要放置文件系统的目录,采用《mini2440 Linux移植开发实战指南》,新根文件系统目录的脚本文件create_rootfs_bash,使用命令chmod +x create_rootfs_bash ,改变文件的可执行权限,执行“./create_rootfs_bash ”运行脚本,就完成了根文件系统目录的创建。脚本create_rootfs_bash文件的内容为:
在脚本中改变了tmp 目录的使用权,让它开启sticky 位,为tmp 目录的使用权开启此位,可确保tmp 目录底下建立的文件,只有建立它的用户有权删除。尽管嵌入式系统多半是单用户,不过有些嵌入式应用不一定用root 的权限来执行,因此需要遵照根文件系统权限位的基本规定来设计。
4.建立动态链接库(即lib目录)
动态链接库直接用友善之臂的,先解压友善之臂的根文件包,拷贝lib的内容到新建的根文件目录lib内。
6.交叉编译busybox(即根文件系统内bin,sbin等目录)
Busybox 是一个遵循GPL v2 协议的开源项目,它在编写过程总对文件大小进行优化,并考虑了系统资源有限(比如内存等)的情况,使用Busybox 可以自动生成根文件系统所需的bin、sbin、usr 目录和linuxrc 文件。具体介绍可以参考韦东山完全手册的346页。
(1)、解压busybox
cd /opt/FriendlyARM
tar –zxvf busybox-1.17.2-20101120.tgz
(2)、进入源码,修改Makefile 文件:(这个地方是很重要的一步,必须做,有的教程或者文章参考内核的配置与编译,即在make menuconfig和make后面添加ARCH、CROSS_COMPILE等,而对此不做修改,将可能会导致“request_module: runaway loop modprobe binfmt-464c”等错误出现)
cd /opt/studyarm/busybox-1.17.2
修改:
CROSS_COMPILE ?=arm-linux- //第164 行
ARCH ?=arm //第189 行
(3)、配置busybox
提示:友善之臂已经在光盘中提供了busybox 的源代码包,在光盘\linux 目录中,busybox-1.17.2-20101120.tgz解压后里面包含了友善之臂提供的缺省配置文件:fa_config (输入命令“cp fa.config .config”可以调用该配置),一般用户直接使用缺省文件就可以了,这样生成的busybox 和root_qtopia_qt4 中的是完全一致的。但为了对它的配置了解 更多一些,可以参考 《mini2440 Linux移植开发实战指南》 的如下步骤:
输入 make menuconfig进行配置
下面的配置和busybox1.17.2的配置基本一样,部分地方不太一样。
5.dev设备文件的制作
设备文件较多,而且比较繁杂,因此其制作一般包括两个部分:静态创建设备文件和使用mdev创建设备文件
(1).静态创建设备文件
其实在刚开始制作文件系统的目录里已经静态制作创建了两个必须的设备的设备文件:console和null,内核在引导时这两个设备节点必须存在。
udev:它是个用户程序,能根据系统中硬件设备的状态动态的更新设备文件,包括设备文件的创建、删除等。它的操作相对复杂,但灵活性很高。
mdev是busybox自带的一个简化版的udev,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动 程序所需的节点文件。在以busybox为基础构建嵌入式linux的根文件系统时,使用它是最优的选择。在busybox的配置中,下面的选项将增加对mdev的支持。
在6,7两步的配置结束后,就可以编译并安装busybox。
编译:make ARCH=arm CROSS_COMPILE=arm-linux,其实仅执行make即可,我在这里添加了ARCH和CROSS_COMPILE,其实没什么作用,只是为了保险。因为如果编译的不是ARM版的busybox,系统时无法运行的。
安装:make install CONFIG_PREFIX=/opt/FriendlyARM/mini6410/rootfs/。CONFIG_PREFIX中安装的位置也可以在配置的时候设置,具体位置为:
在第5步中,安装动态链接库后,lib/modules目录下已经有内核模块了,但是这个内核模块和我采用的内核不是一个版本,因此重新编译安装。
进入内核的目录,在编译安装内核模块之前必须保证内核已经正确无误的配置及编译过一次。在这里假设还没有编译过。
(1)我们要使得Linux-2.6.38的缺省目标平台成为ARM 的平台。
修改总目录下的Makefile
原
(2)配置、编译内核模块
在此不具体说明怎么配置,可以将内核里友善自带的配置文件拷贝。然后执行:
a、新建etc/mdev.conf文件,内容为空。
b、拷贝主机etc目录下的passwd、group、shadow文件到rootfs/etc目录下。
c、etc/sysconfig目录下新建文件HOSTNAME,内容写自己喜欢的名字。
d、etc/inittab文件:
9.制作根文件系统镜像
执行以下命令:
这将会在/usr/sbin目录下创建生成相应的工具集
然后执行
一. 使用eclipse与设备连接进行断点调试 2013-02-26
1)将Y:\[project_name]\development\ide\eclipse下的.classpath拷贝到Y:\[project_name]\下。
2)Eclipse启动,file->new->project,导入工程。
3)连接设备,打开DDMS,在device列表中的进程选中你要调试的进程。
4)设置debug。如下图。
Project选择调试项目。
Port选择远程端口,这里是8700。
最后按debug。
出现如下绿色标记,代表设置成功。
具体端口视具体情况而定。
5)在代码中打上断点,其他操作如同调试java一般程序那样。
1. AsyncTask介绍与应用 2013-02-25
转载自:http://blog.csdn.net/bd_zengxinxin/article/details/8504696
先大概认识下Android.os.AsyncTask类:
* android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式来使后台线程和UI线程进行通讯:后台线程执行异步任务,并把操作结果通知UI线程。
* AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
* Params 启动任务执行的输入参数,比如HTTP请求的URL。
* Progress 后台任务执行的百分比。
* Result 后台执行任务最终返回的结果,比如String,Integer等。
* AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现这些方法。
* 1) 继承AsyncTask
* 2) 实现AsyncTask中定义的下面一个或几个方法
* onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
* doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
* onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
* onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.
* onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI 线程中创建
2) execute方法必须在UI 线程中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法,需要在UI线程中实例化这个task来调用。
4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。
下面通过一个Demo来说明如何使用Android.os.AsyncTask类,通过进度条来显示进行的进度,然后用TextView来显示进度值。程序结构图如下:
[1] \layout\main.xml 布局文件源码如下:
[html] view plaincopy
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 >
7 <TextView
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"
10 android:text="Hello , Welcome to Andy's Blog!"/>
11 <Button
12 android:id="@+id/download"
13 android:layout_width="fill_parent"
14 android:layout_height="wrap_content"
15 android:text="Download"/>
16 <TextView
17 android:id="@+id/tv"
18 android:layout_width="fill_parent"
19 android:layout_height="wrap_content"
20 android:text="当前进度显示"/>
21 <ProgressBar
22 android:id="@+id/pb"
23 android:layout_width="fill_parent"
24 android:layout_height="wrap_content"
25 />
26 </LinearLayout>
[2] /src中的MainActivity.java源码如下:
[html] view plaincopy
27 package com.andyidea.demo;
28
29 import android.app.Activity;
30 import android.os.AsyncTask;
31 import android.os.Bundle;
32 import android.view.View;
33 import android.widget.Button;
34 import android.widget.ProgressBar;
35 import android.widget.TextView;
36
37 public class MainActivity extends Activity {
38
39 Button download;
40 ProgressBar pb;
41 TextView tv;
42
43 /** Called when the activity is first created. */
44 @Override
45 public void onCreate(Bundle savedInstanceState) {
46 super.onCreate(savedInstanceState);
47 setContentView(R.layout.main);
48 pb=(ProgressBar)findViewById(R.id.pb);
49 tv=(TextView)findViewById(R.id.tv);
50
51 download = (Button)findViewById(R.id.download);
52 download.setOnClickListener(new View.OnClickListener() {
53 @Override
54 public void onClick(View v) {
55 DownloadTask dTask = new DownloadTask();
56 dTask.execute(100);
57 }
58 });
59 }
60
61 class DownloadTask extends AsyncTask<Integer, Integer, String>{
62 //后面尖括号内分别是参数(例子里是线程休息时间),进度(publishProgress用到),返回值 类型
63
64 @Override
65 protected void onPreExecute() {
66 //第一个执行方法
67 super.onPreExecute();
68 }
69
70 @Override
71 protected String doInBackground(Integer... params) {
72 //第二个执行方法,onPreExecute()执行完后执行
73 for(int i=0;i<=100;i++){
74 pb.setProgress(i);
75 publishProgress(i);
76 try {
77 Thread.sleep(params[0]);
78 } catch (InterruptedException e) {
79 e.printStackTrace();
80 }
81 }
82 return "执行完毕";
83 }
84
85 @Override
86 protected void onProgressUpdate(Integer... progress) {
87 //这个函数在doInBackground调用publishProgress时触发,虽然调用时只有一个参数
88 //但是这里取到的是一个数组,所以要用progesss[0]来取值
89 //第n个参数就用progress[n]来取值
90 tv.setText(progress[0]+"%");
91 super.onProgressUpdate(progress);
92 }
93
94 @Override
95 protected void onPostExecute(String result) {
96 //doInBackground返回时触发,换句话说,就是doInBackground执行完后触发
97 //这里的result就是上面doInBackground执行后的返回值,所以这里是"执行完毕"
98 setTitle(result);
99 super.onPostExecute(result);
100 }
101
102 }
103 }
[3] 下面看下程序的运行结果截图: