LoginSignup
2
2

More than 5 years have passed since last update.

[メモ] mynewt (IoT向けのRTOS環境):BLENanoでLチカ

Last updated at Posted at 2016-07-26

概要

  • Apache Mynewt というIoTのためのRTOSをためしてみようかと。。
  • が、まだ動作してない ... 低速でうごいてたっぽい。Clock周りの修正が必要??
    とりあえず、アプリ側のウェイトを短くする.
  • (UbuntuでJlinkの環境をうごかすのが面倒...フラッシュに焼いて、デバッグ以降..は、そのうち。。)

環境

  • Ubuntu 16.04 64bit
  • BLENano nRF51822ベース

手順~ツール類の準備

Linuxのツール Set up toolchain for Linux

#1. Install gcc/libc that will produce 32-bit executables:
sudo apt-get install gcc-multilib libc6-i386
#2. Install gdb
sudo apt-get install gdb

newtのインストール Install newt tool on Linux

#1.  Install git, libcurl
sudo apt-get install git 
sudo apt-get install libcurl4-gnutls-dev 
#2. Install Go, the programming language
## ワーク
cd $HOME
mkdir -p dev/go 
cd dev/go
export GOPATH=`pwd`
## golangインストール.
sudo apt-get install golang 
#3. Create local repository
go get mynewt.apache.org/newt/...
#4. Build the Newt tool
cd $GOPATH/src/mynewt.apache.org/newt/newt
go install
ls "$GOPATH"/bin/
# PATHをはる
export PATH=$GOPATH/bin:$PATH

ARMのクロスコンパイラのインストール Install ARM cross arm tools for Linux

# 16.04だといらない??.
#sudo apt-get remove binutils-arm-none-eabi gcc-arm-none-eabi 
#sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded 
#
sudo apt-get update 
sudo apt-get install gcc-arm-none-eabi
sudo apt-get install gdb-arm-none-eabi
#
# Install OpenOCD
# sudo apt-get install openocd 
# 0.8.0を入れろと書いてあるが、ubuntu16.04だと、0.9.0がインストールされるので、あとで検討...

手順~最初のプロジェクト

Create Your First Mynewt Project

... そのままやればよい...Linux上で0 1 0 1とprintfされる。

手順~BLENanoで、プロジェクト作成・ビルド

  • sudo apt-get install srecord
    srecのツールをインストール. intel hexファイル作成に使用.
cd $HOME/dev
rm -rfv myproj
#
newt new myproj
cd myproj
#
#vi project.yml
# `project.yml`の`0-latest` => `0.0.0`に変更することで、developブランチから持ってくる.
sed -i 's/0-latest/0.0.0/' project.yml
#
newt install -v
# ファイルは、nrf51dkから持ってくる..そうしないとリンクエラーになる..
cd repos/apache-mynewt-core/hw/bsp/nrf51-blenano/
cp -v ../nrf51dk/*.ld ./.
cp -v ../nrf51dk/src/*.c ./src
cp -v ../nrf51dk/include/bsp/*.h ./include/bsp/
#
# vi include/bsp/bsp.h
## - include/bsp/bsp.h___21から19に変更。
## //#define LED_BLINK_PIN   (21)
## #define LED_BLINK_PIN   (19)
sed -i 's/(21)/(19)/' include/bsp/bsp.h
#
#
cd $HOME/dev/myproj
#
# ターゲット作成.
#Lチカ アプリ.
newt target create blink_blenano
newt target set blink_blenano app=apps/blinky
newt target set blink_blenano bsp=@apache-mynewt-core/hw/bsp/nrf51-blenano
newt target set blink_blenano build_profile=debug
# ブート.
newt target create blenano_boot
newt target set  blenano_boot app=@apache-mynewt-core/apps/boot
newt target set  blenano_boot bsp=@apache-mynewt-core/hw/bsp/nrf51-blenano
newt target set  blenano_boot build_profile=optimized
# 確認.
newt target show
# ビルド
newt build blenano_boot
newt build blink_blenano
# 署名?して、イメージ作成
newt create-image blink_blenano 1.0.0

#
# HEX イメージ作成.
srec_cat bin/blenano_boot/apps/boot/boot.elf.bin -binary  -offset=0x0 -o boot.hex -intel
srec_cat bin/blink_blenano/apps/blinky/blinky.img -binary  -offset=0x8000 -o img.hex -intel
srec_cat boot.hex -intel img.hex -intel -o img_OUT.HEX -intel --line-length=44
  • 生成物

    • bin/blenano_boot/apps/boot/boot.elf (?? 0x0000から配置 ??)
    • bin/blink_blenano/apps/blinky/blinky.img (?? 0x8000から配置 ??)
    • img_OUT.hex => mbedのドライブに放り込んで焼く。
  • 5秒くらいごとにLチカする。

  • アプリ側のウエイトをかえる...

    myproj/apps/blinky/src/main.cのblinky_task_handler()
    ...
        /* Wait one second */
        os_time_delay(200); //<<<=== 1000から 200くらいに。
    
        /* Toggle the LED */
        hal_gpio_toggle(g_led_pin);
    ...
    
再ビルドする
# ビルド
newt build blenano_boot
newt build blink_blenano
# 署名?して、イメージ作成
newt create-image blink_blenano 1.0.0
#
# HEX イメージ作成.
srec_cat bin/blenano_boot/apps/boot/boot.elf.bin -binary  -offset=0x0 -o boot.hex -intel
srec_cat bin/blink_blenano/apps/blinky/blinky.img -binary  -offset=0x8000 -o img.hex -intel
srec_cat boot.hex -intel img.hex -intel -o img_OUT.HEX -intel --line-length=44

=> ちょっとはやくなった。

その他

  1. BLE動かすのは、まだ先だな... (だれか...

  2. HEXを作って、mbedみたいにやいてうごかないか、、と試したが、できなかった。
    => 5倍くらい遅いスピードでLチカしてたっぽい

  3. newtのloglevel

    src/mynewt.apache.org/newt/newtmgr/cli/logs.go
    ...
    const (
            DEBUG    uint64 = 1
            INFO     uint64 = 2
            WARN     uint64 = 4
            ERROR    uint64 = 8
            CRITICAL uint64 = 10
            /* Upto 7 custom loglevels */
            PERUSER uint64 = 12
    )
    
    const (
            STREAM_LOG  uint64 = 0
            MEMORY_LOG  uint64 = 1
            STORAGE_LOG uint64 = 2
    )
    
    func LoglevelToString(ll uint64) string {
            s := ""
            switch ll {
            case DEBUG:
                    s = "DEBUG"
            case INFO:
                    s = "INFO"
            case WARN:
                    s = "WARN"
            case ERROR:
                    s = "ERROR"
            case CRITICAL:
                    s = "CRITICAL"
            case PERUSER:
                    s = "PERUSER"
            default:
                    s = "CUSTOM"
            }
            return s
    }
    ...
    
  4. メモ

myproj/repos/apache-mynewt-core/libs/os/src/os_task.cに実体
int 
os_task_init(struct os_task *t, char *name, os_task_func_t func, void *arg, 
        uint8_t prio, os_time_t sanity_itvl, os_stack_t *stack_bottom, 
        uint16_t stack_size)
myproj/apps/blinky/src/main.c
...
/* Init all tasks */
volatile int tasks_initialized;
int init_tasks(void);

/* Task 1 */
#define BLINKY_TASK_PRIO (1)
#define BLINKY_STACK_SIZE    OS_STACK_ALIGN(256)

struct os_task blinky_task;
os_stack_t blinky_stack[BLINKY_STACK_SIZE];
static volatile int g_task1_loops;

/* For LED toggling */
int g_led_pin;

void
blinky_task_handler(void *arg)
{   
    struct os_task *t;

    g_led_pin = LED_BLINK_PIN;
    hal_gpio_init_out(g_led_pin, 1);

    while (1) {
        t = os_sched_get_current_task();
        assert(t->t_func == blinky_task_handler);

        ++g_task1_loops;

        /* Wait one second */
        os_time_delay(1000);

        /* Toggle the LED */
        hal_gpio_toggle(g_led_pin);
    }
}

/**
 * init_tasks
 *
 * Called by main.c after os_init(). This function performs initializations
 * that are required before tasks are running.
 *
 * @return int 0 success; error otherwise.
 */
int
init_tasks(void)
{
    os_task_init(&blinky_task, "blinky", blinky_task_handler, NULL,
            BLINKY_TASK_PRIO, OS_WAIT_FOREVER, blinky_stack, BLINKY_STACK_SIZE);

    tasks_initialized = 1;

    return 0;
}

/**
 * main
 *
 * The main function for the project. This function initializes the os, calls
 * init_tasks to initialize tasks (and possibly other objects), then starts the
 * OS. We should not return from os start.
 *
 * @return int NOTE: this function should never return!
 */
int
main(int argc, char **argv)
{
    int rc;

#ifdef ARCH_sim
    mcu_sim_parse_args(argc, argv);
#endif

    os_init();

    rc = init_tasks();
    os_start();

    /* os start should never return. If it does, this should be an error */
    assert(0);

    return rc;
}

PC上でのhal_gpio_toggleのしくみ ... printfしてる

myproj/repos/apache-mynewt-core/hw/mcu/native/src/hal_gpio.c
...
void hal_gpio_write(int pin, int val)
{
    if (pin >= HAL_GPIO_NUM_PINS) {
        return;
    }
    if (hal_gpio[pin].dir != OUTPUT) {
        return;
    }
    hal_gpio[pin].val = (val != 0);
    printf("hal_gpio set pin %2d to %1d\r", pin, hal_gpio[pin].val);
    fflush(stdout);
}

int
hal_gpio_read(int pin)
{
    if (pin >= HAL_GPIO_NUM_PINS) {
        return -1;
    }
    return hal_gpio[pin].val;
}

int
hal_gpio_toggle(int pin)
{
    int pin_state = (hal_gpio_read(pin) != 1);
    hal_gpio_write(pin, pin_state);
    return pin_state;
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2