組み込み技術を向上したい!!

でも組み込み以外にも手を出し始めました・・・

NUCLEO-F303RE

NUCLEO-F303RE

少し、NUCLEO-F303REをいじってみたので、使用感をメモ。

回路図の準備

www.st.com

Schematic Packあたりから回路図をダウンロード。MB1136.pdfというのが回路図。

電源まわりの確認

気になったのがCPUが熱くなること。いろいろ電源ラインがあるので、いろんな供給方法をやってみたけど、改善しなかった。(基板不良??)

電源ラインが多すぎて、希望の動作をさせるにはどうすればいいかよくわからなかった。

消費電力を削減するため、ST-Link部分の電源供給を断ちたかっただけなのに・・・。

  • MB1136.pdfの1ページ目。
    VINはE5Vを生成する。JP5でE5VかU5Vが+5Vとなるように切り分けられる。+5Vから+3V3が生成されそれがJP5経由でVDDとなる。
  • MB1136.pdfの2ページ目。
    VDDはL1を経て(SB57あり)AVDDを生成する。VDDは当然MCUの電源。
  • MB1136.pdfの3ページ目。
    E5V, U5Vはそれぞれ+3V3_ST_LINKを生成できる。
  • 順番に見ていく。
    USBから給電した場合を考えてみる。USBからの給電はU5V。
    T2のSTS7PF30LはPchなので、S -> Dの電気の流れを制御するためにあるはず。 G がLOWならば動作する。
    ST-Link役のU2のIOからPWR_ENnというのが出ていて、こいつがT2の G に接続されている。
    U5V投入直後は G がU5Vでプルアップされているが、U5Vから+3V3_ST_LINKが生成されたら、
    G がLOWになって、システム(+5V, +3V3)に電源を供給するという流れのようだ。
    特に違和感はない。
    E5VもU5Vも+3V3_ST_LINKにつながってしまうので、E5V、U5Vから電源供給すると目的の「ST-Link部分の電源供給を断つ」ということはできそうにない。
    基板を知人プレゼントしてしまったので、今となっては確認できないが、JP5を両方オープンにして+5Vに直接5V入れればよかったのかな?

 

mbed-rtos

以前↓でやったとき

sunnydays-k.hatenablog.com

よりじっくりmbed-rtosを使えたのは勉強になった。

RTOS - Handbook | mbed

から情報は得られる。
rtos対応しているデバイスかどうかはCortex Mの場合はフォルダ階層でmbed-rtos⇒rtx⇒TARGET_CORTEX_M⇒RTX_Conf_CM.cの中に目的のデバイス名が定義してあるかを確認すればわかる。

まずはTaskといえばいいのかThreadといえばいいのかわからんが、OS管理させたい関数を作る。
その後、main関数でThreadとして作ってあげればOK。どうやらmain関数自体もThreadとなってるらしい。I'm poor at English!!
Priorityの設定も可能。Thread生成後に変えたい場合は.set_priority()で変えればいい。
QueueやMailを使わず、グローバル変数でやりとりしても今回は問題が起きなかった。簡単に使える??

以下参考プログラム

#include "mbed.h"
#include "rtos.h" // rtos.hをインクルードするのを忘れずに
 
// IO定義などはまとめて書くと便利なこともある
DigitalOut IOs[2] = {
    DigitalOut(PA_10), DigitalOut(PB_3)
};

volatile int gState = 0; // グローバル変数を共有しても今回の実験でシリアスな問題は起きなかった。
// PA_10のトグル
void TaskIoToggle0(void const *args) {
    while (true) {
        if ( gState == 0 ) {
            IOs[0] = !IOs[0];
        }
        Thread::wait(100); // 100とすると、このループは100ms毎の処理となる。
    }
}
// PB_3のトグル
void TaskIoToggle1(void const *args) {
    while (true) {
        if ( gState == 0 ) {
            IOs[1] = !IOs[1];
        }
        Thread::wait(300); // 300とすると、このループは300ms毎の処理となる。
    }
}
 
int main() {
    // 優先度を設定することにより、task_io_toggle0の方が優先される
    Thread task_io_toggle0(TaskIoToggle0, (void*)"tog0", osPriorityHigh);
    Thread task_io_toggle1(TaskIoToggle1, (void*)"tog1", osPriorityNormal);

    // このループにより、1000ms毎にIO操作するかしないか切り替わる
    while (true) {
        Thread::wait(1000);
        if ( gState == 0 ) {
            gState = 1;
        }
        else {
            gState = 0;
        }    
    }
}