__wrap__free_rが無いと言われたら

MbedのプロジェクトをGCC環境にエクスポートしてビルドすると、リンクの段階で下記のようなエラーが発生する場合があります。(どういう場合に発生するのか不明。)

undefined reference to `__wrap__free_r'
undefined reference to `__wrap__malloc_r'
undefined reference to `__wrap__calloc_r'
undefined reference to `__wrap__realloc_r'

この場合、リンカのオプションから対応する下記のものを削除すればエラーが解消します。

-Wl,--wrap=_free_r
-Wl,--wrap=_malloc_r
-Wl,--wrap=_calloc_r
-Wl,--wrap=_realloc_r

Eclipse系のIDE、例えばSW4STM32の場合、[Project] > [Properties] > [C/C++ Build] > [Settings] > [Tool Settings] > [MCU G++ Linker] > [Miscellaneous] の [Linker flags]で設定できる。

f:id:licheng:20200516204832p:plain

WindowsのIPアドレス設定画面どこ行った?

Windows10って、「コントロールパネル」と「設定」とが朝廷と幕府みたいに併存してるの、いいかげんなんとかならんのかな?

IPアドレスの設定画面の出しかたなど、Windows XP以来ころころ変更されてる気がする。Windows10 (1909)での出し方を以下にメモする。

たぶんいちばん速い出しかた

  1. Win+Xキー押す → 「ネットワーク接続」 (またはWキー押す)
  2. アダプターのオプションを変更する」(地球とモニタのアイコン)
  3. ネットワークアダプタを選んでプロパティを開く

他の出し方(1)

  1. スタートを右クリックして「設定」 (または左クリックして歯車のアイコン)
  2. ネットワークとインターネット」(地球のアイコン)
  3. アダプターのオプションを変更する」(地球とモニタのアイコン)
  4. ネットワークアダプタを選んでプロパティを開く

他の出し方(2)

  1. 「ここに入力して検索」に「コントロールパネル」と入力して開く
    またはスタートメニューから「Windowsシステムツール」→「コントロールパネル
  2. 大きいアイコンの表示で「ネットワークと共有センター
    またはカテゴリの表示で「ネットワークとインターネット」→「ネットワークと共有センター
  3. 「アダプタの設定の変更」(左上にある)
  4. ネットワークアダプタを選んでプロパティを開く

設定でもコントロールパネルでもけっきょく同じところに行くんじゃん…

PSoC CreatorでPDLが無いと言われたら

PSoC Creatorをアップデートした場合(?)に、下記のようなエラーが出ることがあります。

f:id:licheng:20200511100231p:plain

PDLとは「Peripheral Driver Library」で、PDL v2はFM0+やFM4に、PDL v3はPSoC6に対応しています。(PSoC4やPSoC5はそんなライブラリ要らないってこと?)

PDLは C:\Program Files (x86)\Cypress\PDL か C:\Users\ユーザ名\Documents\Cypress\PDL にインストールされています。もしもインストールされていなければ こちら からダウンロードしてインストールします。

PSoC Creatorのメニューの「Tools」→「Options」の「Project Management」で、PDLのパスを指定すればエラーは解消されます。

f:id:licheng:20200511103016p:plain

Androidアプリでのファイル読み書き

※ 今さらな内容のメモです。かなり古い内容を含んでいる可能性があります。

Androidアプリで設定データなどを保存するにはSharedPreferencesを用いるのがいちばん簡単である。
しかし、USB接続でデータファイルをPCとやりとりしたい場合もある。その場合、ファイルの読み書きは次のようにおこなう。

ディレクトリ作成

    // ストレージ直下に Hoge というディレクトリが無ければ作成
    String dirPath = Environment.getExternalStorageDirectory().getPath() + "/Hoge/";
    File dir = new File(dirPath);
    if(!dir.exists()){
        dir.mkdir();
    }

書き込み

    // Hoge/Piyo.txt というファイルに書き込み
    filePath = dirPath + "Piyo.txt";
    FileOutputStream fos = new FileOutputStream(filePath);
    OutputStreamWriter osw = new OutputStreamWriter(fos);
    BufferedWriter bw = new BufferedWriter(osw);
    
    bw.write("hogehogepiyopiyo");
    bw.newLine();

    bw.flush();
    bw.close();
    fos.getFD().sync(); // ストレージの同期
    fos.close();

読み出し

    // Hoge/Piyo.txt というファイルから読み出し
    filePath = dirPath + "Piyo.txt";
    FileInputStream fis = new FileInputStream (filePath);
    InputStreamReader isw = new InputStreamReader (fis);
    BufferedReader br = new BufferedReader(isr);

    String line = br.readLine();

    br.close();
    fis.close();

基板の銅箔厚の「oz」とは?

FusionPCBとかElecrowとかでプリント基板を作るとき、銅箔厚の指定で「oz」という見慣れない単位が出てきます。「oz」というのはオンスのことですが、ここではoz/ft2 (オンス/平方フィート) を意味します。つまり1平方フィートあたり何オンスの重さの銅箔かということです。(オンスだのフィートだのアメリカ人はいつまで中世の単位を使う気なのかという気がしますが。)

1オンス = 28.35g
1フィート = 30.34cm
1オンス/平方フィート = 0.0308g/cm2

銅の密度は 8.94g/cm3 なので

1オンス/平方フィートの銅箔の厚みは
0.0308g/cm2 ÷ 8.94g/cm3 ≒ 35μm

なので、1ozの銅箔は35μmの厚さということになります。

ちなみに、1ozの銅箔ではパターン幅1mmあたり許容電流1Aと昔から言われています。

4月のまとめ

進捗

所感

今月はSOEMのNucleo対応が難航したこと、入荷予定だったM5Stack用LANモジュールが未入荷でSOEMのM5Stack対応の作業が進められなかったことなどあり、停滞気味。体調を崩しがちだったこともブレーキになった。連休中に立て直して5月は勢いを取り戻したい。

UIスレッドで実行させる (雑な話)

UIスレッド(メインスレッド)以外のスレッドからUIを操作したいとき、Windows (.NET)でもAndroid (Java)でも直接操作することは許されない。そういうときはUIスレッドに処理を依頼する形を取る。WindowsならControl.Invoke()またはControl.BeginInvoke()、AndroidならHandler.post()を用いる。

…というのはまあ分かってるのだけども、ふだんC言語ばかり書いているので、たまにC#Javaを書くと書き方を忘れてしまうのである。

Windows (.NET)

  • スレッドは、関数(メソッド)をThreadStartデリゲートを通してThreadに渡し、Startする。
  • UIの操作は、ラムダ式をActionデリゲートにキャストしてInvokeする。
using System.Threading;

// フォームのクラス
public class FormHoge : Form
{
    // スレッド
    Thread threadHoge;
    
    // スレッド関数
    private void threadFunc()
    {
        // UIスレッドで実行させる
        this.Invoke((Action)(() => {
            // UIの操作
            textboxHoge.Text = "hoge";
        }));
    }
    
    // スレッド開始
    private void startThread()
    {
        threadHoge = new Thread(new ThreadStart(threadFunc));
        threadHoge.Start();
    }
}

Android (Java)

  • スレッドは、Runnableのrunを実装したものをThreadに渡し、startする。
  • UIの操作は、Runnableのrunを実装したものをハンドラにpostする。
import android.os.Handler;

// アクティビティのクラス
public class HogeActivity extends Activity {
    
    // スレッド
    private Thread mThread;
    // ハンドラ
    private Handler mHandler = new Handler();
    
    // スレッド
    class HogeThread implements Runnable{
        public void run() {
            
            // UIスレッドで実行させる
            mHandler.post(new Runnable() {
                public void run() {
                    // UIの操作
                    textviewHoge.setText("hoge");
                }
            });
        }
    }
    
    // スレッド開始
    private void startThread() {
        mThread = new Thread(new HogeThread());
        mThread.start();
    }
}

JavaでもJava8以降 (Androidでは APIレベル24以降)ではRunnableに代えてラムダ式が使えるらしい。