2012年8月1日 星期三

INTEL HEX 格式

Intel HEX是一個文字檔,用來用來紀錄相對應的二進制碼。

格式:
:llaaaatt[dd...]cc
||||||||||||||||`` CHECKSUM (Zero checksum)
|||||||||```````- DATA
|||||||``- TYPE
|||||||     `- 00 : data record
|||||||     `- 01 : end of file record
|||||||     `- 02 : expended segment address record
|||||||     `- 04 : expended linear address record
|||````- ADDRESS
|``- LENGTH
`-START - colon

範例:

:10010000214601360121470136007EFE09D2190140
:100110002146017EB7C20001FF5F16002148011988
:10012000194E79234623965778239EDA3F01B2CAA7
:100130003F0156702B5E712B722B732146013421C7
:00000001FF



  Start code
  Byte count
  Address
  Record type
  Data
  Checksum




參考資料:
http://en.wikipedia.org/wiki/Intel_HEX
http://www.keil.com/support/docs/1584/

2012年7月26日 星期四

再論Linux開機

從電腦上電到出現命令提示符號間,系統經過了許多血汗的努力,這過程在使用者角度上不太重要,但,如果想要定做一個小型的Linux系統,就需要了解Linux整個啟動的過程。

當電腦上電之後首先是執行BIOS的程式,接著由BIOS交接到磁碟機上的MBR,通常OS Loader會載到MBR,這Loader負責把OS 核心(Kernel)與rootfs檔案initrd.img載入到記憶體中,並把控制權交接給核心運作,之後會解開initrd.img到記憶體上,成為暫時的rootfs但是是在RAM上,被稱為initrd (INITial Ram Disk),解開的rootfs之中有init這檔案,核心會去執行它,init(or linuxrc)必須要可以執行,可以是Script,有人稱它為Application Manager,這程式接手之後就得負責把磁碟機驅動起來,之後要掛載檔案系統,建立一些必要的設備節點,最後是根目錄切換,切換之後再去執行新的目錄中的init,把完整的系統驅動起來。

  1. bootloader載入kernel及initrd
  2. kernel解開initrd,並釋放initrd所佔用的記憶體空間
  3. 將rootfs掛載到ram disk上
  4. 執行 init (initialization)
  5. 掛載真正的rootfs
  6. chroot執行/sbin/init
所以第一次掛載ramfs時候如果需要開機到RAID上,就需要修改initrd.img這檔案,驅動起RAID並且掛載上再切換到RAID上,或是需要掛載iSCSI的磁碟當成系統碟也是需要修改它,如果不夠了解整個開機過程,相信沒辦法做到這一點,如果不需要太多的程序來搶資源,也可以讓自己寫的程式去領PID 1來用,整個系統就幾乎是你的程式獨占資源,所以對這些程序流程理解的愈深,相對的擁有的自由度就愈高。

當我在做小型的Linux系統的時候,我只需要開機到ramfs,所以不再往下交到目標磁碟機手上,而是直接用ramfs就好,一般這種作法搞出來的嵌入式系統是整個運作在記憶體上,好處是掛掉隨便使用者亂關都沒事,反正下一次要用還是得重新載入到記憶體上,只要原始的檔案沒毀損就沒事,缺點就是要等載入跟解壓縮,如此一來開機時間就會拉長,在很多的網通設備、多媒體播放器上都是這樣搞,只是他們也得面臨到開機速度的挑戰,所以就會看到各家奇奇怪怪的加速手段。

 在kernel版本2.6之後,initrd改用cpio製作,可以稱做cpio-initrd,它不需要特殊的block device或loop back device,製作過程比較簡單,而2.6與2.4的差異可以參考這一篇文章寫的。

上頭說的流程是Kernel 2.6以後的版本,而對於開機流程相信查到的文件常常是叫你去改inittab這檔案,如果你跟我一樣是用ubuntu/Debian就會發現事情並不單純(李組長語調),傳統的作法繼承於Unix-Like底下System-V init的作法,但是之後因為一堆隨身碟、硬碟、、、等隨插即用的東西出現,這個系統變得不太能夠適應,新的需求對於軟硬體的啟動、停止、掛載、移除,需要服務可以動態的啟動,傳統的sysVinit是基於runlevel的系統,使用runlevel(單、多使用者以及其它level)和鏈接(於/dec/rc?.d目錄,分別鏈接到/etc/init.d的init script)來啟動和關閉服務,而Ubuntu使用的是UPStart-Init則是基於事件的系統,它使用事件來啟動和關閉系統服務,傳統的SysVinit還有一個缺點,就是啟動需要跑一堆shell script,好處是很容易改,但是缺點是「慢」,這個缺點是從MacOS學到的教訓,在相同的位置上Solaris使用SMF(Service Management Facility),而Mac OS則使用Launchd,而Ubuntu則是傾向集這些軟體的優點於一身。

使用上也真的比較快,開機真的快多了,而且對於裝置服務的反應以比較靈敏,新的CPIO省去一次載入核心的時間,而init省去shell script運作產生的浪費,目前最耗時間的還是載入rootfs的時間(壓縮比加到頂也沒小多少,但是就明顯感覺核心解壓縮有點燒到點時間)。

sysVinit
  • initScript /rc script
  • rc => run commands
  • /etc/rc.d/init.d
  • /etc/inittab
    • id:5:initdefault:
  • /etc/rc.d/rc5.d
    • exp:
    • /etc/rc.d/rc5.d/K36mysqld
    • link to ../init.d/mysqld
    • K36mysqld
      • K : Kill/Start
      • 36: boot sequence
      • mysqld: service name
  • runlevel設定相互獨立
UPStart
  • event-driven/-based
  • 理順服務依賴關係以便實現平行啟動
  • 按需求啟動
  • Upstart job script
  • 有關UPStart相關的說明可以參考這一篇文章
也就是init最後不要交到真的磁碟機的/sbin/init而是交到ramfs裏面的/sbin/init,如果是用UPStart的服務,則是要搬相對的資料給他用,/etc/init目錄下的東西,底下的東西是.conf只是設定檔而已,不是shell script,而也要順便拷貝/etc/init.d目錄下的東西,除此之外還有相對應的設定檔也要拷貝,比如說ssh,除了init或init.d之外,還放了一個/etc/ssh/的目錄,也要順便拷貝走,與DNS相關的是/etc/hosts、/etc/resolv.conf、/etc/nsswitch.conf這3個設定檔,與帳號、密碼相關的設定檔是/etc/passwd、/etc/shadow、/etc/group這3個,如果說認証上有問題要注意/etc/pam.d/,PAM(Pluggable Authentication Modules),要順便注意/etc/nologin、/etc/securetty、/etc/security/*這堆。



2012年7月12日 星期四

我真的很懶嗎?


我一直覺得,我還蠻懶惰的,不喜歡做一堆重複的工作,寧願認真做完一次,寫個code,叫電腦自動做,也不願意重複的命令一直打,感覺這種行為很浪費生命,明明自動程序在跑幾秒鐘就沒事了,要燒個一天去做就感覺很白痴。

底下兩段CODE是把當下的UBUNTU或DEBIN系統抽出來做一個ROOTFS,也就是自動做出initrd.img的腳本,用Perl寫這種腳本還蠻快的,而且很好寫,主要是autofs.pl在運作,poCmd.pl是讀取cmd.list內容,讓autofs.pl去呼叫,poCmd.pl會按照cmd.list內列出來的命令,逐一拷貝到/bin底下,順便把需要的動態庫檔案也拷貝進去,後面要把busybox支援的命令在/bin底下做一個soft link,讓系統起來之後有一些基本的命令可以用。

原理就上一篇講的那些做一個自動腳本,把目前的系統抽一個initrd.img的小rootfs出來用,讓系統開機使用RAM DISK的ROOTFS運作,也就是有一些系統商做的小LINUX系統的搞法。

這種系統就是比誰做的小,也就是要做剛好的系統,這有兩個大原則,一個是只載入要用的模組,另外一個是只放需要的命令,所以不要白痴的把所有的模組都放在裏面,也不需要把沒用到的動態函式庫放進去,這樣會讓你做出來的ROOTFS會肥到百M的尺寸,要小,這就需要挑,挑的方法也很簡單,就先看目前系統需要哪些模組,lsmod這個命令可以列出目前系統載入了哪些模組,之後靠modinfo -n去看那個檔案放哪,只抓要用到的東西,另外有些命令用到動態庫,要調用ldd -v 命令去看用了哪些動態庫,只需要拷貝要用到的動態庫就好,這樣才能夠做出比較小的系統,我做出來的initrd.img大概就16M左右,事實上還好沒很肥,反正是自動做的,這大小還可以接受。

本來只是要我做個小系統,讓測試人員可以直接開進去使用,要穩、好拷貝,所以才要我搞這個,我也是努力的花了一星期(含其他案子同時進行)搞出來,下次就開腳本去抽就有了,不需要再來煩我~~XD。

當然不免俗的這程式有BUG(我知道有個問題),有看出來的可以留言,我們討論一下~~XD


poCmd.pl

#!/usr/bin/perl -w

open FH,"<../cmd.list";
foreach my $line(< FH >){
 chomp($line);
 if($line ne ""){
 my $limitCounter=0;
 DOAGAIN:
  my @paths=("/bin/","/sbin/","/usr/bin/","/usr/sbin/");
  print "$line";
  my $found=0;
  foreach my $path(@paths){
   if(-e "$path$line"){
    print "\t- $path$line\n";
    system "cp $path$line bin/.";
    my @vars=`ldd -v $path$line | grep lib | grep :\$ | cut -d ':' -f 1`;
    foreach my $var(@vars){
     chomp($var);
     $var =~ s/\t//g;
     $var =~ s/\ //g;
     print "\t$var\n";
     my $libPath="lib/.";
     #$libPath = "lib64/." if($var =~ /x86\_64/i);
     system "cp $var $libPath";
    }
    $found = 1;
    $limitCounter=0;
    last;
   }
  }
  if($found == 0){
   print "Can't found command exist!";
   system "sudo apt-get install $line";
   exit 1 if($limitCounter >= 3);
   $limitCounter++;
   goto DOAGAIN;
  }
 }
}

close FH;

#process busybox softlink

print "make busybox command list\n";
chdir "bin/";
my @vars = `busybox | grep \,\ `;
foreach my $var (@vars){
 if($var !~ /copyright/i){
  chomp($var);
  $var =~ s/\ //g;
  $var =~ s/\t//g;
  my @cmds = split /\,/,$var;
  foreach my $cmd(@cmds){
   if($cmd !~ /\[/){
    print "[busybox command]\t$cmd\n";
    system "ln -s busybox $cmd";
   }
  }
 }
}

autofs.pl

#!/usr/bin/perl -w

use File::Basename;
#Auto make rootfs on Debin/Ubuntu
#Author Jones
print "Auto make rootfs for Debin/Ubuntu\n";
print "Author Jones Lai\n";

my $var = `uname -a`;

if(($var !~ /ubuntu/i)&&($var !~ /debin/i)){
 print "This script just made for Debin/Ubuntu\n";
 exit 1;
}

$var = `dpkg -l`;

if($var !~ /build\-essential/){
 print "Require build-essential\r\n";
 system "sudo apt-get install build-essential";
}

my @kernels = `ls /lib/modules/`;

@kernels = sort {$b cmp $a} @kernels;

my $lastKernel = $kernels[0];

chomp($lastKernel);

print "Last kernel version is $lastKernel\n";

if(!(-e "vmlinuz")){
 print "copy kernel to local\n";
 system "cp /boot/vmlinuz-$lastKernel ./vmlinuz";
}
if(!(-e "initrd.img")){
 system "mkinitramfs -o initrd.img $lastKernel";
}
if(!(-e "tmp")){
 system "mkdir tmp";
}else{
 system "rm tmp/ -fr";
 system "mkdir tmp";
}

chdir "tmp/";
system "gunzip < ../initrd.img | cpio --extract --preserve --verbose --no-absolute-filenames";
my @modules = `lsmod`;

open(FH,">conf/modules");

foreach my $module(@modules){
 chomp($module);
 next if($module =~ /module/i);
 my ($MOD,$others) = split /\ +/,$module;
 print FH "$MOD\n";
 my $var = `modinfo -n $MOD`;
 chomp($var);
 my $dirname  = dirname($var);
 system "mkdir -p .$dirname/\n";
 system "cp -p $var .$var\n";
 print "[copy module]: $var\n";
}
close(FH);

system "perl ../poCmd.pl";

system "cp ../init init";
system "chmod +x init";

$var = `find . | cpio --create --format='newc' > ../newinitrd`;
print "$var\n";
$var = `gzip ../newinitrd`;
print "$var\n";
$var = `mv ../newinitrd.gz ../newinitrd.img`;
print "$var";
$var = `rm ../initrd.img` if(-e "../initrd.img");
$var = `mv ../newinitrd.img ../initrd.img`;

chdir "../";

2012年7月5日 星期四

運用ubuntu的initrd.img檔案作個小系統

syslinux


#dd if=/usr/lib/syslinux/mbr.bin of=/dev/sdx bs=512 count=1
#syslinux -sf /dev/sdx


syslinux.cfg
TIMEOUT 20
DEFAULT linux
LABEL linux
KERNEL vmlinuz
APPEND initrd=initrd.img
rootfs
直接叫ubuntu的工具做出來
mkinitramfs -o initrd.img /lib/modules/2.6.22-14-generic


1. 解開initrd.img
#cp initrd.img initrd.gz
#gunzip initrd.gz
#mkdir tmp2
#cd tmp2
#cpio -id --no-absolute-filenames < ../initrd

#cd tmp2
#gunzip < ../initrd.img | cpio --extract --preserve --verbose --no-absolute-filenames


2.壓縮initrd.img
#cp initrd.img initrd.img.org
#rm initrd.img
#cd workTemp
#find . | cpio --create --format='newc' > ../newinitrd
#gzip ../newinitrd
#mv ../newinitrd.gz ../newinitrd.img
#mv ../newinitrd.img ../initrd.img


修改init文件,主要是插入busybox的soft link,把命令指到busybox上

需要載入的核心模組修改conf/modules檔案。

拷貝命令到/bin底下,拷貝進去不見得就可以使用,還需要補足用到的動態函式庫,此時ldd命令就很重要。
比如說拷貝了perl命令

#ldd -v /usr/bin/perl

linux-gate.so.1 =>  (0x00d6b000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x00df2000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x003cf000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x008bf000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x001ad000)
libcrypt.so.1 => /lib/tls/i686/cmov/libcrypt.so.1 (0x00c14000)
/lib/ld-linux.so.2 (0x00e6c000)


Version information:
/usr/bin/perl:
libcrypt.so.1 (GLIBC_2.0) => /lib/tls/i686/cmov/libcrypt.so.1
libdl.so.2 (GLIBC_2.1) => /lib/tls/i686/cmov/libdl.so.2
libdl.so.2 (GLIBC_2.0) => /lib/tls/i686/cmov/libdl.so.2
libpthread.so.0 (GLIBC_2.2) => /lib/tls/i686/cmov/libpthread.so.0
libpthread.so.0 (GLIBC_2.0) => /lib/tls/i686/cmov/libpthread.so.0
libm.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libm.so.6
libc.so.6 (GLIBC_2.4) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.3.2) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.11) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.1.2) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libc.so.6
/lib/tls/i686/cmov/libdl.so.2:
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
libc.so.6 (GLIBC_2.1.3) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib/tls/i686/cmov/libc.so.6
/lib/tls/i686/cmov/libm.so.6:
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
libc.so.6 (GLIBC_2.1.3) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libc.so.6
/lib/tls/i686/cmov/libpthread.so.0:
ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
libc.so.6 (GLIBC_2.1.3) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.3.2) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libc.so.6
/lib/tls/i686/cmov/libc.so.6:
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
/lib/tls/i686/cmov/libcrypt.so.1:
libc.so.6 (GLIBC_2.1.3) => /lib/tls/i686/cmov/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libc.so.6


函式庫還是要補上才可以使用,不然一執行就會出現錯誤訊息說有缺

2012年6月28日 星期四

保險佔了總收入的三分之一!!!

最近聽到同事生活吃緊,老是在哎哎叫,收入已經不夠優渥了,還讓保險吃掉總收入的三分之一,這讓我著實吃驚,感覺非常的...累人。

我想保險有幾個黃金原則:

  • 不能超過總收入的一成
    • 正如底下圖所顯示的一樣(引用來源)。
    • 試問當你都沒錢繳保費了,保障怎麼維持下去
    • 總不能不吃、不喝、不住吧
    • 所以當你保險費用已經佔了總收入的三分之一,是不是要剛好與投資理財對調呢?
    • 這樣理財的效率會不會太差一點,這兩種方法產生的財富我相信幾年之後會差很大,畢竟一年差了20%的投資金額,以最保守的定存來算也會差很多。


  • 會影響家計的成員最優先投保
    • 是有在工作的人失能對家計影響大,還是沒在工作的成員失能對家計影響大?
    • 當你選擇去保沒在工作的家庭成員時,難道不會影響到有在工作的成員的保險預算嗎?(如果你錢跟郭董一樣多,那幹嘛保險?)
    • 沒有扛家計責任的人湊熱鬧,在保什麼險?
    • 老婆沒在工作保費比較低,老公有在工作保費比較高,應該要替誰買保險?
    • 當然是老公阿!當有在工作的家庭成員失能時,你認為老婆的保費誰要繳?怎麼繳?難道拿保單去借錢來繳!?這不是本末倒置嗎?
    • 兒童壽險政府已經告訴你不能保,還是很多家長莫名其妙的想保,還來個保險最後限時搶購的戲碼,小孩又不是家中的經濟支柱,講句不好聽的實話,掛掉對你家計有什麼影響?莫名其妙,這些錢拿來保家長不是比較有價值嗎?
    • 家中的經濟支柱才需要保險,那是因為這個保險是為了防止意外,產生家中的經濟振盪,讓其他不事生產的成員產生突然而來的經濟壓力,而你保在這些成員身上,反而不去加碼在經濟支柱上,對家中的經濟穩定除了沒貢獻之外,還會造成更大的風險,當家中經濟支柱出現狀況時,其他成員反而要支付保險費,不是嗎?都沒在賺錢怎麼辦?此時保險公司還會來要你拿保單借錢,借不用還嗎?不是都是你的錢嗎?而且經濟結構都出現問題了,怎麼賺來還保險費?
    • 要我說,沒經濟產出的家庭成員,根本就不需要保險,風險高的經濟支柱,保險公司也不太想讓你保,風險高保費自然就高,這也本末倒置。
    • 你可以參考怪老子這一篇的文章,他觀念我還蠻認同的,而且還有EXCEL檔案帶算式可以精算一下。
  • 買保險不要想賺錢
    • 想想保險公司養那麼多業務、行政、肥貓不用錢嗎?
    • 那保險產生的利潤怎麼算?
    • 事實上可以看綠角的筆記,利率是保費定價的基礎之一,也就是說定存目前的利率會影響到你的保費,如果說定存利率愈高,相對的你的保費就愈低,反過來定存的利率愈低,相對的保費就愈高,為什麼?
    • 保險公司拿了錢放著不會生利息嗎?除了算死差益之外還是要賺利差益的部份阿,利差益就是保險公司預定的利率要低於定存阿,也就是你付出去錢有一部份的比例會押在定存上生利息,當然設計保單會依照利率來算計你的保費阿!不然怎麼賺錢?萬一賺的錢不夠支付支出時,難道要保險公司賠錢嗎?
    • 儲蓄險的利率不太可能高過定存利率,保險業務員會以總利率跟定存的年利率來比較,讓他家的儲蓄險看起來好像有點價值,但是一旦除以你投入時間就會發現,保單給的利息低的可憐,而且通常會比定存還要低,這很沒效率,所以買保險不要想賺錢!
    • 以我媽那張超爛的人情保單來說,躉繳(一次繳清)60萬,6年利率約是5%,5%看起來是比定存高,但是那是6年,定存利率指的是年利率,小時候老師有說不同單位不能來比較,沒忘的話拿起國小數學的除法來算,6年利率轉成年利率只需要除以6就好,這簡單阿!那就是0.8%嘛,這不只是低,還超低,而且低的可憐,而且還是單利,不像定存是複利在算,這就會差很大,以目前定存利率3年的利率1.4左右來算,大概是六十5萬兩千多元,而六年一次的單利則是六十三萬而已,也就是說,已經差了兩萬多,更不用說以前利率應該是2.2%左右,那應該是六十八萬四千多左右,這些錢到哪去了,當然是拿去給保險公司當規費去了,況且還有你的保險費要付,所以我可以說,大概是6年5萬多的差額給了保險公司,這不是在花錢嗎?所以買保險是在賺錢還是在賠錢?我對保障的內容更不滿意,保額根本沒多少。當真的經濟出現點問題的時候,那更慘,跟保險公司借錢?你的錢借出來還要付他們利息,解約還要付違約金,當初還是先扣掉規費才去算利息,也就是說我所謂的5%算出來的金額還高估了點,這合約真是爛透了。而且當你缺錢的時候要用,解約要按照年份賠錢,保單質借利息4.4%,而且是年利率複利喔,也就是說他在算目前的利率還是拿以前2.2%直接乘2喔,所以把錢拿去存保險公司是非常不划算的一件事情,比存定存還糟糕,而且簽下去就變成你欠他錢而且還是躉繳了狀態下也是欠保險公司錢。
    • 投資型保單也一樣,基金要帳戶保管費、外幣要手續費、、、等阿哩阿雜的費用要付掉,而且是先扣掉,後面才是拿去投資的,保險公司要的真是一毛都跑不掉,萬一跌破淨值呢?那是你的風險,對他們而言該扣還是要扣,他不會可憐你血本無歸的。
    • 所以保險不要想賺錢,那是在消費,那是在買商品,你面對的是保險「業務員」。

2012年6月20日 星期三

軟體外包印度真的有效率嗎?

底下這個code會讀取XLM的檔案,把內容透過PC的RS232 PORT傳送到LCM上,並且等著接收模組上按鍵回送的鍵盤碼,這程式只有40行還含註解,算是十分簡單的DEMO程式,可是測試LCM的DEMO程式要XML幹嘛阿?

這故事要說到印度阿三,東ㄠ西ㄠ的鬼叫LCM不會動,一下子懷疑電路有問題,一下子不會用Perl,搞得我火都上來了,就圖文並茂的必殺技開下去,後來乾脆把keypad的問題也搞定掉算了,就把原先的只會傳送資料出去的code改成收送都可以的版本,而讀XML就他X的奇怪,最好是跟我說他們軟體想要怎麼用,要去XML讀檔,拿到裏面的欄位阿,想要怎樣...怎樣啦!

挖賽~趕情是當成是在開軟體需求了勒!

我也真他X的仁慈,還幫他們把這XML功能寫上去(雖然對我沒難度,但是還是要哎一下),之前還說要改成我們的模組他們軟體要開發一個月(最好寫個小UI改IP要一個月啦),算了,以他們這種程度,真的沒幾個月搞不下來,他X的我就只有幾個小時可以搞,阿是怎麼樣。

軟體外包給印度搞真的有效率嗎?(可能只是因為這個客戶很病而已...其實人家印度還是很強的...話說現在隨便一隻手機都強過太空梭發射的時代...台灣還是沒發射火箭上去阿...)

#!/usr/bin/perl -w

use Device::SerialPort;
use XML::Simple;

$xml = new XML::Simple;

if(!(-f "data.xml")){
 print "Can't found XML file!\r\n";
 exit 1;
}

$data = $xml->XMLin("data.xml") or die "Can't open XML file!\r\n";

print "$data->{DATA}\r\n";

#Open port with parameter 9600n81
my $port = Device::SerialPort->new("/dev/ttyS0");
$port->databits(8);
$port->baudrate(9600);
$port->parity("none");
$port->stopbits(1);

#write data via serial port
#see LCD_COMMANDS.pdf page 1
#table for function/command
#0xF8 0x01 = Clear screen
#The following data will clear screen first then send your XML data

$displayStr = sprintf("%c%c",0xF8,0x01);
$port->write("$displayStr");
sleep(1);
$port->write("$data->{DATA}");

while(1){
 my ($count, $string) = $port->read(1);
 if($count > 0){
  print "Keycode = ".unpack("H*",$string)."\r\n";
 }
}

2012年6月19日 星期二

龜山工業區廠商名單

今天去工業局查一下龜山工業區的廠商名單,好當成找工作的參考依據,可惜那介面要按照種類去搜尋,使我非常不滿意,所以我希望能夠直接下載到名單,而不是在那裡操作個老半天,我發現他點進去各家廠商的資料是用網址欄的一個變數區分,這讓我有了想法,拿我那個超強的webTableKiller.pl的script來切切看,果不其然,效果超好的。

底下是列出來的名單:
公司名稱住址狀態產業類別
台達電子工業股份有限公司桃園市興隆路14號未建廠電腦、電子產品及光學製品製造業
杏隆實業股份有限公司桃園廠興隆路九號生產中紡織業
其洋股份有限公司興隆路八號生產中紙漿、紙及紙製品製造業
利華實業廠股份有限公司興隆路六之二號歇業紡織業
同良機械有限公司興隆路六之一號生產中機械設備製造業
名超企業股份有限公司桃園廠興隆路七號生產中塑膠製品製造業
源新織造廠有限公司桃園市興隆路6號停工紡織業
泰山電子股份有限公司興隆路四號生產中電腦、電子產品及光學製品製造業
昶維實業股份有限公司桃園縣桃園市興隆路三號生產中紡織業
杉信實業股份有限公司建國東路17號生產中塑膠製品製造業
三洋紡織纖維股份有限公司建國東路二四號生產中紡織業
三洋紡織纖維股份有限公司桃園二廠建國東路二六號生產中紡織業
振湧織造廠股份有限公司建國東路二八號生產中紡織業
昇頡實業股份有限公司建國東路34號2、3、4樓生產中紡織業
德星電子股份有限公司興隆路五號生產中電子零組件製造業
台灣富士全錄股份有限公司桃園縣桃園市興邦路四○號生產中電腦、電子產品及光學製品製造業
復盛應用科技股份有限公司一廠興中街9號生產中基本金屬製造業
友聯車材製造股份有限公司興中街一號生產中其他運輸工具製造業
萬坤股份有限公司興中街三號生產中紡織業
利百代國際實業股份有限公司桃園廠大誠路二號生產中其他製造業
利百代國際實業股份有限公司桃園二廠大誠路二之一號生產中基本金屬製造業
南亞食品工業股份有限公司桃園縣桃園市桃鶯路四一一號生產中食品製造業
恆新紡織(股)公司桃園市桃鶯路439號公告註銷紡織業
元隆汽車股份有限公司桃園市桃鶯路441號生產中汽車及其零件製造業
臺灣固特異股份有限公司桃園工廠桃鶯路四五一號歇業化學製品製造業
桃苗汽車股份有限公司桃園市桃鶯路445號生產中個人及家庭用品維修業
欣興機械工業有限公司大智路八號生產中金屬製品製造業
臺隆工業股份有限公司桃園工廠興華路一四號生產中食品製造業
嘉成建材工業股份有限公司興華路16號生產中金屬製品製造業
正裕特殊金屬股份有限公司興華路一九號生產中基本金屬製造業
來緯實業股份有限公司桃園市興華路10號停工
台灣表面黏著科技股份有限公司興華路七號生產中電腦、電子產品及光學製品製造業
緯聯企業股份有限公司興華路五號生產中紡織業
杉信實業股份有限公司二廠5鄰興華路3號生產中金屬製品製造業
新生銲條工業股份有限公司大智路11號1樓生產中金屬製品製造業
龍膳坊企業有限公司龜山廠桃園縣龜山鄉山鶯路163之1號生產中食品製造業
榮恆興業有限公司興邦路41號生產中機械設備製造業
英屬維京群島商太古可口可樂股份有限公司台灣分公司桃園廠興邦路46號生產中飲料製造業
上展金屬工業股份有限公司桃園廠桃園縣桃園市興邦路三九號生產中金屬製品製造業
大宇紡織股份有限公司桃園一廠興邦路四二號生產中紡織業
欣興電子股份有限公司興邦廠興邦路38號歇業電子零組件製造業
南僑化學工業股份有限公司桃園廠興邦路35號生產中食品製造業
台灣富士全錄股份有限公司第二廠興邦路三六號生產中電腦、電子產品及光學製品製造業
友霖生技醫藥股份有限公司桃園製藥廠大誠路11號生產中藥品製造業
美達工業股份有限公司山頂村興邦路三一號生產中金屬製品製造業
仁美織造有限公司桃園縣龜山鄉龜山工業區建國東路四○號生產中紡織業
台灣獅王化工股份有限公司桃園工廠山鶯路一六○號歇業
台灣富貴電子工業股份有限公司山鶯路一五八號生產中電子零組件製造業
新將軍股份有限公司桃園廠山鶯路一五六之二號一樓生產中電腦、電子產品及光學製品製造業
佳世達科技股份有限公司桃園廠山鶯路157號生產中印刷及資料儲存媒體複製業
正洸股份有限公司桃園廠山鶯路198之2、198之4號生產中成衣及服飾品製造業
美德耐股份有限公司桃園縣龜山鄉山頂村興業街2號生產中
和碩聯合科技股份有限公司桃園廠興業街5號、5號2樓之1(第三層)、5號7樓之1、5號8樓之1生產中電子零組件製造業
理隆纖維工業(股)公司桃園廠龜山鄉興業街9號1樓歇業紡織業
東方石材股份有限公司桃園縣龜山鄉山福村頂興路六○號歇業
裕器工業股份有限公司桃園廠山鶯路一六三號歇業
台達電子工業股份有限公司桃園二廠山鶯路252號1樓及3至10樓生產中電子零組件製造業
旺機針織有限公司桃園廠中興路1之1號1樓生產中紡織業
中誠企業股份有限公司中興路二號生產中紡織業
力儂企業股份有限公司山鶯路二九○號生產中紡織業
廣大飼料(股)公司桃園廠龜山鄉山鶯路169號歇業食品製造業
兆豐國際商業銀行龜山倉庫龜山鄉山鶯路344號生產中其他製造業
富祐鴻科技股份有限公司山鶯路350號生產中電腦、電子產品及光學製品製造業
香榮實業股份有限公司山鶯路國光巷一號生產中紡織業
福大化學工業股份有限公司山鶯路國光巷三號生產中化學製品製造業
欣興電子股份有限公司精密載板事業部三廠山鶯路173-1、173-2、171-2、173-8號生產中電子零組件製造業
台灣立凱電能科技股份有限公司桃園縣桃園市大林里興華路2-1號生產中
晟峰精密工業股份有限公司山鶯路中華巷2之1號(1、2樓)、2之1號3樓生產中塑膠製品製造業
啟利實業股份有限公司山鶯路文華巷2號生產中紡織業
瑞怡造漆有限公司桃園廠山鶯路171-1、171-5號生產中化學製品製造業
佳世達科技股份有限公司雙星廠山鶯路159號1、5、7樓生產中電子零組件製造業
綠德富股份有限公司大智路6、6之1號生產中電子零組件製造業
高菖企業股份有限公司建國東路19號生產中化學材料製造業
旭慶光電股份有限公司山鶯路國光巷6號生產中機械設備製造業
科嶠工業股份有限公司桃園廠桃園縣龜山鄉山頂村山鶯路華玉巷3號生產中機械設備製造業
山福工業股份有限公司桃園縣龜山鄉龜山工業區興邦路33號生產中機械設備製造業
利樂科技股份有限公司大林里大誠路六號歇業橡膠製品製造業
臺灣華歌爾股份有限公司二廠興邦路二七、二九號生產中成衣及服飾品製造業
來佳針織廠股份有限公司桃園廠建國東路二五號一樓歇業成衣及服飾品製造業
凱崴電子股份有限公司桃園廠興邦路32號1、2、3樓生產中金屬製品製造業
桃園汽車客運股份有限公司修車廠興中街五號生產中汽車及其零件製造業
四維精密材料股份有限公司桃園廠興華路12號生產中紙漿、紙及紙製品製造業
中國電器股份有限公司桃園廠興華路一八號生產中電力設備製造業
臺灣華歌爾股份有限公司一廠興邦路二九之一號生產中紡織業
上展金屬工業股份有限公司桃園二廠興邦路37之1號生產中基本金屬製造業
台灣電力股份有限公司龜山鄉興邦路37號電力設備製造業
全廣食品有限公司桃園廠大誠路四號一樓生產中食品製造業
謹成工業股份有限公司桃園廠大智路九號生產中電子零組件製造業
銓銘金屬工業股份有限公司龜山廠山頂村山鶯路三五八號生產中基本金屬製造業
星大精密股份有限公司興華路6號1樓生產中金屬製品製造業
台達電子工業股份有限公司桃園廠興邦路三一之一號生產中電子零組件製造業
新立汽車有限公司桃園縣桃園市大林里大誠路3號生產中個人及家庭用品維修業
興磊科技股份有限公司興中街2號生產中金屬製品製造業
隆億服裝材料廠股份有限公司興業路三一號生產中紡織業
東正元電路工業股份有限公司桃園廠桃園縣桃園市大誠路10號歇業電子零組件製造業
棋傑企業有限公司桃園廠大豐路4號生產中金屬製品製造業
宜美不銹鋼工業有限公司桃園縣桃園市桃鶯路445之1號1樓生產中家具製造業
金永興科技股份有限公司大誠路7號2樓生產中機械設備製造業
福翁工業股份有限公司桃園廠大智路一○號生產中汽車及其零件製造業
裝宏企業有限公司桃園廠興華路1號3樓生產中化學製品製造業
復盛應用科技股份有限公司三廠興華路一之二號生產中金屬製品製造業
裕隆汽車製造股份有限公司工程中心試造工廠桃園縣桃園市興邦路四五之二號生產中汽車及其零件製造業
翊聖企業股份有限公司興邦路三三之一號生產中塑膠製品製造業
鍵銓精密工業有限公司頂興路六四巷一號歇業
欣興電子股份有限公司精密載板事業部一廠山鶯路175-1號生產中電子零組件製造業
勵精股份有限公司桃園工廠興華路二號歇業紡織業
和益貿易股份有限公司龜山廠山鶯路一五六之五號生產中紙漿、紙及紙製品製造業
摩托迪克股份有限公司桃園廠興業街二七號二、三樓生產中電力設備製造業
益茂國際有限公司頂興路六四巷三號生產中紡織業
達方電子股份有限公司精機廠山鶯路167號生產中塑膠製品製造業
協隆針織廠頂興路六四巷五號歇業
良器有限公司建國東路32之1號1、2、3樓生產中塑膠製品製造業
名檠科技股份有限公司興邦路39之11號歇業塑膠製品製造業
龍億精密工業股份有限公司興邦路39之9號生產中金屬製品製造業
泳達精密科技股份有限公司龜山廠興邦路39-5號生產中電腦、電子產品及光學製品製造業
上展金屬工業股份有限公司桃園市大林里興邦路39之3號生產中金屬製品製造業
台灣科萊恩化學股份有限公司桃園化工廠興邦路3○號生產中化學製品製造業
萬錩實業有限公司頂興路六四巷八號生產中塑膠製品製造業
元大電子股份有限公司桃園廠山鶯路三四○巷一號生產中電腦、電子產品及光學製品製造業
憶全企業股份有限公司山鶯路三四○巷八號生產中電腦、電子產品及光學製品製造業
立昌先進科技股份有限公司龜山廠山鶯路三四0巷六號生產中電子零組件製造業
佳豪實業股份有限公司興邦路三九之六號生產中紡織業
中榮彈簧股份有限公司山鶯路三四0號生產中金屬製品製造業
毅昌精密工業有限公司桃園縣龜山鄉山福村頂興路六四巷九號一樓生產中機械設備製造業
台錦工業廠有限公司二廠桃園縣龜山鄉山福村頂興路六四巷七號生產中塑膠製品製造業
佳總興業股份有限公司興邦路39之2、39之4號生產中電子零組件製造業
維倫紡織股份有限公司山鶯路340巷2號生產中紡織業
信東生技股份有限公司祐益廠桃鶯路445之2號2樓生產中化學製品製造業
綿春纖維工業股份有限公司桃園廠興業街一三號生產中紡織業
底下是把龜山工業區廠商名單全部印出來的code。
#!/usr/bin/perl -w

for$i (1..999){
 $url=sprintf("http://www.moeaidb.gov.tw/iphw/gueishan/factory.do?method=goContent&fn=%04d-00&unitId=0511012",$i);
 #print "$url\r\n";
 $ret=`perl webTableKiller.pl big5 \"$url\" 龜山工業區廠商資料.csv`;
 if($ret ne ""){
  print "$ret\r\n";
 }
}

2012年6月17日 星期日

e-Tag 這怪異的系統

有誰注意到你信用卡刷下去之後,到收到簡訊中間差了幾秒鐘?

為什麼你過收費站之後,卻需要兩天才會知道扣款的狀況?

官方說法是「人工」計算需要時間,我是覺得還蠻詭異的,把「人工」從收費亭趕出來,讓財團請「人工」作業,這是什麼邏輯阿!

車牌辨識需要人工不是十分合理,以現行的系統準確率大概9x%,也就是不到10%的量需要人工辨識之外,其他的資料電腦去影像辨識就應該可以立刻判斷,並寄送出資訊,而用信件寄送也是莫名其妙的作法,為什麼不像信用卡用簡訊發通知呢?

難道就純粹是要整不與財團合作用路人嗎?(最好處理費用那麼貴啦)

對於不安裝e-tag的用路人通過,影像辨識系統會抓到車牌號碼,如果有登記手機號碼,只需要發送簡訊給用路人,再去繳費即可,政府整天要節能減碳,然後狂發紙張信件,狂讓郵差燒汽油,這有問題吧!

廠商搶錢隨便找理由,政府官員就無腦接受這種有病的系統,還寄信件勒!

系統需要兩天真的是超級令人震憾的,兩天對電腦處理的速度來說,就好比人類旅行太空用光年計算,不知道跑幾百萬光年去了,信用卡的反應速度才是正常的吧!

如果正如廠商官方說法一樣,用人工在運作系統,這也太神奇了吧!

不是就系統抓取資料之後判斷、分流(e-tag、影像辨識、需要人工辨識) ,送到資料庫中,隨便抓台modem array,把沒裝e-tag有電話的用路人資料query出來用modem送簡訊出去,剩下沒辦法處理的才去寄信件,寄信都沒回的就去寄罰單,電腦在做需要兩天?


怎麼可能,這種速度,我想真的是人工,如果真的用人工,政府官員也有問題吧!
這種技術有問題的廠商還在用喔,讓廠商隨便開規格,隨便定規矩,最好是罰款也隨便一點,政府官員對財團都可以很隨便,但,對百姓罰單卻很精實,對颱風假也很死版,最好這就是依法行政啦!

2012年4月26日 星期四

USB vs SATA

在看結論之前,先讓我碎碎念一下,學問、學問,要學就要問,但是也不能一遇到問題就急著問人吧!

STFW,明明網路上有人好心的把測試數據擺上讓你比較,問者那到底有花多少時間搜尋,以及研究呢?

如果說是外行的在問就算了,IT工程師耶!

IT工程師需要一定的水準,對數據這麼不敏感,又不去找答案,學歷搞高了也沒用,發展也有一定的限度。

我花了幾分鐘,用網路上找到的數據資料,結論來看,SATA還是比較快,eSATA又幾乎是指改了物理層的連接器跟線而已,所以eSATA原則上與SATA差距不大,SATA 6G與USB3.0比較的話卻差了將近30%左右,還是SATA比較快,SATA 3G與SATA 6G比較的話就沒多大的效益了,所以花錢買設備升級可能需要等等,或是上SSD看看能不能跑到SATA 6G的全部頻寬,不然那個瓶頸應該是硬碟的極限了。

以最後穩定的寫入速度來看,怎麼看都是SATA比較快,而且SATA 6G與SATA 3G沒差多少,實際測試上就是如此。

USB 2.0 vs SATA 3G





















USB 3.0 vs SATA 6G




引用參考:http://ithelp.ithome.com.tw/question/10033311
引用參考:http://en.wikipedia.org/wiki/RTFM

2012年4月16日 星期一

Node.js

一般提到網頁開發技術,很多人的印象就php、Java、.NET、 perl、python、Ruby、、等,在2011年最夯的是Node.js,它是純粹以JavaScript為基礎的框架,不同於jQuery這種前端的框架,它是可以是一種後端的框架,地位跟php、Java 、、、之流類似,只是語法已經純粹使用JavaScript了。

有趣的是他也可以在瀏覽器上直接執行,變成web app,目前看起來就「屌」,用起來也屌,問題是現階段拿來做專案,也可能會屌的爆肝。

這新技術有可能統一backend的程式,使得web app有統一的語言,寫起來也方便多了,是有可能造成趨勢,而且還是個有屌到的open source專案,相信群眾熱情是有可能把它舞台。

優點

  1. JavaScript
  2. 效能表現
  3. 社群支援

缺點

  1. 太年輕,基本上還剛開始而已
  2. 沒專用的開發工具
  3. 一直在callback,維護有點難度


參考:
http://www.inside.com.tw/2011/03/13/new-tech-nodejs
http://syshen.cc/post/5452172966/node-js-1
http://www.grandsights.twbbs.org/2011/09/nodejs_11.html

GreenMamba可以把Excel直接轉成Web Database


GreenMamba(青竹絲!?)可以直接把Excel轉成Web database,提供web介面存取Excel,可能有些人會用的到,也正好有人問到,我也找到方法,就寫一下筆記,雖然不是很推荐的方法,但是就...某些時候可以直接拿來用,也是有機會可以省去一些時間。

我想概念也不難,就是靠CGI去把Excel展開,並且提供Web GUI介面存取該頁面,所以需要開啟一個web server,公式的部份就不知道有沒有實現,主要是我沒有測試過該軟體,所以請有試過的朋友可以回一下文。


而對於想直接套用這軟體把Excel當成資料庫使用,省去寫網頁的人就請三思而後行,通常這種偷空減料的方法,後期很容易遇到困難。


參考資料:http://larsjuhljensen.wordpress.com/2011/10/18/resource-turning-an-excel-sheet-into-a-web-accessible-database-with-greenmamba/

2012年4月13日 星期五

USB DFU Class



USB DFU (Device Firmware Upgrade) Class,主要是用來更新USB Device的軔體,改天再深入研究看看。


參考文件 http://www.usb.org/developers/devclass_docs/usbdfu10.pdf



IPMB通訊協定筆記

IPMB Communication protocol note

IPMI是智慧平台管理(Intelligent Platform Management Interface),按照wiki的講法,原先是INTEL架構給企業系統的週邊設備用的一種工業標準,IPMI也是一個開放的免費標準,IPMI可以橫跨不同的作業系統、軔體和平台,可以監控和自動回報大量伺服器的運作狀況,用以降低伺服器系統成本。

實體上你在伺服器的主機板上有機會看如下圖兩種connector(怎麼看起都長一樣...)。

接腳的定義如下圖所示,TypeA與TypeB的差別就Pin4在不在而已。
這份文件是本人、在下、我對於IPMB通訊協定的筆記,人老了有些東西不靠外部記憶體很難都寫到腦袋裏面,尤其是這種人訂出來的協定,沒有所謂好壞的問題,只有所謂要不要遵守問題,所以就在雲端寫寫筆記。

這協定是架構在I2C之上,有幾個與I2C不一樣的特性:

  1. 只有Master Write可以用,也就是I2C R/W bit一直都是 0 (Write)
  2. 不支援10-bits的位址
  3. 每一個傳輸只能有一個slave address
  4. 不能使用re-start(repeated start)
  5. I2C ACK只表示該位元組收到確定而已,沒有其他意思

協定的外觀如下圖所示:


各個欄位意義如下表所示:


其中比較容易有疑問的是對於checksum的算法,它是zero-checksum,他阿哩阿雜講一堆,我是覺得舉例比較快。


checksum zero-checksum算法是從rsSA/rqSA~dataEnd一個byte一個byte的加總在一起之後mod 0x100,再取 2'sc (2的補數),底下是我從wireshark取下來的資料

0000 20 b4 2c 9c f8 00 00 00 32 03 00 37 .,..... 2..7    

我們用顏色區分資料

0000 20 b4 2c 40 f8 00 00 00 32 03 00 93 .,..... 2...    

紅色部份先是資料目的位址,再來是來源位址,黃色的部份是checksum,零會被忽略不加(國小問題吧)。
第一個checksum是0x2C = 2'sc((0x20+0xB4)%0x100)
第二個checksum是0x93 = 2'sc((0x40+0xF8+0x32+0x03)%0x100)

再來是Net Fn/LUN(net function)的擺法,一樣是舉個例子:

其中netFn是0x06,rqLun是0x00,則Get Device ID request就如下圖所示組合:

Get Device response就如下圖所示組合:

MSB先放netFn則是6-bits,接著才是LUN是2-bits。

Completion Code是在response才會有的回應,主要是功能就像是status word或是稱為response code,用來說明命令執行結果到底OK還是不OK,如果不OK那是什麼狀況。


Command及Response格式之類的就很無聊的查表、查表、再查表,沒什麼營養,IPM Device "Global" Command如下表,O/M=Optional/Mandatory。


參考一 http://download.intel.com/design/servers/ipmi/ipmb1010ltd.pdf
參考二 http://download.intel.com/design/servers/ipmi/IPMI2_0E4_Markup_061209.pdf

2012年4月12日 星期四

perl的檔案處理

配合上perl對文字串的處理,它在做檔案處理還蠻實用的。

  • 刪除檔案 unlink
  • 更改檔名 rename
  • 更改權限 chmod
  • 取得檔案屬性 stat
  • 拷貝檔案 copy
底下的參考網址有範例程式可以參考


參考網址

GUI沒辦法像積木一樣堆積出新的面貌,也就沒什麼彈性可以自動處理,工程師在這種環境底下慢慢的會變得跟一般使用者沒兩樣,失去高速、自動控制系統的能力,當然GUI在某些時候的確是比較直觀、方便,對使用者來說或許是福音,但是對於工程師來說可能就是毒藥,工程師常常需要大批的處理檔案,怎麼辦?

一個一個改嗎?

我是認為寫code按照某個規則,整批的改比較快吧!

檔案及檔案夾中有空白要改

在網路上看到一個問題,有人資料夾或檔案有空白,希望把資料夾或檔案名稱中的空白改成底線,而底下的code就是本人使用Perl寫出來的,事實上還蠻簡單的,當然與上次在Linux上使用的方法有點差異,Perl的資源豐富、強大,有發現好方法可以快速的搞定當然是拿來用阿~~XD。

所以code是愈寫愈小...XD


#!/usr/bin/perl -w

use File::Find;

$start_dir = shift || '.';

find( sub{
 if($_ =~ /\ /){
  my $new=$_;
  $new=~s/\ /\_/g;
  print "$_ --> $new\r\n";
  rename($_,$new);
 }
}, $start_dir );

2012年4月4日 星期三

用日期排列超級影音動物機下載的影片並砍掉垃圾檔

你是不是像我在太陽下低頭下載之後發現一堆垃圾檔案,也像我一樣覺得BT軟體不是按照下載完成的時間排放在資料夾中,覺得不是很方便。

我與一般使用者不一樣的地方就是,我會寫code解決這鳥事,不過就是把檔案撈出來砍掉嘛,順便重做連結讓找的時候方便一點而已,所以我寫出底下的code,這主要是運作在Linux伺服器上,我家的超級影音動物機(改天專題介紹一下這強大的機器),利用crontab排程更新資料就變得十分完美,只要丟檔案到AutoSeed資料夾下,等著看最新下載的就好,當然這個程式改一改就可以自動砍掉老舊的檔案,自動保持系統容量在一定的範圍之內。



#!/usr/bin/perl -w

use File::Basename;

$fileLocate="/media/mediaDisk";
@lines=`find $fileLocate/done`;
my $var=`rm -fr $fileLocate/dayList/*`;

my $index=0;

foreach $line(@lines){
	chomp($line);
	if(($line =~ /\.url$/i)||
	   ($line =~ /\.chm$/i)||
	   ($line =~ /\.mht$/i)||
	   ($line =~ /\.txt$/i)||
	   ($line =~ /___padding_file/)
	){
		unlink("$line");
	}
	if(($line =~ /\.mkv$/i)||
	   ($line =~ /\.avi$/i)||
	   ($line =~ /\.divx$/i)||
	   ($line =~ /\.mov$/i)||
	   ($line =~ /\.mp4$/i)||
	   ($line =~ /\.m4v$/i)||
	   ($line =~ /\.rmvb$/i)||
	   ($line =~ /\.rm$/i)||
	   ($line =~ /\.wmv$/i)||
	   ($line =~ /\.asf$/i)||
	   ($line =~ /\.ass$/i)||
	   ($line =~ /\.srt$/i)||
	   ($line =~ /\.ssa$/i)||
	   ($line =~ /\.sub$/i)||
	   ($line =~ /\.idx$/i)||
	   ($line =~ /\.vkt$/i)
	){
		if(-f $line){
			my @statArray=stat("$line");
			my ($sec,$min,$hour,$mday,$mon,$year)=localtime($statArray[9]);
			$year+=1900;
			$mon++;
			my $locate="$fileLocate/dayList/$year-$mon-$mday";
			#printf("%s\n",$line);
			if(!(-e $locate)){
				mkdir("$locate");
				print "[[$locate]]\n";
			}
			my($fname,$dir,$ext)=fileparse($line);
			print "$fname\n\t$dir\n\t$ext\n";
			print "ln -s \'$line\' \'$locate/$fname\'";
			if(-e "$locate/$fname"){
				$var=`ln -s \'$line\' \'$locate/$index_$fname\'`;
				$index++;
			}
			$var=`ln -s \'$line\' \'$locate/$fname\'`;
		}
	}else{
		if(-z $line){
			print ">>$line\n";
		}
	}
}

MCU的操作系統

當時開發VT100這個操作介面給MCU用,是基於「無聊」,想要在8bit MCU上搞一個操作系統上去而已,後來實際使用上發現,這還是個他媽的好IDEA,開發階段DEBUG可以塞一些功能帶入參數操作試試看,有些時候試爽了之後才把參數填上,有些時候臨時要看系統狀況也是靠這招,我的程式在PIC16系列與8051都有測試過,在非常窘迫的環境下還是可以使用,真是他媽的好程式(也不想是誰寫的),當然更不用說在優渥的環境之下使用,PIC 16bit/32bit或是ARM 系列都是可以運作良好,這個介面主要是在那種小型的嵌入式系統上使用。

JL代表Jones Lai本人、在下、我,以前都是聽老師在台上臭彈,「給我CPU,我就做的出系統」,現在覺得也沒什麼,就那樣嘛~~XD。

當然這個VT100沒實現類似DOS-KEY或是Bash那堆auto-complete方便的服務,除了我懶的寫之外,8bit的MCU無論是ROM或RAM也都塞不下去,在那種系統上連command的長度都要計較,還給你搞這個,純粹是找死,改天深入談VT100的一些細節好了,這篇就先出個code讓你聞香一下,光是這個操作介面要在51的鳥環境下跑,就夠艱苦的了,過程還有一些鳥狀況。



參考資料:
WIKI-VT100
ANSI/VT100 Terminal Control