勢いでPython + Django + Eclipse(PyDev)

どもーらーめんこぞーですー(´ω`)ノ

ノリで気づいたらPythonを触り始めている件(´ω`)某氏にはRubyist的なソレを話したような気がしますが、スマンありゃウソだった

ていうのも、「なんとなーく楽ゥにWebアプリケーション作ってみたいなー↑」みたいなノリでそういう言語あさってたワケで(ˇωˇ )
(それまでJavaServletがどうのでウオオオオアアアアーッしてた件)

で、前々から目をつけていたdotCloud。(゚ω゚)ギムン
アチラさんでサポートしてる言語どれがいいかなー的なノリで「まぁまぁやわらかくて、クライアントアプリにもWebアプリにもツブしが効いて、活用事例が検索で見つかるくらいあって、今後ともお付き合い願えそうなブツ」を選んでると、僕の中ではPythonRubyのお二方になったソレでして(´ω`)。oO(Javaはもうある程度触ってる+第二言語修得的なソレなのでスルーリ)

最終的に自分の決定要因はロゴのカラーリングと言葉の響き+Webアプリなフレームワークで検索結果に手が着いたというソレでPythonさんになりますた(´ω`)ノ以後よろすく。

とりあえずDjangoとやらでIt Worksしてみた次第ですヾ(´ω`)ノシ

まずeclipseにPyDevをインスコ。
参考サイト様:PyDev のインストール
PyDevさん本家( http://pydev.sf.net/updates )のURLコピペして、eclipseメニューの「help→Install New Software」から右上の「Add→『Name:PyDev(なんでもいい), Location:http://pydev.sf.net/updates」で読み込んで、ダイアログ中段のPyDevのチェックボックスにチェック(Mylynみたいなのは無視)→あとはNext。

PyDevがインスコできたらDjangoもインスコ。
参考サイト様:WindowsにAptana PydevでDjangoの開発環境を構築する
Django本家のDownloadページ(https://www.djangoproject.com/download/)からDjango-1.4.tar.gzをダウソ。tar.gzで固められてるので、Windowsな方はcygwin環境下か7zipマネージャあたりで解凍すると幸せだと思います。解凍したあとはターミナル(Windowsな方はコマンドプロンプト)にてDjangoを解凍したフォルダに移動後、下記コマンド。(PythonインスコされててPATH通ってる前提だけどいいッスよね)

python setup.py install

なんかウバァーッとたくさんログ吐かれたて止まったらたぶんイケてます。(errorとか書かれてなければ…)
ちなみにWindows環境の方でcygwinな方はコマンドプロンプトから直接↑のコマンド打った方が良さ気です。cygwinからッターンしてみるとまともにインスコされてなかったので…(たぶんcygwin配下かつPATH通ってない何処かにファイル群が置かれたっぽいス)
んでDjangoインスコがイケてるかどうかは下記コマンドでエラーっぽいこと言われなければOKらしいです。

python
>>>import django

PyDevもDjangoも入ったところで、eclipseからDjangoプロジェクト作ってIt Worksに臨みます。
参考サイト様:Django でちょっとしたアプリを作成する手順の覚え書き (1)
参考サイト様の内容丸コピでとりあえずヤッてみました。ただしディレクトリ名をちょっと変えてみるささやかな抵抗を試みました。

参考サイト様: webapp_util -> ヲレ:HelloDjango
参考サイト様: model_name_util -> ヲレ:myapps

Djangoプロジェクトの実行時に引数として http://127.0.0.1:10000/ で起動するようにしてみました。

で、It Works!

さて、こっからdotCloud用にいろいろヤッてみるソレですが、今回はこのへんで。(´ω`)ノシ ではまたー

beagleboard-xM ( Rev.C ) でAndroid 2.3.4 ( GingerBread ) を動かせた

どもーらーめんこぞーですー(´ω`)ノ

beagleboard-xMを昨年だったか一昨年だったかに購入して放置プレイをキメていました。
なんでかっていうと、付属のÅngström(オングストローム, Linuxディストリビューションのひとつらしいです)が入ったmicroSDカード以外で一切ブートできなかったのでorz

敗因はおそらく下記三項目っぽいです。
1. Texas Instrumentsさん(以下TI)のAndroid2.2(Froyo)のPre-Builtイメージを使ってた
2. 手持ちのmicroSDカードの相性が悪かった
3. HDMI->DVI変換ケーブルを刺して使えるモニタではなかった

1.は、beagleboard-xMのリビジョンによってイケるのとイケないのがあると聞きました。Rev.AとRev.BはTIさんのPre-Built版でイケるそうですが、Rev.Cはu-boot.binとuImageを修正版に入れ替えないといけないらしいです(参考:BeagleBoard-xMにGingerbreadをのせる)

2.はbeagleboard触ってる方々の記事を見ているとたまにうまく起動しないmicroSDカードがあったりなんだりらしいですね(´ω`)ものによって遅いだけだったり起動しなかったりがあるそうで

3.は完全にヤラれました。今まで古いディスプレイ(BenQ, 2007年購入)の方のDVI端子にbeagleboardの映像出力をつないでいて、起動時の様子をシリアルコンソールで確認しつつandroidのロゴが出るのを待っていました。下記のようなシリアルのログでずっと「起動できなくて固まってるだけ」と思ってました。実際には「実は映像出てるけど、古いディスプレイでHDMI->DVI変換ケーブル使ったら映像が出ない」だけでした。新しいディスプレイのDVIにつなぐと一発で表示されましたorz(参考:組み込みAndroid#5)

Texas Instruments X-Loader 1.51 (Jul 11 2011 - 21:11:32)
Unsupported Chip!
Beagle xM Rev C
Starting X-loader on MMC 
Reading boot sector

213256 Bytes Read from MMC 
Starting OS Bootloader from MMC...
Starting OS Bootloader...


U-Boot 2010.06 (Jul 08 2011 - 04:37:45)

OMAP34xx/35xx-GP ES2.1, CPU-OPP2 L3-165MHz
OMAP3 Beagle board + LPDDR/NAND
I2C:   ready
DRAM:  384 MiB
NAND:  HW ECC [Kernel/FS layout] selected
0 MiB
*** Warning - bad CRC or NAND, using default environment

In:    serial
Out:   serial
Err:   serial
Beagle xM Rev A/C
Die ID #0d2600029ff80000015f26ad0f00800c
Hit any key to stop autoboot:  0 
mmc1 is available
reading boot.scr

460 bytes read
Running bootscript from mmc ...
## Executing script at 82000000
reading uImage

2745172 bytes read
***** Kernel: /dev/mmcblk0p1/uImage *****
***** RootFS: /dev/mmcblk0p2 *****
## Booting kernel from Legacy Image at 82000000 ...
   Image Name:   Linux-2.6.37-g06ebbba
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2745108 Bytes = 2.6 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Linux version 2.6.37-g06ebbba (a0131746@swubn01) (gcc version 4.4.3 (GCC) ) #1 1
CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7f
CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: OMAP3 Beagle Board
Reserving 8388608 bytes SDRAM for VRAM
Memory policy: ECC disabled, Data cache writeback
OMAP3630 ES1.2 (l2cache iva sgx neon isp 192mhz_clk )
SRAM: Mapped pa 0x40200000 to va 0xfe400000 size: 0x10000
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 62976
Kernel command line: console=ttyO2,115200n8 androidboot.console=ttyO2 mem=256M M
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 248MB = 248MB total
Memory: 245300k/245300k available, 16844k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
    vmalloc : 0xd0800000 - 0xf8000000   ( 632 MB)
    lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .init : 0xc0008000 - 0xc003b000   ( 204 kB)
      .text : 0xc003b000 - 0xc052f000   (5072 kB)
      .data : 0xc0530000 - 0xc0574940   ( 275 kB)
NR_IRQS:409
Clocking rate (Crystal/Core/MPU): 26.0/400/600 MHz
Reprogramming SDRC clock to 400000000 Hz
dpll3_m2_clk rate change failed: -22
IRQ: Found an INTC at 0xfa200000 (revision 4.0) with 96 interrupts
Total of 96 interrupts on 1 active controller
GPMC revision 5.0
Trying to install interrupt handler for IRQ402
Trying to install interrupt handler for IRQ403
Trying to install interrupt handler for IRQ404
Trying to install interrupt handler for IRQ405
Trying to install interrupt handler for IRQ406
Trying to install interrupt handler for IRQ407
Trying to install interrupt handler for IRQ408
Trying to install type control for IRQ409
Trying to set irq flags for IRQ409
OMAP clockevent source: GPTIMER1 at 32768 Hz
Console: colour dummy device 80x30
Calibrating delay loop... 597.64 BogoMIPS (lpj=2334720)
pid_max: default: 32768 minimum: 301
Security Framework initialized
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
regulator: core version 0.5
regulator: dummy: 
NET: Registered protocol family 16
OMAP GPIO hardware version 2.5
OMAP GPIO hardware version 2.5
OMAP GPIO hardware version 2.5
OMAP GPIO hardware version 2.5
OMAP GPIO hardware version 2.5
OMAP GPIO hardware version 2.5
omap_mux_init: Add partition: #1: core, flags: 0
OMAP3 Beagle Rev: xM C
Found NAND on CS0
Registering NAND on CS0
Unable to get DVI reset GPIO
hw-breakpoint: debug architecture 0x4 unsupported.
OMAP DMA hardware revision 5.0
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
omap_i2c omap_i2c.1: bus 1 rev4.0 at 2600 kHz
twl4030: PIH (irq 7) chaining IRQs 368..375
twl4030: power (irq 373) chaining IRQs 376..383
twl4030: gpio (irq 368) chaining IRQs 384..401
regulator: VUSB1V5: 1500 mV normal standby
regulator: VUSB1V8: 1800 mV normal standby
regulator: VUSB3V1: 3100 mV normal standby
twl4030_usb twl4030_usb: Initialized TWL4030 USB module
regulator: VMMC1: 1850 <--> 3150 mV at 3000 mV normal standby
regulator: VDAC: 1800 mV normal standby
regulator: VDVI: 1800 mV normal standby
regulator: VSIM: 1800 <--> 3000 mV at 1800 mV normal standby
regulator: VAUX3: 1800 mV normal standby
regulator: VAUX4: 1800 mV normal standby
omap_device: omap_i2c.2: new worst case activate latency 0: 30517
omap_i2c omap_i2c.2: bus 2 rev4.0 at 400 kHz
omap_i2c omap_i2c.3: bus 3 rev4.0 at 100 kHz
Advanced Linux Sound Architecture Driver Version 1.0.23.
Switching to clocksource 32k_counter
musb-hdrc: version 6.0, otg (peripheral+host), debug=0
musb-hdrc musb-hdrc.0: dma type: dma-inventra
musb-hdrc musb-hdrc.0: USB OTG mode controller at fa0ab000 using DMA, IRQ 92
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (double precision)
omap-iommu omap-iommu.0: isp registered
AM37x/DM37x  Linux PSP version 04.02.00.07 (OMAP3BEAGLE)
ashmem: initialized
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
JFFS2 version 2.2. (NAND) (SUMMARY)  &#65533;&#169; 2001-2006 Red Hat, Inc.
msgmni has been set to 479
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
OMAP DSS rev 2.0
OMAP DISPC rev 3.0
OMAP VENC rev 2
OMAP DSI rev 1.0
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
omap_uart.0: ttyO0 at MMIO 0x4806a000 (irq = 72) is a OMAP UART0
omap_uart.1: ttyO1 at MMIO 0x4806c000 (irq = 73) is a OMAP UART1
omap_uart.2: ttyO2 at MMIO 0x49020000 (irq = 74) is a OMAP UART2
console [ttyO2] enabled
omap_uart.3: ttyO3 at MMIO 0x49042000 (irq = 80) is a OMAP UART3
brd: module loaded
loop: module loaded
mtdoops: mtd device (mtddev=name/number) must be supplied
omap2-nand driver initializing
No NAND device found.
No NAND device found.
OneNAND driver initializing
usbcore: registered new interface driver asix
usbcore: registered new interface driver cdc_ether
usbcore: registered new interface driver smsc95xx
usbcore: registered new interface driver net1080
usbcore: registered new interface driver cdc_subset
usbcore: registered new interface driver zaurus
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-omap.0 supply hsusb0 not found, using dummy regulator
ehci-omap.0 supply hsusb1 not found, using dummy regulator
ehci-omap ehci-omap.0: OMAP-EHCI Host Controller
ehci-omap ehci-omap.0: new USB bus registered, assigned bus number 1
ehci-omap ehci-omap.0: irq 77, io mem 0x48064800
ehci-omap ehci-omap.0: USB 2.0 started, EHCI 1.00
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: OMAP-EHCI Host Controller
usb usb1: Manufacturer: Linux 2.6.37-g06ebbba ehci_hcd
usb usb1: SerialNumber: ehci-omap.0
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 3 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
android init
android_probe pdata: c053ff2c
android_bind
android_usb gadget: android_usb ready
musb-hdrc musb-hdrc.0: MUSB HDRC host driver
musb-hdrc musb-hdrc.0: new USB bus registered, assigned bus number 2
usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb2: Product: MUSB HDRC host driver
usb usb2: Manufacturer: Linux 2.6.37-g06ebbba musb-hcd
usb usb2: SerialNumber: musb-hdrc.0
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
f_adb init
android_register_function adb
adb_bind_config
f_mass_storage init
android_register_function usb_mass_storage
mice: PS/2 mouse device common for all mice
input: gpio-keys as /devices/platform/gpio-keys/input/input0
input: twl4030_pwrbutton as /devices/platform/omap/omap_i2c.1/i2c-1/1-0049/twl41
omap_device: omap_i2c.1: new worst case deactivate latency 0: 30517
using rtc device, twl_rtc, for alarms
twl_rtc twl_rtc: rtc core: registered twl_rtc as rtc0
i2c /dev entries driver
Linux media interface: v0.10
Linux video capture interface: v2.00
omap3isp supply VDD_CSIPHY1 not found, using dummy regulator
omap3isp supply VDD_CSIPHY2 not found, using dummy regulator
omap3isp omap3isp: Revision 15.0 found
omap-iommu omap-iommu.0: isp: version 1.1
mt9v113 2-003c: chip id mismatch read 0x0, expecting 0x2280
isp_register_subdev_group: Unable to register subdev mt9v113
OMAP Watchdog Timer Rev 0x31: initial timeout 60 sec
twl4030_wdt twl4030_wdt: Failed to register misc device
twl4030_wdt: probe of twl4030_wdt failed with error -16
device-mapper: uevent: version 1.0.3
device-mapper: ioctl: 4.18.0-ioctl (2010-06-29) initialised: dm-devel@redhat.com
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
logger: created 64K log 'log_main'
logger: created 256K log 'log_events'
logger: created 64K log 'log_radio'
logger: created 64K log 'log_system'
usbcore: registered new interface driver snd-usb-audio
OMAP3 Beagle/Devkit8000 SoC init
usb 1-2: new high speed USB device using ehci-omap and address 2
asoc: twl4030-hifi <-> omap-mcbsp-dai.1 mapping ok
ALSA device list:
  #0: omap3beagle
oprofile: hardware counters not available
oprofile: using timer interrupt.
TCP cubic registered
Initializing XFRM netlink socket
NET: Registered protocol family 17
NET: Registered protocol family 15
Registering the dns_resolver key type
VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
ThumbEE CPU extension supported.
Power Management for TI OMAP3.
smartreflex smartreflex.0: omap_sr_probe: SmartReflex driver initialized
smartreflex smartreflex.1: omap_sr_probe: SmartReflex driver initialized
SmartReflex Class3 initialized
clock: disabling unused clocks to save power
platform mpu.0: omap_voltage_scale: Already at the requestedrate 600000000
usb 1-2: New USB device found, idVendor=0424, idProduct=9514
usb 1-2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
hub 1-2:1.0: USB hub found
hub 1-2:1.0: 5 ports detected
regulator_init_complete: incomplete constraints, leaving VDAC on
twl_rtc twl_rtc: setting system clock to 2000-01-01 00:02:53 UTC (946684973)
omap_vout omap_vout: Buffer Size = 3686400
omap_vout omap_vout: : registered and initialized video device 15
omap_vout omap_vout: Buffer Size = 3686400
omap_vout omap_vout: : registered and initialized video device 16
Waiting 1sec before mounting root device...
mmc0: host does not support reading read-only switch. assuming write-enable.
mmc0: new high speed SDHC card at address e624
mmcblk0: mmc0:e624 SU08G 7.40 GiB 
 mmcblk0: p1 p2 p3
usb 1-2.1: new high speed USB device using ehci-omap and address 3
usb 1-2.1: New USB device found, idVendor=0424, idProduct=ec00
usb 1-2.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
smsc95xx v1.0.4
smsc95xx 1-2.1:1.0: usb0: register 'smsc95xx' at usb-ehci-omap.0-2.1, smsc95xx d
usb 1-2.2: new full speed USB device using ehci-omap and address 4
usb 1-2.2: New USB device found, idVendor=04b8, idProduct=a519
usb 1-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-2.2: Product: USB Hub Keyboard 
usb 1-2.2: Manufacturer: Chicony
hub 1-2.2:1.0: USB hub found
hub 1-2.2:1.0: 3 ports detected
usb 1-2.3: new low speed USB device using ehci-omap and address 5
usb 1-2.3: New USB device found, idVendor=0458, idProduct=0007
usb 1-2.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-2.3: Product: Optical Mouse
usb 1-2.3: Manufacturer:  KYE  
input:  KYE   Optical Mouse as /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-22
generic-usb 0003:0458:0007.0001: input: USB HID v1.10 Mouse [ KYE   Optical Mou0
usb 1-2.2.1: new full speed USB device using ehci-omap and address 6
EXT3-fs: barriers not enabled
usb 1-2.2.1: New USB device found, idVendor=04b8, idProduct=0310
usb 1-2.2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-2.2.1: Product: USB Hub Keyboard 
usb 1-2.2.1: Manufacturer: Chicony
input: Chicony USB Hub Keyboard  as /devices/platform/ehci-omap.0/usb1/1-2/1-2.3
generic-usb 0003:04B8:0310.0002: input: USB HID v1.10 Keyboard [Chicony USB Hub0
input: Chicony USB Hub Keyboard  as /devices/platform/ehci-omap.0/usb1/1-2/1-2.4
generic-usb 0003:04B8:0310.0003: input: USB HID v1.10 Device [Chicony USB Hub K1
kjournald starting.  Commit interval 5 seconds
EXT3-fs (mmcblk0p2): using internal journal
EXT3-fs (mmcblk0p2): recovery complete
EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
VFS: Mounted root (ext3 filesystem) on device 179:2.
Freeing init memory: 204K
init (1): /proc/1/oom_adj is deprecated, please use /proc/1/oom_score_adj inste.
init: cannot find '/system/etc/install-recovery.sh', disabling 'flash_recovery'
enabling adb
adb_open
# warning: `zygote' uses 32-bit capabilities (legacy support in use)

でもって成功したやり方を示します。(参考:Android 2.3.4を起動してみる)
Android2.3.4のPre-Builtイメージならbeagleboard-xMのRev.Cでも特に変更なく使用可能とのことで、とりあえずTIさんのここからPre-Builtイメージを拾ってきます。

適当なフォルダに解凍して、イメージファイル群のフォルダに移動します。

tar xzvf beagleboard-xm.tar.gz
cd ./beagleboard-xm

ターミナルの言語を英語仕様に変更します。
こちらの環境では「LANGUAGE=C」までやらないとあとで「日本語環境から直ってねぇじゃねぇかバーロー」って怒られました(´ω`)
[20120706追記: ×LANGAGE=C ○LANGUAGE=C 書きまつがいですた(>ω<)]

LANG=C
LANGUAGE=C

でもってbeagleboard-xMで起動するためのmicroSDカードをカードリーダか何かでPCに刺しておいて、そのデバイス名を確認しておきます。(ここではmicroSDのデバイス名が /dev/sdf だったとします。あとmicroSDカードはフォーマットされますので事前にファイル等保存していましたらどこかにバックアップを取っておくことをおすすめします)

sudo ./mkmmc-android.sh /dev/sdf

うまいことブート用のファイル群が配置されれば下記のようなログが出てきます。
2GBのmicroSDでやった場合なので、ソレ以上の容量のものを使うとCYLINDESあたりの数字は若干変わってくると思いますが、最後らへんのメッセージは変わらないのでDoneしたらおkです。

Assuming Default Locations for Prebuilt Images
All data on /dev/sdf now will be destroyed! Continue? [y/n]
y
[Unmounting all existing partitions on the device ]
umount: /dev/sdf: not mounted
[Partitioning /dev/sdf...]
Disk /dev/sdf doesn't contain a valid partition table
DISK SIZE - 1973420032 bytes
CYLINDERS - 239
[Making filesystems...]
[Copying files...]
[Copying START_HERE floder to boot partition]
[Copying all clips to data partition]
[Done]

できたブート用microSDカードをbeagleboard-xMのmicroSDカードスロットに挿して電源を供給すると、初回は5分〜10分くらいかかりますが、その後はものの1分〜3分くらいで起動します。

ついでにEthernetの有効化まで記します。(参考:Android 2.3.4を起動してみる)
Windowsの場合はハイパーターミナルやTeraTermLinuxならminicom等でbeagleboard-xMのシリアルコンソールに接続します。(115200bps, データビット8bit、スタート/ストップビット1bit、パリティなし、フロー制御なし)
下記コマンドを打つとDHCP有効でEthernetポートを有効化するらしいです。(usb0てUSB扱いなんですかね(´ω`)?)

netcfg usb0 dhcp

下記コマンドでIPアドレスもらえてるかどうか確認できるそうです。

netcfg

次に、デフォルトゲートウェイを設定します。まずデフォルトゲートウェイIPアドレスを確認するため、下記コマンドをッターン

getprop net.usb0.dns1

でもってソレで表示されたIPアドレスを下記コマンドでッターン

setprop net.dns1 さっき表示されたIPアドレス

これでEthernetを通じてネットにイケます。
固定IPの際は下記コマンドのようです。(参考:Gingerbread (Android 2.3.4) on BeagleBoard-xM Rev.C)

ifconfig usb0 指定したいIPアドレス netmask 指定したいサブネットマスク
route add default gw デフォルトゲートウェイIPアドレス dev usb0

具体例として下記のように設定することができるようです。
beagleboard-xM台とブロードバンドルータ(スイッチングハブ機能付き)1台が接続されてる構成のイメージです。

ifconfig usb0 192.168.1.10 netmask 255.255.255.0
route add default gw 192.168.1.1 dev usb0

DHCPでの例ですが、Google検索できてます(*´ω`*)

とりあえずAndroidが動くようになったのでこっからドライバやらなんやら増やしてグフフフフウ(^p^)
ではまたーヾ(*´ω`*)ノシ

Jetty8でWebSocketしてみた(蔵側)

どもー(´ω`)ノ Ramencozoです

前回の続き(Jetty8でWebSocketしてみた(鯖側))です(´ω`)
今回はWebSocketクライアントとなるAndroid端末側の実装について書き書きしますφ(´ω`)

必要なライブラリはこちら(´ω`)っ
・WebSocketライブラリ:weberknecht -> weberknecht-0.1.1.jar

このライブラリをAndroidなProjectフォルダに突っ込んで(新規でlibとかフォルダ作ってそこに置きます)、Build Pathの方の設定でAdd Jar Fileします(´ω`)
[2012/06/25 追記] ADT(Android Development Tools)プラグインに変更があったのか、外部ライブラリを置くフォルダは「libs」としたほうが良いようです。(Android Dependenciesに自動で内包されるようです)
逆に、別のフォルダに置いた場合、Build Path→Configure Build Path→Order and Exportのとこで該当ライブラリにチェック付けないとapkにライブラリが内包されないようです。

WebSocketクライアントなアプリは下記。画面に表示される MainActivity.java と、WebSocket接続の処理を行う WebSocketManager.java から成っています。


HelloWebSocketClient / MainActivity.java

package jp.ramensroom.hellowebsocketclient;

import de.roderick.weberknecht.WebSocketEventHandler;
import de.roderick.weberknecht.WebSocketMessage;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

// チャットログ用 ListView + ArrayAdapter
private ListView chatListView;
private ArrayAdapter chatArrayAdapter;

// テキスト送信用 EditText + Button
private EditText postEditText;
private Button sendButton;

// WebSocket Client
private WebSocketManager manager;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

chatArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);

chatListView = (ListView)findViewById(R.id.chat_listview);
chatListView.setAdapter(chatArrayAdapter);

postEditText = (EditText)findViewById(R.id.post_edittext);

sendButton = (Button)findViewById(R.id.send_button);

manager = new WebSocketManager();
manager.connect("ws://サーバIPアドレス:サーバポート/echo", new WebSocketEventHandler() {
@Override
public void onOpen() { // WebSocket接続確立時に呼ばれる
Toast.makeText(getApplicationContext(), "WebSocket Connected.", Toast.LENGTH_SHORT).show();
}

@Override
public void onMessage(WebSocketMessage message) { // WebSocketサーバからデータが送られてきた時に呼ばれる
final String msg = message.getText();

chatArrayAdapter.insert(msg, 0); // ListViewの先頭に最新のデータが来るように0番目へ挿入
}

@Override
public void onClose() { // WebSocket接続切断時に呼ばれる
Toast.makeText(getApplicationContext(), "WebSocket Disconnected.", Toast.LENGTH_SHORT).show();
}
});

sendButton.setOnClickListener(new OnClickListener() { // Buttonが押された時の処理
@Override
public void onClick(View v) {
final String msg = postEditText.getText().toString();

Toast.makeText(getApplicationContext(), "Message Sent.", Toast.LENGTH_SHORT).show();
manager.send(msg);
chatArrayAdapter.insert("me:" + msg, 0); // 自分の投稿であることを明記
postEditText.setText(""); // でもってEditTextの入力領域クリア
}
});
}
}

HelloWebSocketClient / WebSocketManager.java

package jp.ramensroom.hellowebsocketclient;

import java.net.URI;
import java.net.URISyntaxException;

import de.roderick.weberknecht.WebSocket;
import de.roderick.weberknecht.WebSocketConnection;
import de.roderick.weberknecht.WebSocketEventHandler;
import de.roderick.weberknecht.WebSocketException;

public class WebSocketManager{
private WebSocket webSocket;
private boolean connectState;

public WebSocketManager() {
connectState = false;
}

// WebSocketサーバとの接続確立メソッド
public void connect(String url, WebSocketEventHandler handler){
try {
URI uri = new URI(url);
webSocket = new WebSocketConnection(uri);
webSocket.setEventHandler(handler);
webSocket.connect();

connectState = true;
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (WebSocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// WebSocketサーバへStringデータを送信するメソッド
public void send(String message){
try {
webSocket.send(message);
} catch (WebSocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// WebSocket接続を切断するメソッド
public void close() {
try {
webSocket.close();
connectState = false;
} catch (WebSocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// WebSocket接続がなされているかを確認するメソッド
public boolean isConnected(){
return connectState;
}
}

HelloWebSocketClient/res/layout / main.xml


実際に動作させた様子が下記画像の通りとなります(´ω`)っ
WebSocketServer (PC側, JDK1.6, Swing)


WebSocketClient (Android側)

こんな具合にPCとAndroid間でカンタンに双方向リアルタイム通信ができたっていう報告ですたヾ(*´ω`*)ノシ
ただ、なんかタイムアウトがけっこー起きるみたいなのでその辺タイムアウトする前に「生きてますよー」的なメッセージを定期的に投げたほうがいいかもしれませんね(´ω`)

それではまた(´ω`)ノ

Jetty8でWebSocketしてみた(鯖側)

どもーRamencozoです(´ω`)ノ
ちょいと某アプリ用にちょいちょいいじいじしてるWebSocketの実装についての記事書きますす(´ω`)
(続編はこちら(っ´ω`)っJetty8でWebSocketしてみた(蔵側))
(WebSocket:WebサーバとWebブラウザ間で双方向通信を行うための通信規格)

WebSocketはリアルタイムな通信で鯖-クラ間のコネクションの接続のやりとりがラク的な話を聞いて、自宅鯖-Android端末間でヤッてみることにしました(´ω`)ノ

必要なライブラリ等はこちら(´ω`)っ
・サーバ:Jetty8 -> Jetty Stable-8 distribution

Jetty8なzipを解凍して、中に入ってるlibの中の.jarファイルすべてをJava ProjectのBuild PathにAdd Jar Fileします(´ω`)ホントはいらないものも含まれてると思いますがメンドいのでスルー

鯖のコードは下記。MainClass である MainWindow.java と、実際に内部で稼働するServerクラスである WebSocketServer.java と、クライアントと接続されるごとに生成される MyWebSocket.java の3つから成っています。


HelloJetty / MainWindow.java

package jp.ramensroom.hellojetty;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;

public class MainWindow extends JFrame{

private static final String TITLE = "WebSocketServer";
private static final int WIDTH = 580;
private static final int HEIGHT = 500;

private static final String MESSAGE_START_SERVER = "Start Server";
private static final String MESSAGE_STOP_SERVER = "Stop Server";

// サーバのポート(8081)とドキュメントルート
private static final int SERVER_PORT = 8081;
private static final String SERVER_DOCROOT = "./html";

// GUIパーツ
private static JTextArea logTextArea;
private JToggleButton serverBootToggleButton;

private WebSocketServer server;

// コンストラクタ
public MainWindow() {

server = new WebSocketServer(SERVER_PORT, SERVER_DOCROOT);

// GUI(Swing, JFrame)の整備
Container container = getContentPane();
JPanel parentPanel = new JPanel();

// サーバ-クライアント間の通信ログ表示用のTextArea。スクロールもできるようにセッティング
logTextArea = new JTextArea("WebSocket Server App\n");
JScrollPane scrollPane = new JScrollPane(logTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(512, 250));

// サーバの起動/終了ボタン
serverBootToggleButton = new JToggleButton(MESSAGE_START_SERVER);
serverBootToggleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
if(serverBootToggleButton.isSelected()){
new Thread(){
public void run() {
try {
// ボタンが押されたらサーバを起動
logTextArea.append("Server Started.\n");
logTextArea.setCaretPosition(logTextArea.getText().length());

server.start();
server.join();
} catch (Exception e) {
// 起動失敗時の表示
logTextArea.append("Something Wrong.\n");
logTextArea.setCaretPosition(logTextArea.getText().length());

e.printStackTrace();
}
};
}.start();
serverBootToggleButton.setText(MESSAGE_STOP_SERVER);
}else{
try {
// もう一度ボタンが押されたらサーバを終了
server.stop();

logTextArea.append("Server Stoped.\n");
logTextArea.setCaretPosition(logTextArea.getText().length());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
serverBootToggleButton.setText(MESSAGE_START_SERVER);
}
}
});

parentPanel.add(scrollPane, BorderLayout.CENTER);
parentPanel.add(serverBootToggleButton, BorderLayout.SOUTH);

container.add(parentPanel);

setTitle(TITLE);
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}

// WebSocketクラスからTextAreaにログを書き込むためのメソッド
public static void loggingData(String msg){
logTextArea.append(msg + "\n");
logTextArea.setCaretPosition(logTextArea.getText().length());
}

// メインクラス起動
public static void main(String[] args) {
new MainWindow();
}
}


HelloJetty / WebSocketServer.java

package jp.ramensroom.hellojetty;

import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketHandler;

public class WebSocketServer extends Server{

private SelectChannelConnector connector;
private WebSocketHandler wsHandler;
private ResourceHandler resHandler;

// WebSocketごとにIDを振るためのカウンタ
private int idCounter;

public WebSocketServer(int port, String rootDirPath) {
idCounter = 0;

connector = new SelectChannelConnector();
connector.setPort(port);
addConnector(connector);

wsHandler = new WebSocketHandler() {
@Override
public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
// クライアントから接続要求があれば MyWebSocket を返して接続開始
idCounter++;
System.out.printf("Protocol:%s\n", protocol);
return new MyWebSocket(idCounter);
}
};

resHandler = new ResourceHandler();
resHandler.setDirectoriesListed(true);
resHandler.setResourceBase(rootDirPath);

wsHandler.setHandler(resHandler);
setHandler(wsHandler);
}

// ぶっちゃけ使わないけど一応
private String usage() {
String msg = "";

msg += "java -cp CLASSPATH " + WebSocketServer.class + " [ OPTIONS ]\n";
msg += " -p|--port PORT (default 8080)\n";
msg += " -d|--docroot file (default 'src/main/resources/html')\n";

return msg;
}
}


HelloJetty / MyWebSocket.java

package jp.ramensroom.hellojetty;

import java.io.IOException;
import java.util.Calendar;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.eclipse.jetty.websocket.WebSocket;

// WebSocket.OnTextMessage を implements
public class MyWebSocket implements WebSocket.OnTextMessage {


private int myID; // 接続ID
private Connection connection;

// 全てのWebSocket接続が収められた Set
static Set wsConnections = new CopyOnWriteArraySet();

public MyWebSocket(int id) {
myID = id;
}

// WebSocket 接続開始時に呼ばれるメソッド
@Override
public void onOpen(Connection conn) {
connection = conn;
connection.setMaxIdleTime(Integer.MAX_VALUE);

System.out.println("Connection Added:" + myID);
System.out.println(" - MaxIdleTime:" + connection.getMaxIdleTime());
System.out.println(" - MaxTextMessageSize:" + connection.getMaxTextMessageSize());

MainWindow.loggingData("Connection Added:" + myID);
MainWindow.loggingData(" - MaxIdleTime:" + connection.getMaxIdleTime());
MainWindow.loggingData(" - MaxTextMessageSize:" + connection.getMaxTextMessageSize());

synchronized (connection) {
// Setに自身を登録
wsConnections.add(this);
}
}

// WebSocket 接続にてクライアントからのデータを受信した際に呼ばれるメソッド
@Override
public void onMessage(String msg) {

// すべてのWebSocketなコネクションにメッセージを投げる
for (MyWebSocket ws : wsConnections) {
try {
System.out.println("Get Message:" + msg);
ws.connection.sendMessage("Get Message:" + msg);
MainWindow.loggingData("Get Message via " + ws.myID);
MainWindow.loggingData(" - Message:" + msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

// WebSocket 接続終了時に呼ばれるメソッド
@Override
public void onClose(int parameter, String msg) {
System.out.println(parameter + " disconnect. -> " + msg);
synchronized (connection) {
// Setから自身を削除
wsConnections.remove(this);
}
}
}

クライアント側はまた次の記事で(´ω`)ではまた

参考にしたサイトはこちら(´ω`)ノ
Jetty8で作るWebSocketチャット(サーバ側編)
日記 / 2012 / 01 / 22 / JettyでWebSocketを試してみた。

eXtreme HAGO 3 (えくすとりーむ はごー みーち)に参加してきた

どもーRamencozoです(´ω`)

沖縄県内のエンジニアが集まってネタを披露しまくる技術者の祭典「eXtreme HAGO」の第3回が昨日(2012/03/03)に開催されました(*´ω`*)
会のATNDはこちら → http://atnd.org/events/24700

@yasulabさんのシリコンバレーからSKypeでの発信やその教え子ら各位の若くパワー溢れるプレゼンからスタートして、中盤に女子力を補充。後半に入ってTechTechしまくりなプレゼン(@higumachan725の「つぃーとをニコ動的にスクリーンに流す、『私の発表を邪魔して!』」や、鳩動画さんや、@SNIP_SNIP_SNIPさんのリアルタイム現在地取得等)がわらわら(´ω`三´ω`)

最後らへんに僕と鈴木さんの2連ハードウェア勢で(´ω`三´ω`)みょくみょくさせていただきました(*>ω<*)
締めに@kimihito_さんのクーラーください+ステマのサブリミナルプレゼンで会はhotな内に閉じました(´ω`)ノ

自分の発表を振り返って、良い点と改善すべき点を主観で振り返ると下記な感じ。

良い点:
・みょっくんの可愛らしさを余すところ無く示せた(*´ω`*)
・動作デモをストレートに終えた
・ノリでけっこう発声よくしゃべれた

改善すべき点:
・時間余りorz
・妙な付け足しのところ噛み噛みorz
・ぶっちゃけ発表スライドの情報かなり不足→システム内部の動きとか不明
・デモが動かなかったときの対策をなんらしてなかった件→動画とかもナシ
・コントローラ使ってデモしてたときマイク握ってなかった→Ustがあああ
・てかそもそも、会場の後ろの人はみょっくん見えてなかったんじゃね的な

(`ェ´)ピャー

みょっくん自体の中身とかについては記事書くんでそっちで勘弁してください(´ω`)

あ、でもって夜の部(´ω`)。

Twi廃アプリご紹介しましたが、まさかの@unknown_22さんによる飛び込みTwitterクライアントアプリのプレゼンがありまして(゚ω゚*)
@unknown_22さんはクライアント作成歴やPost数やTwitterの使用スタイル等、非常に深くご理解なさってたようで自分調子こいてました&アゴにカウンターくらった気分でしたwwついのーんは神
ですんで自分のあの発表は「自分、廃人志望です」が正解だったようです(^p^)シツレイしました

そっちも記事書きますんでソレでご勘弁をば(ただ某@yamanetoshiさまからC2○M的なナニが云々的なご意見頂いてるのでソレの適用後かもしんないスね(^p^))

てなワケでめちゃくちゃ楽しい会でございましたヾ(*´ω`*)ノシ eXtreme Hagothonは1週間とのことですが行けるかなー…?

ではまた(*´ω`*)ノ

あなたとTLにやすらぎを -みょっくん(´ω`)-

どうも、らーめん小僧と申します(´ω`)このたび癒し系を目指したつもりのアプリをリリースいたしました。
※ぶっちゃけ特段意味がないままノリで突っ走ったアプリですんでご勘弁を

PCまたはAndroidで直リンク: みょっくん(´ω`)
QRコード(QRコード無料作成さんを利用させていただきました):

2013/02/10 追記:
PC・スマートフォン(iPhone, Android, WindowsPhone, BlackBerry, webOSその他もろもろ)・ガラケー(たぶんイケる)のブラウザからみょっくんツィートできる「Webからみょっくん」始めましたヾ(´ω`)ノシ
アクセスはこちら→ http://myokkunweb-ramencozo.dotcloud.com/

(´ω`)←この子の正式な名前はわかんないままですが、仮称として個人的に「みょっくん」と呼ぶことにします。
(´ω`三´ω`)みょくみょく←ある日よくわかりませんがアタマにふって湧いた個人的にかわいい動作です。「みょくみょく」と呼びます。詳細はこちらをご覧ください。

そのうえで本アプリ「みょっくん(´ω`)」です。このアプリはウィジェットとしてホームスクリーンに、または通知領域にみょっくんを置き、そのみょっくんをタップするとランダムなみょくみょくtweetをする、というものです。
一応Android1.6から対応してます。ただし動作確認はAndroid2.2.1なIS06でしかしてないので動作報告をぜひぜひお待ちしております。

使い方の流れとして、


1.Twitterアカウント認証
2.ウィジェットの配置、通知領域への常駐、ハッシュタグ付与
3.ひたすらタップ

となっています。

1.Twitterアカウントの認証:
アプリ一覧から「みょっくん(´ω`)」をタップして起動します。初回起動時は下のような画面になっていると思います。

アプリの画面の一番上に現在認証されているTwitterアカウントの名前が表示されます。初回起動時は認証がなされていないので「なし」と表示されているはずです。

すぐ下のボタン、「Twitterにログイン」をタップすると認証用の画面に切り替わります。ユーザー名とパスワードを入力後、「連携アプリを認証」のボタンを押してください。

すると認証用のPINコードが表示されますので、画面下のテキスト入力エリアにPINコードを入力して、「認証」ボタンを押してください。
なお、このPINコードは認証作業をするたびに変更されるので、友人とか知らないおっさんとかに見られても別に痛くもかゆくもうまくもありません。

認証が完了すると最初の画面にあった現在のユーザーのところが自分のアカウント名になっていることと思います。
これでTwitterアカウントの認証作業は完了です。



2.ウィジェット・通知領域への配置等:
まずウィジェットから。ホームスクリーンの何もない領域を指で長押ししてポップアップを出し、「ウィジェット」から「みょっくん(´ω`)」を選んでください。

次に通知領域とハッシュタグです。最初の設定画面の「通知領域に常駐」のスイッチをONにすると常駐します。また、下の「ハッシュタグをつける」のスイッチをONにすると「#みょっくん」のタグ付きでつぃーとされます。

こんな感じでみょっくんが通知領域に常駐します。



3.つぃーと!:
みょっくんをウィジェットでホームスクリーンに、または通知領域に配置できたら、みょっくんを指でぽちっとタップしてあげてください。つぃーとされます。



番外.別アカウントの認証:
また、別のアカウントでみょっくんアプリを認証する際、IDとパスを記憶しちゃった方は下図のようにログアウトボタンを押すことで再度IDとパスワードの入力ができるようになります。みょっくんが覚えていられるアカウントは1個だけですので、違うアカウントでつぶやきたくなったら再度認証してください。



今のところ50パターンくらい入れてあります。タップするたびにランダムでつぃーとします。
Twitterは同じ文章のつぃーとを弾くような仕様になっていますが、このアプリでは弾かれないように同じつぃーとをした数だけ全角スペースを追加してスルーリしてます。(しかしTwitterさんに悪い気もするので控えめに)

不具合等ございましたら@RamencozoにリプやDMを、またはこのページにコメントやマーケットの方のコメントにてよろしくお願いします。
目安としてご報告テンプレ置きますのでよろしければご参考に。

                                                  • -

・機種名(Xperia arcとかIS01とかGalaxyS2とか)
・どういうタイミングで(ウィジェットをタップしたとき、Twitter認証をしたとき、ほか)
・何が起きたか(反応を示さなかった、いきなり強制終了、設定が勝手に消えた、ほか)

                                                  • -

2012/02/24時点での動作確認端末
AndroidMarketで収集されたインストール済みの端末リスト載せます
正確には「動作確認端末」ではなく「インストール済み端末」なのですが一応。この中で動作不良とかありましたらいつでもご連絡をー

ちなみに↑の「jmasai」って端末はどうやらIS06(au SIRIUSα)のことらしいです(´ω`)へー

Android1.6から対応取ってるのでたぶんだいたいの機種で大丈夫とは思いますが、まったく動かなかった等の報告あればよろしくです(´ω`)

というわけでどうぞよろしくおねがいしますーヾ(*´ω`*)ノシ