BU-353 認識

手順を整理して master からブランチ作成して盛り込んでみる事に。前提としては armadillo500fx な eclair に BU-353 な GPS デバイスを認識させる、というソレ。

手順

としては以下?

  • master ブランチから repo start
  • BoardConfig.mk 修正
  • prelink-linux-arm.map 修正
  • freerunner_platform_hardware_hw を external 配下に clone
  • system.prop 修正
  • gps_freerunner.c 修正
  • mm 使って libfreerunner_gps と libhardware_legacy を make
  • Android なイメージ作成
  • 実機転送して stty で baud rate 変更して chroot で起動

順に盛り込み内容を以下に。

master ブランチから repo start

原本がある、というのは良い。

$ repo checkout master
$ repo start test0722 --all

BoardConfig.mk 修正

vendor/sola/a500fx/BoardConfig.mk の末端に以下を追加。

BOARD_HAVE_FREERUNNER_GPS := true
BOARD_GPS_LIBRARIES := libfreerunner_gps

BOARD_HAVE_FREERUNNER_GPS はこの後 clone する gps_freerunner な Android.mk にて使われております。フライング気味ですが以下。

$ cat external/freerunner_platform_hardware_hw/gps/Android.mk 
# hardware/libfreerunner_gps/Android.mk

ifeq ($(strip $(BOARD_HAVE_FREERUNNER_GPS)),true)

  LOCAL_PATH := $(call my-dir)

  include $(CLEAR_VARS)

  LOCAL_SRC_FILES := \
    gps_freerunner.c

  LOCAL_MODULE := libfreerunner_gps

  LOCAL_SHARED_LIBRARIES := \
    libutils \
    libcutils \
    libdl \
    libc

  include $(BUILD_SHARED_LIBRARY)

endif
$

true でないとコンパイル対象にならない模様。また、BOARD_GPS_LIBRARIES は libhardware_legacy 方面の Android.mk にて使われております。

$ cat hardware/libhardware_legacy/gps/Android.mk 
# Use hardware GPS implementation if available.
#
ifneq ($(BOARD_GPS_LIBRARIES),)
  LOCAL_CFLAGS           += -DHAVE_GPS_HARDWARE
  LOCAL_SHARED_LIBRARIES += $(BOARD_GPS_LIBRARIES)
endif

# Use emulator GPS implementation if QEMU_HARDWARE is set.
#
USE_QEMU_GPS_HARDWARE := $(QEMU_HARDWARE)

ifeq ($(USE_QEMU_GPS_HARDWARE),true)
    LOCAL_CFLAGS    += -DHAVE_QEMU_GPS_HARDWARE
    LOCAL_SRC_FILES += gps/gps_qemu.c
endif

LOCAL_SRC_FILES += gps/gps.cpp

$

freerunner なライブラリが上記の通り、libfreerunner_gps になっているのでこれを代入しておけば OK な模様。
ちなみに vendor/sola 配下は repo の管理範疇外だったので branch 切り替えても中身は変わってなかった件。(とほほ
# build も build/core も同様でした

prelink-linux-arm.map 修正

こちらですが、make 時に prelink というモノを作るらしく (詳細は現時点で不明)、その時に mapping する的情報なテキストファイルにエントリが無いと駄目らしい。Android.mk に

LOCAL_PRELINK_MODULE := false

とやれば、との記述もありましたが、こちらは採用せず build/core/prelink-linux-arm.map の末端に情報を追加すれば良い模様。以下を末端に追加しています。

libfreerunner_gps.so    0x9A000000

freerunner_platform_hardware_hw を external 配下に clone

以下か。

$ cd external
$ git clone git://gitorious.org/android-on-freerunner/freerunner_platform_hardware_hw.git

中身に手を入れるのは別途にて。

system.prop 修正

gps_freerunner.c の中で ro.kernel.android.gps なプロパティの値を使ってデバイスファイルを開く、というコトをしてますので設定エントリを追加しておく必要があります。

ro.kernel.android.gps=ttyUSB0

gps_freerunner.c 修正

こうやって纏めてみると意外に盛り込む量自体は少ないですね。参照したマニュアルの類が以下です。

しかもこれも repo の管理範疇外なので残ってたりしてorz
仕方が無いので mv でリネイムして clone しなおします。

freerunner_gps_set_position_mode 手続き

ここは安易にコメントアウトで対応しております。ある意味ダウト。

static int freerunner_gps_set_position_mode(GpsPositionMode mode, int fix_frequency)
{
    GpsState*  s = _gps_state;
    
    // only standalone supported for now.
/*
    if (mode != GPS_POSITION_MODE_STANDALONE)
        DFR("%s: called with bad GpsPositionMode !!", __FUNCTION__);
        return -1;
*/

まだ原因究明には至っていませんので、継続調査必要。

gps_dev_set_nmea_message_rate 手続き

全部引用しますが、基本的にはコマンド文字列の修正のみ。

static void gps_dev_set_nmea_message_rate(int fd, char *msg, int rate)
{

  char buff[50];
  int i;
/*
  sprintf(buff, "$PUBX,40,%s,%d,%d,%d,0*", msg, rate, rate, rate);
*/
  sprintf(buff, "$PSRF103,%s,00,%02d,01*", msg, rate);

  i = strlen(buff);

  sprintf((buff + i), "%02x\r\n", gps_dev_calc_nmea_csum(buff));

  gps_dev_send(fd, buff);

  DFR("gps sent to device: %s", buff);

  return;

}
gps_dev_set_baud_rate 手続き

こちらもコマンド文字列の修正のみ。PUBX なコマンドの場合、3 回出力が必要だったみたいですが、PSRF なコマンドでは一度のみ、にしてます。

static void gps_dev_set_baud_rate(int fd, int baud)
{

  char buff[50];
  int i, u;
/*
  for (u = 0; u < 3; ++u) {

    sprintf(buff, "$PUBX,41,%d,0003,0003,%d,0*", u, baud);
*/
    sprintf(buff, "$PSRF100,1,%d,8,1,0*", baud);

    i = strlen(buff);

    sprintf((buff + i), "%02x\r\n", gps_dev_calc_nmea_csum(buff));

    gps_dev_send(fd, buff);

    DFR("gps sent to device: %s", buff);
/*
  }
*/
  return;

}
gps_dev_set_message_rate 手続き

こちらは gps_dev_set_nmea_message_rate 手続きの呼び出し元なんですが、PSRF103 コマンドに渡すメッセージ文字列が異るという事で以下の修正を盛り込んでおります。

static void gps_dev_set_message_rate(int fd, int rate)
{

  unsigned int i;

  char *msg[] = {
                 "00", /* GGA */
                 "01", /* GLL */
                 "02", /* GSA */
                 "03", /* GSV */
                 "04", /* RMC */
                 "05", /* VTG */
                 "08"  /* ZDA */
/*
                 "GGA", "GLL", "ZDA",
                 "VTG", "GSA", "GSV",
                 "RMC"
*/
                };

  for (i = 0; i < sizeof(msg)/sizeof(msg[0]); ++i) {
    gps_dev_set_nmea_message_rate(fd, msg[i], rate);
  }

  return;

}
gps_dev_init 手続き

デフォルトでは gps_dev_set_baud_rate は呼び出されていないので、初期化な手続きから呼び出す形を取りました。

static void gps_dev_init(int fd)
{

  gps_dev_power(1);

  gps_dev_set_baud_rate(fd, 4800);

  usleep(1000*1000);

  // To set to STOP state
  gps_dev_stop(fd);

  return;

}

gps_dev_set_baud_rate の呼び出しが追加されてます。

mm 使って libfreerunner_gps と libhardware_legacy を make

mm などという便利なツールがあるという事自体を知りませんでした。make は以下なカンジになります。

$ source $ANDROID/build/envsetup.sh
$ cd $ANDROID/external/freerunner_platform_hardware_hw
$ mm
$ cd $ANDROID/hardware/libhardware_legacy
$ mm -B

よくよく考えたら

$ touch $ANDROID/hardware/libhardware_legacy/gps/gps.cpp

して mm でも良かったんですね。

Android なイメージ作成

armadillo500fx なスクリプトを使います。

$ $ANDROID/vendor/sola/a500fx/image/armadillo500fx-image.sh

実機転送して stty で baud rate 変更して chroot で起動

上記スクリプトにて vendor/sola/a500fx/image に android.tar.gz ができるので、何らかの方法で実機の SSD な領域 (?) に転送します。その後は以下。

# tar zxvf android.tar.gz
# stty -F /dev/ttyUSB0 4800
# chroot ./android /init

今から

上記手順が正しいかどうか、実地検証ッス。

検証終了

上記手順で何とかなってるみたいですが、クリーンな環境 (?) で試験してみたいな。来週自宅持ち帰りな予定なのでソコでヤッてみます。