2018年11月25日日曜日

Raspberry Pi3 Redmine導入 エラーからの復活 まとめ

[背景]
https://chuchulabo.blogspot.com/2018/11/raspberry-pi3-redmine.html
でRedmine入れて,他のPCからRedmineのページが見れることを確認した。
浮かれた気分でRaspberry Pi3 を「sudo reboot」で再起動!

もう一度,Redmineのページが見れるかどうかを確認。
・・・見れなくなってた・・・
これが出るようになった。

We're sorry, but something went wrong.

We've been notified about this issue and we'll take a look at it shortly.
なーんーでーやー!

[目的]
Redmineのページを見れるように修復

[内容]
----- 現象 -----
いろいろいじってると,postgresqlにログインできないなくなっていることに気が付いた。
pi@raspberrypi:/ $ psql
psql: サーバに接続できませんでした: そのようなファイルやディレクトリはありません
ローカルにサーバが稼動していますか?
Unixドメインソケット"/var/run/postgresql/.s.PGSQL.5432"で通信を受け付けていますか?
----- 修正方法 -----
postgresqlを再インストールすれば直った。
再インストールの方法
  1. postgresqlを削除 「sudo apt-get --purge remove postgresql」
  2. postgresqlが削除できているか確認 「dpkg -l | grep postgres」
  3. 何も出てこなければOK。
    そうでなければ,
    「sudo apt-get --purge remove postgresql postgresql-doc postgresql-common」
    といった形で,出てきたものを一つずつスペースで区切って削除する。
  4. 「dpkg -l | grep postgres」で,何も表示されなくなるまで繰り返し。
  5. 再起動 「sudo reboot」 (別にいらないかも)
たとえば,「dpkg -l | grep postgres」で,つぎのように表示された場合,
pi@raspberrypi:/ $ dpkg -l | grep postgres
ii  postgresql-client-9.6                 9.6.10-0+deb9u1                   armhf        front-end programs for PostgreSQL 9.6
ii  postgresql-client-common              181+deb9u2                        all          manager for multiple PostgreSQL client versions
「sudo apt-get --purge remove postgresql postgresql-client-9.6 postgresql-client-common」
を実行して削除する。
最終的に,「dpkg -l | grep postgres」を実行して,何も表示されなくなればOK。
参考 : https://askubuntu.com/questions/32730/how-to-remove-postgres-from-my-installation

次に,postgresqlのインストールと初期設定を行う。 Redmineの公式の通りにしただけでは,おそらく同じようにRaspiを再起動したら使えなくなると思ったため。
  1. postgresqlをインストール 「sudo apt install postgresql」
  2. postgresqlサーバをインストール 「sudo apt install postgresql-server-dev-9.6」
  3. postgresqlユーザで,postgresqlのターミナルに入る。 「sudo -u postgres psql postgres」 ("postgres=#" が表示される。)     
    • 「CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'your_password' NOINHERIT VALID UNTIL 'infinity'; CREATE ROLE」
    • 「CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;」
    • 「\q」(postgresqlからquit)
  4. postgresユーザのパスワード変更 「sudo passwd postgres」
  5. postgresユーザでログイン 「su - postgres」
    piユーザから,posgtresユーザに切り替わる。(postgres@raspberrypi:~$ が表示される。)
    • postgresqlのターミナルに入る。 「psql」
      • データベースロールの確認 「\du」
      • 「\q」(postgresqlからquit)
    • postgresユーザからログアウト 「exit」
  6. ディレクトリ移動 「cd /etc/postgresql/9.6/main/」
  7. pg_hba.confを編集 「sudo nano pg_hba.conf」
    ・・・(省略)・・・
    # Database administrative login by Unix domain socket
    # local   all             postgres                                peer
    local   all             postgres                                trust 
    
    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    
    # "local" is for Unix domain socket connections only
    # local   all             all                                     peer
    local   all             all                                     trust
    ・・・(省略)・・・
    
  8. postgresqlを再起動 「sudo service postgresql reload」
  9. ここから先は,公式の操作の6.からを再度トレースする https://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_on_Debian_9
調べながらの作業では,実際に,上述の手順では行なっていないが,見直すと,こんな感じになっていた。

[結論]
大体の流れとして,psqlを再インストールして,postgresユーザの設定をして,公式の通りに操作すればOK。

[参考URL]

2018年11月20日火曜日

Raspberry Pi3 Redmine導入 仕切り直し


Raspberry Pi3 Redmine導入 仕切直し

[背景]
Redmineの導入に前失敗したし,
このままやと負けた気がするし,
とにかくRedmine入れたい!
いじりたい!

[目的]
Rasperry Pi3 Raspbian stretch にRedmineを入れる

[内容]
まず,前回で,設定がぐちゃぐちゃになっていたので,クリーンインストール。
NOOBで,Raspbianを入れて,クリーンな状態に。

  1. Raspbianの初期設定。
    https://chuchulabo.blogspot.com/2018/09/raspberry-pi-3.html
  2. Redmineのインストール。
    前回日本語で調べてたら出てこなかったけど,「redmine howto install」で調べたら,Redmineの公式のマニュアルが出てきた。
    RaspbianはDebian系なので,Debian Stretchへのインストール方法をそのまま実行。
    http://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_on_Debian_9
  3. 終わり!
「redmine howto install」でトップに出てくるリンク先は,上に貼ったリンクとは違う。
が出てくる。
このページに,
Redmine should run on most Unix, Linux, macOS, macOS Server and Windows systems as long as Ruby is available on this platform. See specific installation HowTos here.
と書いてある。
OS毎のインストール方法を見たい場合は,"here"のリンク先を参照してね。とのこと。
このリンク先から,Debian Stretchへのインストール方法のページに移動する。
ちなみに,"here"のリンク先は,以下。
http://www.redmine.org/projects/redmine/wiki/HowTos

[注意事項]
Redmineのインストールで,bundleをインストールするところがある。
"bundle install"コマンドを実行する前に,
"cd /opt/redmine/redmine-3.4.6/"コマンドで,ディレクトリを移動しておくこと。
理由としては,"bundle install"コマンドは,Gemfileがあるところでやらないと失敗するから。
できなくても,出てきたエラーでググったら簡単にどうすればいいかがわかる。
確か,GemFileがあるところをfindで探して,・・・的なHPがあるので,見たらわかる。

また,Redmineのインストールのマニュアルにある,
your_ip_addressとか,your_password とかは,適宜自分のraspberry piの設定に合わせる。

[まとめ]
公式あるなら,初めから見てればよかった・・・。
気づかなかった・・・そりゃ公式あるよね・・・。



2018年10月18日木曜日

Raspberry Pi3 Redmine導入(諦めました)

Raspberry Pi3 Raspbian Stretch redmineインストール覚書
(まだできてません)

[背景]
Raspberry Piをサーバー化してみたい
なんとなくredmineを使いたい

[目的]
Raspberry Pi でRedmineの設定を行う

[内容]
以下のコマンドを順番に実行する。

■ソフトウェアアップデート
  • sudo apt-get update
  • sudo apt-get upgrade 


■Apache, Imagemagick, Ruby, Gitをインストール
  • sudo apt-get install apache2 libapache2-mod-passenger
  • sudo apt-get install imagemagick libmagick++-dev
  • sudo apt-get install ruby-dev bundler
  • sudo apt-get install git subversion

■MySQLをインストール
  • sudo apt-get install mysql-server default-libmysqlclient-dev 



MySQLのパスワード設定
SSHでインストールとかしてると,rootパスワード設定しろとか言ってくれないから,コマンドを叩いて設定する。

MySQLにログイン。

  • sudo mysql -u root

rootでログインしたら,「MariaDB [(none)]> 」みたいのが表示される。
その状態で,以下のコマンドを実行してrootのパスワードを変更する。
  • update mysql.user set password=password('XXXXXXXX') where user = 'root';
  • (XXXXXXXXは,パスワード。)
つぎに,パスワードの変更を適用して,MySQLのrootからログアウト。
  • flush privileges;
  • exit;
最後に,パスワードが反映されているかどうかをチェックする。
  • sudo mysql -u root -p
  • (この後,パスワードの入力が求められるので,XXXXXXXX(自分が設定したパスワード)を入力する)
多分,rootだけでなく,piについても,同様に設定するのが良いのだと思う。


■MySQLにRedmine用のデータベースを作成

MySQLにログイン。

  • sudo mysql -u root -p

MySQLにログイン後,以下のコマンドを実行。
  • create database redmine default character set utf8;
  • (redmineという名前のデータベースを作成)
  • grant all on redmine.* to redmine@localhost identified by 'redmine';
    (ユーザ名 : redmine, Pass : redmine のユーザを作成)
  • flush privileges;
    (適用!)
redmine用のデータベースが作成されるので,ログアウト。

  • exit;


■Redmineのインストール
  • sudo mkdir -p /var/www/redmine
  • sudo chown www-data /var/www/redmine
  • sudo -u www-data svn co http://svn.redmine.org/redmine/branches/3.3-stable /var/www/redmine
  • (Enter押した記憶ないけど,突然のチェックアウト開始だった)
チェックアウト成功の確認は,以下のコマンドで,なんか色々入ってたらOKだと思う。
  • ls /var/www/redmine

■RedmineとMySQLのRedmine用データベースの紐付け
ファイルを作成。
  • sudo nano /var/www/redmine/config/database.yml
nanoで,以下を入力して,保存。


production:
  adapter: mysql2
  host: localhost
# Redmine用のMySQLデータベース名
  databese: redmine
# Redmine用のMySQLユーザ名
  username: redmine
# Redmine用のMySQLパスワード
  password: redmine
  encoding: utf8


設定ファイルを作成(コピー)。
  • sudo cp /var/www/redmine/config/configuration.yml.example /var/www/redmine/config/configuration.yml


■gemパッケージインストール
  • cd /var/www/redmine
  • sudo -u www-data bundle install --without development test --path vendor/bundle

■gemパッケージの初期設定?
  • sudo -u www-data bundle exec rake generate_secret_token
  • sudo -u www-data RAILS_ENV=production bundle exec rake db:migrate
  • sudo -u www-data RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data

■Apacheの設定
  • cd /etc/apache2/sites-enabled
  • sudo nano 000-default.conf
nanoで,以下のように変更して,保存。

DocumentRoot /var/www/html
DocumentRoot /var/www/html
DocumentRoot /var/www/redmine/public


■Raspberry Piの再起動

  • sudo reboot


■Redmineへアクセス

ブラウザから,Raspberry PiのIPアドレスを叩いて,アクセスしてみた。

We're sorry, but something went wrong.

We've been notified about this issue and we'll take a look at it shortly.

とか出てログインはおろか,ページすら表示されないぞ!

■Redmineへアクセスできない問題の調査

●MySQLへログインができなくなってる!
色々調べてみたら,Rubuy on RAILS の問題とか,MySQLとRedmineのリンクができてないとか書いてた。
RubyやMySQLの再インストールをやったりしてるうちに,
MySQLにログインできなくなってることに気付いた。

pi@raspberrypi:/ $ sudo mysql -u root -p

mysql: error while loading shared libraries: /lib/arm-linux-gnueabihf/libreadline.so.5: invalid ELF header

このエラーは,対象のファイルがリンクされてないのが原因らしい。
再インストールしたら治るとか書いてあったが,治らなかった。
そこで,とりあえず,MySQLを再起動しようとしても,失敗する。

pi@raspberrypi:/var/log/mysql $ sudo service mysqld restart
Job for mariadb.service failed because the control process exited with error code.

See "systemctl status mariadb.service" and "journalctl -xe" for details.

で,ステータスをみてみると,


pi@raspberrypi:/var/log/mysql $ systemctl status mariadb.service
・・・(略)・・・
10月 22 00:01:17 raspberrypi systemd[1]: Starting MariaDB database server...
10月 22 00:01:18 raspberrypi systemd[1]: mariadb.service: Main process exited, code=exited, status=127/n/a
10月 22 00:01:18 raspberrypi systemd[1]: Failed to start MariaDB database server.
10月 22 00:01:18 raspberrypi systemd[1]: mariadb.service: Unit entered failed state.

10月 22 00:01:18 raspberrypi systemd[1]: mariadb.service: Failed with result 'exit-code'.

そもそもスタートしてないっぽい。
そこで,とりあえず,スタートさせようとしても,できない。

pi@raspberrypi:/var/log/mysql $ sudo service mysqld start
Job for mariadb.service failed because the control process exited with error code.

See "systemctl status mariadb.service" and "journalctl -xe" for details.

そこで,エラーの詳細を表示する。

pi@raspberrypi:/var/log/mysql $ journalctl -xe
10月 22 00:01:17 raspberrypi sudo[1249]: pam_unix(sudo:session): session opened for user root by pi(uid=0)
10月 22 00:01:17 raspberrypi systemd[1]: Starting MariaDB database server...
-- Subject: Unit mariadb.service has begun start-up
-- Defined-By: systemd
-- Support: https://www.debian.org/support
-- 
-- Unit mariadb.service has begun starting up.
10月 22 00:01:18 raspberrypi mysqld[1356]: /usr/sbin/mysqld: error while loading shared libraries: /lib/arm-linux-gnueabihf/libaio.so.1: invalid ELF head
10月 22 00:01:18 raspberrypi systemd[1]: mariadb.service: Main process exited, code=exited, status=127/n/a
10月 22 00:01:18 raspberrypi systemd[1]: Failed to start MariaDB database server.
-- Subject: Unit mariadb.service has failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
-- 
-- Unit mariadb.service has failed.
-- 
-- The result is failed.

ここでも,リンクに失敗しているらしい。
/usr/sbin/mysqld: error while loading shared libraries: /lib/arm-linux-gnueabihf/libaio.so.1: invalid ELF head」が,リンク失敗のところ。

解決法は,リンクを教えてやればいいとのこと。
以下のコマンドを実行し,.cfgファイルを編集する。

  • sudo vi /etc/ld.so.conf
以下の文を追記する。


/lib/arm-linux-gnueabihf


ld.so.confには,「include /etc/ld.so.conf.d/*.conf」が書かれている。
includeされるファイルの中に,同じ文が書かれているので,リンクされそうなものだが,されていないっぽい。

この後に,以下のコマンドを実行して,MySqlを実行する。

  • service mysql start
すると,問題なく,MySqlを開始することができた。
できなかった。エラーが出た。
そこで,Raspberry Pi自体を再起動したところ,
自動でmysqlがスタートされたらしく,
MySQLにrootでログインできた。

  • sudo reboot
    (再起動)
  • mysql -u root -p
    (rootでログイン)




[参考URL]







2018年10月1日月曜日

Raspberry Pi 3 SSH接続

Raspberry Pi3 Raspbian Stretch でSSH接続 覚書

[前提]
  • PC : Mac OS High Sierra
  • Raspberry Pi : Raspbian Stretch

[手順]
Raspberry Pi側の設定
  1. Raspberry PiのSSH接続を有効にする。(デフォは「無効」)
    1. スタート->設定->Raspberry Piの設定
    2. インターフェイスタブを選んで,SSHを「有効」にする
  2. Raspberry Piを再起動(いらんかも)
  3. ターミナルを立ち上げて,「ifconfig」を入力して,IPアドレスをチェック
Mac側の設定
  1. ターミナルを起動
  2. 「ssh pi@xxx.xxx.xxx.xxx」を入力
  3. パスワードが聞かれるので,Raspberry Piのpiユーザのパスワードを入力

[注意]
MacからSSH接続しようとしたら,ずっと

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
・・・
が表示されて接続拒否されてた。

これは,Mac側の問題らしい。
SSHのキーが古いよってことらしい。

  • ssh-keygen -R xxx.xxx.xxx.xxx
とコマンドをうって,再度ssh接続を試みたらつながった。
(xxx.xxx.xxx.xxxは,Raspberry Piに割り当てられてるIPアドレス)

参考URL : https://www.niandc.co.jp/sol/tech/date20150729_507.php


Raspberry Pi 3 デバイスドライバ作成 Part1

[前提]
  • HW : Raspberry pi 3
  • OS : Raspbian Stretch with Desktop

[やったこと]
gccでコンパイルとかできないといけない。
Linuxのデバイスドライバ開発では,Linuxのソースコードとヘッダが必要らしい。

メインで参考にしたURLは以下。

まずは,以下のコマンドを実行したい。
  1. sudo apt-get install build-essential
  2. sudo apt-get install git
  3. cd /usr/src
  4. sudo apt-get install linux-image-rpi-rpfv
  5. sudo apt-get install linux-headers-rpi-rpfv
しかし,4で失敗する。
エラー内容は,以下の通り。
  • ・・・へのハードリンクの作成に失敗しました : 許可されていない操作です
  • dpkg: パッケージ initramfs-tools の処理中にエラーが発生しました (--configure)
  • サブプロセス インストール済みの post-installation スクリプト はエラー終了ステータス 1 を返しました
  • etc.
調べたところ,BOOT領域が足りないのが原因っぽい。
以下のコマンドを実行した。
  1. sudo apt-get remove linux-image-4.9.0-6-rpi
    (4.9.0-6は,OSのバージョン。適宜変更のこと)
  2. sudo apt-get autoremove
  3. sudo apt-get dist-upgrade
その後,失敗していたコマンドを実行する。
  1. sudo apt-get install linux-image-rpi-rpfv
  2. sudo apt-get install linux-headers-rpi-rpfv
エラーを吐くことなく,正常に終了。

このエラーで参考にしたURLは以下。


つぎに,インストールした,linuxイメージをboot時に読み出すために,
/boot/config.txt に追加編集する。
  1. sudo vi /boot/config.txt
追加するのは,以下の文。
# Add chuchulabo : Parameters to boot on raspbian kernel(linux-image-rpi-rpfv package)
kernel=vmlinuz-4.9.0-6-rpi
initramfs initrd.img-4.9.0-6-rpi followkernel

そして,再起動。
  1. sudo reboot

そして・・・
SSHでRaspberry piに繋がらなくなりました!
うおーい!!!
間違いなく,config.txtをいじったのが悪いんやけど・・・


/********** 続く **********/


2018年9月30日日曜日

Raspberry pi 3 インストール+初期設定

Raspberry pi 3 のインストール + 初期設定の覚書

[前提]

  • PC : Mac Book Pro
  • OS : High Sierra
  • 使用SDカード容量 : 32GB
  • NOOBSでRaspbianをインストール
    "https://www.raspberrypi.org/downloads/"
  • NOOBS

    Offline and network installVersion:2.8.2Release date:2018-06-27

[インストール手順]
手順はいろんなところに載ってるので,それを参照のこと。


[インストール注意事項]

  • SDカードのファイルシステムはFAT32でなければならない。
  • 「DiskUtilityでフォーマットする場合は,MS-DOSを選択する」と書いているHPが多いが,実際は無理。
    DiskUtilityでSDカードのフォーマットはしないこと。
  • SDカードのフォーマットは,SD Card Formatter で行うこと。
    DL先 : https://www.sdcard.org/jp/downloads/formatter_4/
    シンプルなので,直感的に使える。ファイルシステムの選択はないが,デフォルトでFAT32でフォーマットしてくれる。

[初期設定]
いろんなところに載ってるので,調べる。
ただ,このサイトの「パッケージとOSの更新」くらいはやっといたほうが良い気がする。



2018年3月13日火曜日

STM32 Nucleo on mac memo

Cube MXで自動生成していくにあたり,覚書き。

・FreeRTOS リソースの自動生成は,タスクのみとする。
・ペリフェラルは,自動生成する。
 CubeMXで設定等を行う。
・タスク起動の引数で,使用するペリフェラルのポインタを全部渡す。
・タスク間通信を行うために,各タスクごとにメッセージキューを1個割りあてる。
・メッセージキューのIDとか,必要情報もタスク起動の引数で渡したらいい?

終わり?


2018年2月28日水曜日

STM32 Nucleo FreeRTOS SW割り込み on mac memo

[目標]

・スイッチで,LEDをON/OFFする。
  ・最初 : LED OFF
  ・1回目 : LED ON
  ・2回目 : LED Blink(500ms)
  ・3回目 : LED OFF
・スイッチのON/OFFには,IRQ割り込みを用いる
 (ポーリングは面白くないよね)

[前提]

・NucleoL152RE を使用
・NucleoにデフォルトでのってるLED(LD2) をLチカ
・開発環境 SW4STM32(AC6)
・コード生成ツールSTM32CubeMX を使用
http://chuchulabo.blogspot.jp/2018/02/stm32-nucleo-freertos-l-on-mac-memo.html
 で作ったプロジェクトを再利用。
 (めんどくさいから)
 (続きとして作るね)

[手順]

http://chuchulabo.blogspot.jp/2018/02/stm32-nucleo-freertos-l-on-mac-memo.html
の続き。

== Cube MXの設定 ==

CubeMXのプロジェクトを開く。
Nucleoに乗ってる青いスイッチを使用する。
で,それに繋がってるピンは,PC13。
「B1[Blue PushButton]」ってなってる。
ピンをクリックすると,そのピンに設定されている機能を設定/参照できる。
PC13をクリックして,「GPIO_EXTI13」であることを確認する。
さっき設定した「GPIO_EXTI13」は,
このPC13ピンは,GPIOで,割り込み使いますよって意味。
GPIO : 汎用入出力。General-purpose input/output の略。
EXTI : 外部割込み/イベントコントローラ。External Interrupt の略。

次に,GPIOの設定を行う。
「Configulation」タブ->「GPIO」ボタンをクリック。
Pin Configulationダイアログが立ち上がる。
「GPIO」タブを選択すると,設定されているGPIOピンが見れる。
今(Nucleoのデフォルト)は,LEDとSWの設定が見える。
「PC13-WKUP2」をクリックすると,下にどんな設定になっているかが表示される。
プルダウン形式で選択可能。
Nucleoのデフォルトは,
  ・立ち上がりエッジで割り込み
  ・プルアップ/プルダウン なし
になってる。
User Label は,自由に設定できる。
別にデフォルトでいい。
今回は,他の項目は確認しなくていい。
「OK」をクリックして,GPIOの設定は終了。

次に,割り込みの設定を行う。
さっきの立ち上がりエッジ割り込みとか,
割り込み設定じゃないのかというツッコミをしたくなったけど,
立ち上がりエッジ/立ち下がりエッジ/両エッジ とかは,汎用I/Oの割り込みだから必要なもの。
というわけで,やっぱりGPIOの設定になるのかな?

割り込みは,NVICで設定できる。
NVIC : ネスト型ベクタ割り込みコントローラ。Nested Vectored Interrupt Controllerの略。

「Configulation」タブ->「NVIC」ボタンをクリック。
NVIC Configulationダイアログが開く。
「NVIC」タブ->「EXTI line[15:10] interrupts」の「Enabled」にチェックを入れる。
「Preemption Priority」とか,「Sub Priority」とかは,とりあえずデフォルトで。
あと,FreeRTOSを使ってるので,とりあえず「Uses FreeRTOS functions」にチェックを入れておく。

「Enabled」にチェックを入れると,Code Generationの項目が勝手に設定される。
「Code Generation」タブ->「EXTI line[15:10] Interrupt」が勝手にできる。
「Generate IRQ handler」 にチェックが入っていることを確認する。
たぶん,これでNVICの設定は終わり。
「OK」をクリックする。

「Project」->「Generate Code」でコードを生成する。
生成したら,コード(もとい,プロジェクト)を開くか聞かれるので,とりあえず開く。


== 設計? ==


スイッチのON/OFFの時の割り込み(EXTI line[15:10] Interrupt)で,LEDのON/OFF/BLINKを切り替えるのもいいけど,それでは,FreeRTOS使わなくてもできる。
なので,少し回りくどいことをする。
せっかくLEDタスクを作っているので,LEDの制御は,全てLEDタスクから行うようにする。(と言っても,BLINKはタイマ機能使うけど。)
というわけで,シーケンス図。
スイッチの割り込みがかかったら,メッセージをLEDタスクに送る。
LEDタスクは,メッセージを受け取るごとに,
ON->OFF->BLINK->・・・
とLEDの光り方を変えていく。
ちなみに,これはSeq Diagで作った。
PowerPointで作ろうかとも思ったけど,線を引くのがいやだったので,Seq Diagを使用。
すごい便利。
参考 : http://blockdiag.com/ja/seqdiag/index.html

割り込みとタスクのメッセージのやりとりは,メッセージキューを使用する。
メッセージキューとメールキュー,用途どう違うのかわからんけど,
  ・メッセージキュー : int型/ポインタ のみを転送可能
  ・メールキュー : どんな型でも転送可能
って書いてある気がする。
ただ,メールキューは,メッセージキューのラッパーな気がする。
メッセージキューは,int型/ポインタ 以外の例えば構造体のデータとかを転送したい場合には,メモリプールを取得->メモリプール領域内にデータを保存->メモリプールのポインタを転送 としなければならない。
メールキューは,この一連の流れを,勝手にやってくれるものというイメージ。

メールキューの方が便利そうだが,
なんとなく,基本を知るために,メッセージキューを使う。

== 割り込みの作業準備(ただの説明) ==


今更やけど,main.cから呼ばれてるのは,
  ・HAL_Init() : stm32l1xx_hal.cに記述。
  ・SystemClock_Config() : main.cに記述。
  ・MX_GPIO_Init() : gpio.cに記述。
  ・MX_USART2_UART_Init() : usart.cに記述。
  ・MX_FREERTOS_Init() : freertos.cに記述。
  ・osKernelStart() : cmsis_os.cに記述。
で,このあと,while(1)でループ。

でも,このループにはこないはず。(たぶん)
なぜなら,タスクを起動して,そのタスクにディスパッチされるから。


今回,記述が必要なのは,LedTaskと,スイッチ割り込みがかかった時の処理。
で,これらをどこに書くかというと,
  ・LedTask -> freertos.c
  ・スイッチ割り込み -> stm32l1xx_it.c?

LedTaskに関しては,過去(https://chuchulabo.blogspot.jp/2018/02/stm32-nucleo-freertos-l-on-mac-memo.html)に記述した通り,void StartLedTask(void const * argument) 関数が,タスクの実体。

では,スイッチ割り込み(EXTI line[15:10] Interrupt)の処理の実体はどこにあるかというと,stm32l1xx_it.cにある,void EXTI15_10_IRQHandler(void) という関数がそう。
割り込みがかかると,この関数に飛んでくる。
さらに,中でHAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); を実行している。

P13は,スイッチの繋がってるピン。
つまり,スイッチ押された時に,HAL_GPIO_EXTI_IRQHandler(); 内に書いてる処理が実行される!
じゃあ,そのHAL_GPIO_EXTI_IRQHandler() はどこに書かれているのか?
これは,stm32l1xx_hal_gpio.c に書かれている。

HAL_GPIO_EXTI_IRQHandler() の中で,さらにコールバック関数(HAL_GPIO_EXTI_Callback(GPIO_Pin);)が呼び出されている。

たぶん,自分で記述すべきは,このコールバック関数だと思う。

ちなみに,割り込みかかってから,ずっと,
全部の関数で,uint16_t GPIO_Pinを引数として渡している。
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);  こんな感じで。

EXTI line[15:10] Interruptは,みたらわかるけど,10〜15 の割り込みがかかった時,呼び出される。じゃあ,さらにわけた個別の処理(10なら10の,13なら13の異なる処理)を行いたい場合,どうするか?
これはユーザーがif文とかで分岐させてやらないといけない。
最後のコールバック関数まで分けてくれている様子はないので,コールバック関数内で自分たちで書かないといけないっぽい。

さらに,自動生成のコールバック関数のコメントに,こんなことが書いてある。

/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_GPIO_EXTI_Callback could be implemented in the user file
*/

どういうことかといえば,コールバック関数が必要な場合,ここに定義してる関数は使用するな。別のとこで(ユーザーが作ったファイルで),HAL_GPIO_EXTICallback関数を定義して,その関数を使え。
ってこと。関数の最初に weak ってついてるから,もし,他の場所で同じ名前の関数があった場合には,そっちが使われるようになっている。

長くなったけど,
割り込みでやることは,
  ・ユーザーファイルを作成
  ・ユーザーファイルにHAL_GPIO_EXTICallback関数を定義
  ・定義した関数ないで,GPIO_PIN_13 の時の処理を記述(条件分岐)
  ・処理内容は,メッセージの送信
以上!

== タスクの作業準備(ほぼ割り込み)(ただの説明) ==

タスクは,何も考えずに,割り込みからメッセージが送られてきた時の処理を書けばいいんやけど,一つ問題が。

メッセージキューでメッセージを割り込みハンドラ -> タスク へ送るわけだが,メッセージキューのIDどうすんの?
extern使ったらいいのかもしれんけど,個人的にexternはあんまり好かん。
というわけで,割り込みかかった時の処理と,LEDタスクの処理は同じファイルに記述する。

でも,freertos.cにLEDの割り込みの処理書くのもなぁ・・・と思うので,
LED制御用のファイルを一個作って,そこに,割り込みの処理と,LEDタスクの処理を書くことに。
freertos.cのStartLedTask()関数からは,このLED制御用のファイルに書いた,LEDタスクの処理関数を呼び出す形にする。
図にするとこんな感じ。
気持ち悪いのが,LedCtrl.cの中に,HdrSwitch()関数が書かれていること。
SW制御ようのタスクを作って,タスク間通信をするのが正解なのかもしれない。
でも,今回はこのまま行く。(過去のログを変更するのが大変面倒だから)
次,いつかなおす!(たぶん直さない)

説明はこれくらいにしとこう。力尽きた。

== コーディング ==

書き始めたけど,すっごい書きづらいなぁ。
LED点滅用のタイマーをCubeMXで自動生成してるから,freertos.cにタイマーが書かれてるわけやけど,LedCtrl.cからタイマーの開始/停止をしたい。
freertos.cで生成してるリソースをLedCtrl.cからいじりたい場合,externするしかない気がする。
考え直した方がいいかなぁ。
CubeMXの自動生成,すごい便利やけど,FreeRTOSのリソースに関しては,自分で書いた方がいいかもしれない。タスクくらいは生成してもいいけど,その他のタイマー,メッセージキュー,メモリプールとかは自分で書いた方がいい。
externあまりしたくなければ,ユーザ作成ファイルに結局メッセージキューもメモリプールもタイマーも書くから。

・・・コーディングするのやめよっかな・・・。

コーディングやめる。
大体考えなあかんことはこれまでに書いたから,まぁ大丈夫でしょ。
何より,書きにくいし。

もっと設計ちゃんと考えなあかんなぁ・・・。




2018年2月25日日曜日

STM32 Nucleo FreeRTOS Lチカまで on Mac memo

[目標]
・FreeRTOSを使ってLチカ
  ・作成するタスクは1つ
  ・周期タイマで0.5秒周期で点滅させる

[前提]
・NucleoL152RE を使用
・NucleoにデフォルトでのってるLED(LD2) をLチカ
・開発環境 SW4STM32(AC6)
・コード生成ツールSTM32CubeMX を使用
・開発環境の構築,プロジェクトの作成は,
http://chuchulabo.blogspot.jp/2018/02/stm32-on-mac-memo.html
を参照。

[手順]

== タスクの追加 ==

http://chuchulabo.blogspot.jp/2018/02/stm32-on-mac-memo.html
で作成したプロジェクトをそのまま変更する(めんどいから)。
CubeMXのプロジェクトファイルを開く。
左サイドバーの FREERTOS->Enabled にチェックを入れる。
これだけで,FREERTOSをプロジェクトに入れてくれる。すごい!
タスクの設定をする。
まずは,LEDタスクを作成する。
これも,CubeMXで行う。
「Configuration」タブ -> 「FREERTOS」 をダブルクリック。
FREERTOS Configuration のダイアログが開くので,設定を変更する。
「Tasks and Queues」タブ -> Tasksの方の「Add」ボタンをクリック。


New Task ダイアログが開くので,LEDタスクを設定する。
以下のように設定して,「OK」を押す。
すると,LEDタスクが追加される。
追加されたのを確認したら,「Apply」をクリック -> 「OK」をクリック。

Project->generate Code で,コード生成を開始する。
すると,次のようなダイアログが出る。
よくわからんが,「Yes」を押す。
すると,CubeMXがよしなにコードを生成してくれる。
素晴らしい!

main.cでは,
MX_FREERTOS_Init();
が呼び出されているだけ。
中身は,freertos.c に書いてある。
ちゃんとvoid StartLedTask(void const * argument) ってのが生成されている。



== ちょっとFreeRTOSとCMSISについてメモ ==
使うとチェックを入れたのはFree RTOS。
だが,実際には,Free RTOSのAPIをラッパーしたCMSISのAPIを使用して,
タスクの生成は行われている。

osThreadDef とか,osThreadCreate というのは,CMSISのAPI。

FreeRTOSについて
https://www.freertos.org/index.html

CMSISについて
http://www.keil.com/pack/doc/CMSIS/RTOS/html/index.html

CMSISは,FreeRTOSや,その他のRTOSであっても,共通して使用できるように
策定されたもの。
CMSISのAPIを使っていれば,FreeRTOSから他のRTOS(ThreadXとか?)に変えても,
CMSISの部分が吸収してくれて,移行が簡単になる。

だから,今回は,CMSISのAPIをなるべく使うようにする。
(CubeMXが勝手にやってくれるんだろうけど)

== 周期ハンドラの追加 ==
タイマー機能を使用して,周期ハンドラを作る。
まず,CubeMXで設定を行う。
タイマー機能を使用するため,ソフトウェアタイマを有効にする。
「Configuration」タブ -> 「FREERTOS」 をダブルクリック。
FREERTOS Configuration ダイアログが開く。
「Config parameters」タブ->「Software timer definitions」->「USE_TIMERS」を「Enabled」に変更。
次に,タイマーを作成する設定を行う。
「Timers and Semaphores」タブ->「Timers」の「Add」ボタンをクリック。
NewTimerダイアログが開くので,以下のように設定して,「OK」をクリック。
LEDの点滅用のタイマーなので,名前をLedTimerにした。
Callbackは,タイマーで一定時間たった時に呼ばれるコールバック関数の事。

「Apply」->「OK」をクリックして,FREERTOSの設定終了。
と思ったけど,なんか,「Free RTOS Heap Usage」タブで,「×」が表示されててだめっぽいところがある。読むと,Heapサイズが足りてないっぽい。
タイマーをEnableにしたせいで,使用するHeapサイズが足りなくなったらしい。
とりあえず,Heapサイズを多くとるようにする。
「Config parameters」タブ->「Memory management settings」->「TOTAL_HEAP_SIZE」を3072→4096に変更。
すると,「Free RTOS Heap Usage」タブの「×」が「✔︎」に変わる。

これでOK!多分。
「Apply」->「OK」を押して,FREE RTOSの設定を完了する。

コード生成をしてみる。
「Project」->「Generate Code」で,コードを生成する。

freertos.cをみると,タイマが追加されていることがわかる。




== コーディング ==
MX_FREERTOS_Init(void) でタスクもタイマも作成されている。
タスクに関しては,osThreadCreate() したら,始まるみたい。
ただ,タイマは,osTimerStart()しないと,始まらないっぽい。
というわけで,
LEDタスクからLEDタイマを開始して,
LEDタイマのコールバック関数内でLEDを点滅させる。
まず,タイマをスタートさせる。

以下,コード。
-------------------------------------------------
/* StartLedTask function */
void StartLedTask(void const * argument)
{
  /* USER CODE BEGIN StartLedTask */
  osTimerStart(LedTimerHandle, 500);
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartLedTask */
}

/* LedTimerCallback function */
void LedTimerCallback(void const * argument)
{
  /* USER CODE BEGIN LedTimerCallback */
  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  
  /* USER CODE END LedTimerCallback */

}
-------------------------------------------------


さらに,freertos.cは,HALライブラリをincludeしてないので,
HAL_GPIO_TogglePin()でエラーになる。
ので,HALをincludeする。
以下,コード。
-------------------------------------------------
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"

/* USER CODE BEGIN Includes */     
#include "stm32l1xx_hal.h"


/* USER CODE END Includes */
-------------------------------------------------

以上,コーディング終わり!
500ms周期でLEDが点滅するはず!

Build -> Debug -> Resumeで,実行すると,
LEDが500ms周期で点滅した!
成功!

2018年2月23日金曜日

STM32 開発環境構築 Nucleo Lチカまで on Mac memo

[目標]
以下のインストール
・統合開発環境 SW4STM32
・コード生成ツールSTM32CubeMX
その後
・Nucleo L152RE でLチカ

[手順]
== 統合開発環境 SW4STM32 ==
  1. http://www.st.com/ja/development-tools/sw4stm32.html
    からOpenSTM32Community に入って,
    http://www.openstm32.org/Downloading%2Bthe%2BSystem%2BWorkbench%2Bfor%2BSTM32%2Binstaller
    からMAC OS/X 用の最新版をダウンロード。
    今回は,"install_sw4stm32_macos_64bits-v2.4.run"をダウンロード。
    OpenSTM32に入るには,アカウント登録が必要。
    注意 : ひたすら遅い。1時間くらいかかる。
  2. ファイルをダウンロードした場所でターミナルで開く。
    以下のコマンドを入力。
    $ chmod 755 install_sw4stm32_macos_64bits-v2.4.run 
    $ ./install_sw4stm32_macos_64bits-v2.4.run
  3. インストールのWindowが開くので,そのままデフォルトの設定で進めていく。
    ライセンスとかは,全部agreeにする。http://www.openstm32.org/Installing%2BSystem%2BWorkbench%2Bfor%2BSTM32%2Bwith%2Binstaller

    インストール始まったなーと思っても,なんか進まない時は,ターミナルを確認する。実はPasswordを求められてる。
  4. 終わり!
インストール画面
ターミナル パスワード入力


ついでに,AC6を起動して,アップデートを行う。
Help->Check for Updatesで,アップデートを開始。

== コード生成ツールSTM32CubeMX ==

  1. http://www.st.com/en/development-tools/stm32cubemx.html?sc=stm32cubemx
    から,CubeMXをダウンロード。zipファイルでダウンロードできる。
  2. AC6を立ち上げ,Help->Install New Software を選択。
  3. 無理だった。zipを選択しても,インストールできない。
  4. なので,別の方法を。zipファイルを解凍すると,.Appファイルがある。
  5. SetupSTM32CubeMX-4.24.0.app をダブルクリックする。
  6. インストールのWindowが開くので,デフォルトでインストール。
  7. アプリケーション->STMicroElectronicsにSTM32CubeMX.appがあることを確認。
  8. 終了!




== プロジェクトの作成 ==
デフォルトだと,AC6のワークスペースは,
Documents\workspace になるので,ここにプロジェクトを作成する。

まず,STM32CubeMXを起動する。
NewProjectを選択する。
Board Selectorタブをクリックして,Nucleo-L152RE を選択して,「StartProject」をクリック。

全てのペリフェラルをデフォルトで初期化するか聞かれるので,「Yes」を選択。

すると,こんな感じで,マイコンのピンを選択できる画面が出てくる。


Documents\workspace\NucleoL152RE_Blink フォルダを作って,NucleoL152RE_Blink.iocとして保存する。
次に,コードを生成する。
EclipseのプロジェクトをCubeMXから作成したいので,プロジェクト設定を行う。
Project->Setting を選択。


ProjectSettings ダイアログが開く。
Projectタブで,次のように設定する。
ProjectNameとProjectLocationを適当に設定して,「GenerateUnderRoot」のチェックを外す。


CodeGeneratorタブで,次のように設定する。
「Copy all used libraries into the project folder」と,
「Generate peripheral initialization as a pair of ・・・」にチェックを入れる。
(容量は食うかもしれんが,なんとなく,わかりやすくなりそうだから。)

で,OKを押す。
Project->Generate Code をクリックして,コードを生成する。
これで,AC6のプロジェクトファイルも同時に作ってくれる。
コード生成に成功!と言われる。「Open Project」を選択して,プロジェクトを開く。
すると,AC6が立ち上がり,作成されたプロジェクトを編集できる!
インポート成功!って言われたらOK!

workspaceの中を見てみると,以下のような感じになる。
作成されたプロジェクトの中にも,.iocファイルが作成されている。
もしかして,最初の保存はいらなかったかも。まぁいいや。
今後の課題と言うことで。

→ workspace->NucleoL152RE_Blink.ioc は消しても問題ない。
  CubeMXのコード生成で作成した,
  workspace->NucleoL152RE_Blink->NucleoL152RE_Blink.ioc
  を編集していけば良い。


== プログラム実行 ==

プロジェクトも作ったので,プログラムを実行する。
とはいえ,何も起きないけど。
前提として,NUCLEO L152RE をPCと接続しておくこと。

生成したプロジェクトを開いた状態がこんな感じ。
左のサイドバーのNucleoL152RE_Blinkプロジェクトを右クリック
->「Debug As」->「AC6 STM32 C/C+ Application」をクリック

なんかちょっとダイアログが出た末に,次のダイアログが登場。
デバッグ始めるよー的な?
とりあえず,「Yes」をクリック。

すると,AC6の画面が切り替わる。

ここまできたらOK!「Resume」ボタン,もしくは「F8」を押したら,プログラムが実行される!
したところでまだ何も起きないけど。



== Lチカプログラム作成 ==
まず,コード補完機能を使えるようにするため,
コード補完のショートカットを「Ctrl + Space」から変更する。
"https://qiita.com/rotomx/items/784211ea16760eecac83"
→ とりあえず,「Alt+Space」にした。

main.cを開いて,

int main(void) 関数内のwhile(1)の内部にLチカコードを記述する。
以下,コード

--------------------------------------------------------------------

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
    HAL_Delay(1000);
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
    HAL_Delay(1000);

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
  }

  /* USER CODE END 3 */

--------------------------------------------------------------------

トンカチ(🔨)みたいなボタンを押して,Buildする。
特にエラーが出なければ,デバッグする。
1回デバッグしているため,
左のサイドバーのNucleoL152RE_Blinkプロジェクトを右クリック
->「Debug As」->「AC6 STM32 C/C+ Application」をクリック
をしなくてもいい。
虫っぽいボタンを押して,デバッグを開始する。
画面が切り替わるので,Breakpointを貼ってみる。

HAL_GPIO_WritePin(・・・) と書いている行の左部分にカーソルを合わせて,
「Add Breakpoint」を選択する。



「Resume」ボタン,もしくは「F8」を押したら,プログラムが実行される。
Breakpointを貼ったところでプログラムが毎回止まる。
もう一度「Resume」ボタン,もしくは「F8」を押したら,プログラムが再開される。
1個目のBrekapointで止まった時は,LEDは消えている。
2個目のBreakpointで止まった時は,LEDはついている。
これは,Breakpointを貼った行のプログラムが実行される手前のところでプログラムが停止されるから。

Breakpointをなくしたら,ずっとLEDが点滅し続ける。
周期は1秒間隔!
Lチカ終了!
できた!

[参考]
http://happytech.jp/wordpress/2017/05/28/ide-for-stm32-mcu-sw4stm32/

[おまけ]
今回諦めたけど,EclipseにCubeMXのプラグイン入れる方法を昔載せてた。
http://chuchulabo.blogspot.jp/2017/05/stm32macos.html