2010/10/31

為你的電腦降溫 cooldown CPU

請直接參考BBOY 寫的這篇 Frequency Scaling

在linux底下首先打開make menuconfig-> Power Management support --->
[*] CPU Frequency scaling --->
Default CPUFreq governor (userspace)
< > 'performance' governor
< > 'powersave' governor
-*- 'userspace' governor for userspace frequency scaling
< > 'ondemand' cpufreq policy governor
< > 'conservative' cpufreq governor

接著echo你想要的頻率到/sys底下的file node。
ex:"echo 500000000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
如果我們去查一下該目錄,可以發現
# ls -l /sys/devices/system/cpu/cpu0/cpufreq
總計 0
-r--r--r-- 1 root root 4096 2010-10-31 23:44 affected_cpus
-r-------- 1 root root 4096 2010-10-31 23:44 cpuinfo_cur_freq
-r--r--r-- 1 root root 4096 2010-10-31 21:39 cpuinfo_max_freq
-r--r--r-- 1 root root 4096 2010-10-31 23:44 cpuinfo_min_freq
-r--r--r-- 1 root root 4096 2010-10-31 23:44 cpuinfo_transition_latency
-r--r--r-- 1 root root 4096 2010-10-31 23:44 related_cpus
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_available_frequencies
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_available_governors
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_cur_freq
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_driver
-rw-r--r-- 1 root root 4096 2010-10-31 21:39 scaling_governor
-rw-r--r-- 1 root root 4096 2010-10-31 21:41 scaling_max_freq
-rw-r--r-- 1 root root 4096 2010-10-31 21:41 scaling_min_freq
-rw-r--r-- 1 root root 4096 2010-10-31 23:41 scaling_setspeed
drwxr-xr-x 2 root root    0 2010-10-31 23:44 stats
底下就試著....
# cd /sys/devices/system/cpu/cpu0/cpufreq
# cat cpuinfo_cur_freq
2000000
發現我的電腦目前的頻率也才 2000000, 似乎單位與原文中的不一樣。
後來我去試著用c3dl demo來衡量 CPU 速度,確實可以透過原文章中的方式調慢,我的命令如下:
# for i in 0 1; do echo 1000000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_setspeed; done

原文章有更多有用的資訊,有興趣的人請親自前往觀看

2010/10/25

cross compile busybox for android (為 android 準備 busybox)

我主要是參考cross compile busybox for android,大綱是:

1. 準備 cross compile 工具。
1. 這一項我原本試著用 ubuntu 的內建工具,也就是 xxxx-arm-linux-gnueabi 套件組,可是失敗。
2. 在文中提到可以自Download Sourcery G++ Lite Edition for ARM下載,請選『EABI』、『IA32 GNU/Linux TAR』,我下載的版本是 https://sourcery.mentor.com/public/gnu_toolchain/arm-none-linux-gnueabi/arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

3. 解壓後,我是放在 /usr/local/cross-arm 下

2. 若不想自己編譯,也可以從 busybox 網站直接下載執行檔,我試過可以執行的有 busybox-armv6l, busybox-armv5l, busybox-armv4tl

3. 下載 busybox source code, 上面執行檔最新的是 1.17.2, 但是 source code 是 1.17.3, 因此也可以自己編譯 最新的 busybox 1.17.3 source code
1. 解壓後,使用 make menuconfig 來選擇組態
2. Busybox Settings -> Build Options -> 裡面,挑下面的選項,將它編譯成靜態載入
[*] Build BusyBox as a static binary (no shared libs)
3. 在同樣的地方,挑 () Cross Compiler prefex,按 Enter 後必須填第一步安裝的 cross compile tools, 我的是:
/usr/local/cross-arm/bin/arm-none-linux-gnueabi-
確定後剛剛的選項會變成:
(/usr/local/cross-arm/bin/arm-none-linux-gnueabi-) Cross Compiler prefex
4. 在 Busybox Settings -> Installation Options-> 裡面,挑下面的選項,讓 busybox 可以不必安裝到 /usr 下
[*] Don't use /usr
註:1.19.3 版移到 Busybox Settings -> General Configuration -> 下面了
4. 上面的選項存檔、離開後,就可以用 make 來編譯
5. 放到 device 上,我是模擬機,道理一樣:
adb push busybox /data/busybox.exe
上面是故意改名字的,下一步要用到
6. adb shell:
# mkdir /data/busybox
# cd /data/busybox
# /data/busybox.exe --install .

7. 改變 PATH 環境變數
這一項比較麻煩,原則上就是要改變 system image, 所以有兩個方法,一個是自己改 ramdisk.img, 要用這一招的話請參考 busybox及bash在android中的安裝及init.rc修改
還有一個方法,就是第一點文中的方法,將系統重新掛載成 rewritable.....

su #取得root權限
mount -o remount,rw /dev/block/mtdblock6 /system #重新mount使/system可寫
mv busybox /system/bin/ #移動busybox
chmod 777 /system/bin/busybox #設為可執行
/system/bin/busybox --isntall .
mount -o remount,ro /dev/block/mtdblock6 /system #恢復/system為只讀

2010/10/12

android dynamic GUI 動態介面--範例程式

先來看看 config 檔,
$ cat Sample.xml

<?xml version="1.0" encoding="UTF-8"?>
<cmds>
<cmd text="Test1" path="Add\add" params="3 5"/>
<cmd text="Test2" path="Add\add" params="7 9"/>
</cmds>


$ cat Sample1.xml

<?xml version="1.0" encoding="UTF-8"?>
<cmds>
<cmd text="umount sdcard" path="/system/bin/umount" params="/sdcard"/>
<cmd text="top" path="/system/bin/top" params=""/>
<cmd text="reboot" path="/system/bin/reboot" params=""/>
</cmds>


範例程式如下:

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import android.view.View;
import android.widget.LinearLayout;
import android.widget.Button;
import android.widget.TextView;

public class HelloAndroid extends Activity {
/** 底下這個是放分析 xml 完的內容,資料結構要自己再想過,或是直接以 DOM 的方式存取,而不必另外放也可以
也就是在外面也是用 Document doc 這個物件來存取
**/
String[][] items;

// 底下這三個是我們的 GUI 上會有的元件的「容器」
Button cmd[];
TextView cmdPath;
TextView cmdParam;

/** Called when the activity is first created. */
/** onCreate() 是每個應用程式的入口,所以算是一般 C 裡面的 main() **/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main); // 這個是原來的 HelloAndroid 範例程式,我們不需要原來的 layout 設計,用自己的方式
// 目前以 LinearLayout 來設計,可以改成矩陣式的,不過最好是可以容許橫拿直拿動態調整,第一版可以不必有此彈性功能
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);

// 呼叫我們的 XML file 分析載入函式
GetXMLInfo();

// 底下這三個是我們的 GUI 上會有的元件的「容器」
cmd = new Button[items.length];
cmdPath = new TextView(this);
cmdParam = new TextView(this);

/** 底下就是直接把 XML 內容, 也就是 items 拿來放到 GUI 上
資料結構可以改變,整個 GUI 也可以改變設計
**/
int iCmd;
for (iCmd=0; iCmd<items.length; iCmd++)
{
cmd[iCmd] = new Button(this);
cmd[iCmd].setId(iCmd);

/** 為每個 button 加上按鍵的事件以便做出反應 **/
cmd[iCmd].setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
cmdPath.setText(items[v.getId()][1]);
cmdParam.setText(items[v.getId()][2]);
}
});
cmd[iCmd].setText(items[iCmd][0]);
layout.addView(cmd[iCmd]); // 最後真正加到我們的 layout 中
}
// 上面的 for 迴圈是加按鍵,底下只是加上顯示訊息的文字區塊
layout.addView(cmdPath);
layout.addView(cmdParam);
setContentView(layout);
}
private void GetXMLInfo()
{
try{
File f=new File("/sdcard/Sample.xml");
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("cmd");

int _cmdLength = nl.getLength();
int _cmdAttributes=3;

items = new String[_cmdLength][_cmdAttributes];

for (int i=0;i<_cmdLength;i++){

items[i][0]= nl.item(i).getAttributes().getNamedItem("text").getNodeValue();
items[i][1]= nl.item(i).getAttributes().getNamedItem("path").getNodeValue();
items[i][2]= nl.item(i).getAttributes().getNamedItem("params").getNodeValue();

}

//System.out.println("cmd " + RecordS.length);

}
catch(Exception e){
e.printStackTrace();
}
}
}


執行時:
$ adb push Sample.xml /sdcard/Sample.xml
----呼叫該應用執行





----換成新的 GUI, 用新的 Sample1.xml 取代原先的 Sample.xml, 記得放的檔名是一樣的
$ adb push Sample1.xml /sdcard/Sample.xml
----呼叫該應用執行

android dynamic GUI 動態介面

--動態 GUI--
寫應用程式,動態 GUI 是常常會有此需求的,原則上Dynamic Layout 的簡單概念,可以參考這篇:
http://www.dreamincode.net/forums/topic/130521-android-part-iii-dynamic-layouts/

在網路上找到一個寶庫, 一堆 Android source code 含有 test tools:
http://devdaily.com/java/jwarehouse/android/
其中有一份 DynamicLayout() 的範例:
http://devdaily.com/java/jwarehouse/android/core/java/android/text/DynamicLayout.java.shtml

或者我們可以從底下的問題開始了解我在說什麼:
1. 有人問他想要從 XML 來動態呈現 GUI,但是求問者有些功能做不到
http://efreedom.com/Question/1-2901333/Dynamic-Layout-Change-Runtime
2. 所以有人就回答他,用 setLayoutParams() 或請參考:
http://efreedom.com/Question/1-2693744/Android-Runtime-Layout-Tutorial

--執行外部命令--
至於 Dynamic Layout 之後,每個按鈕的功能,就變成要處理 button event.....再加上執行外部命令功能
http://code.google.com/p/market-enabler/wiki/ShellCommands
想要完整的 code 的話,可以參考:
http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App

還有相對簡單的方法是用 Java RunTime:
http://developer.android.com/reference/java/lang/Runtime.html
如果要使用 RunTime 的話,要能夠對外部命令做 I/O, 完整範例可以參考:
http://devdaily.com/java/edu/pj/pj010016/