2017年12月27日

STM32CubeProgrammer


STM32マイコンの書き込みソフトというと
STM32 ST-Link Utilityですが、
先日、STM32CubeProgrammerが発表されました。


従来の差としては
マルチOS対応と
ST-Linkだけでなく、
UartやUSBを介した書込みも
統合して同じソフトで出来るようになった点です。

早速使ってみました。
インストール時にSTM32TrustedPackageCreatorは
通常使用では使用しないため、インストールしませんでした。



stm32cubeprg1.jpg

起動後の画面はCubeMX風です。

stm32cubeprg2.jpg

右上でST-Linkが選択されていることを確認します。
UartやUSBを使用する場合はそれぞれ応じたインタフェースを選択します。

stm32cubeprg3.jpg

ConnectをクリックするとデバイスとST-Linkが接続されます。

stm32cubeprg4.jpg

左の書き込みモードボタンを選択して、
Browseから書き込みたいbinファイル等を選択します。

stm32cubeprg5.jpg

右下のStartProgrammingをクリックすると書込みが開始されます。

イレース、書込みなどの度に画面にメッセージが
表示されるため、少し煩雑です。
正直メッセージは毎回でなくてもいいです。
どこかで止められればいいのですが。

UartやUSBなど含めて書込みインタフェースが統合されたのは歓迎ですが、
現時点では使い勝手はST-Link Utilityの方が使いやすいと思いました。

バージョンアップによる使い勝手の向上に期待です。


posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2017年12月02日

ADC微小電圧読込

今回はSTM32F103のAD変換を使用した際に
ちょっとした問題に遭遇したため紹介します。


TI製電流検知センサINA181A1の出力を
STM32F103のADCで読み込む際に
意図した電圧が読み込めてないことが分かりました。


シャント抵抗に10mΩを接続し、
0.3Aの電流を流しているので
60mVの出力が出ます。
※INA181A1はゲイン20倍

60mVの出力が出ていることは確認できましたが、
ADCで読み込むと6mVしか読み込めていない状況でした。


調査するとTI製電流検知センサINA181A1は全く問題がなく、
STM32F103のADCの初期化に問題があることが分かりました。


HAL_ADCEx_Calibration_Start
というADCのキャリブレーションを初期化時に実行すると
意図した60mVの出力を読み取ることができました。



可変抵抗などでざっくりとした値をAD変換で読み込む場合は
ADCのキャリブレーションをしなくとも問題ありませんが、
電流検知センサなどの微小な電圧を読み込む際には
ADCのキャリブレーションが必須です。


//ADの初期化
MX_ADC1_Init(); 

//ADのキャリブレーション
if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK) 
  {
    /* Calibration Error */
    Error_Handler();
  }


思った以上に微小電圧の読み込む場合は誤差が出るので、
面倒でもADCのキャリブレーションは初期化時に行った方が良さそうです。





ラベル:部品 STM32 HAL
posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2017年09月24日

ソフトリセット

今回はSTM32マイコンでソフトリセットの使用方法について紹介します。


I2Cのデバイスが検出できない場合や何かしらの異常が発生した場合に
電源投入時の状態に初期化したい場合があります。

その場合に便利な機能がソフトリセットです。



使用するSTM32マイコンのコアに応じて、
ヘッダが異なります。

CortexM0の場合は#include "core_cm0.h"
CortexM3の場合は#include "core_cm3.h"
CortexM4の場合は#include "core_cm4.h"
必要に応じて、変更します。

ソフトリセットを行う関数は
NVIC_SystemReset();
です。

何かしらの異常が発生した後に
上記の関数を入れておくと、
ソフトリセットが掛かります。

異常が連続して起きた場合に変な挙動にならないように
ソフトリセットの使い方には要注意ですが、
比較的簡単に実装できました。

続きを読む
posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2017年09月15日

BOOT0切替なし書き換え

今回はSTM32マイコンでBOOT0切替なしで
書き換えを行う方法を紹介します。

CubeMXでNucleo等を選択すると
BOOT0切替なしでファームの書き換えができます。

一方で、マイコン単体を選択して
最低限の設定でCubeMXで生成したコードを一度書き込むと、
次回の書き換え等でBOOT0をHighにして電源を入れないと
SWD端子に接続したSTLinkからマイコンが認識されず、
ファームの書き込みや削除ができない現象が発生しました。


原因としてはシリアルデバッグを有効化せずにCubeMXで生成したコードを書き込むと、
シリアルが無効化されてプログラムが動いてしまうことです。
書き換える場合はBoot0をHighにして電源を入れて
bootをシステムメモリに変更することで書き換えできます。

意図しない書き換え防止やセキュリティ強化になりますが、
Boot0のジャンパやスイッチの切り替えが面倒です。


ここで、BOOT0切替なしで書き換えを行う方法を紹介します。
CubeMXの設定でシリアルデバッグを有効化します。

serial-debug.jpg


この状態で生成したファームを書き込むと次回以降の書き換えは
BOOT0切替なしで書き換えできます。


製品としてファームを書き込む以外の実験用途では
意図しない書き換え防止やセキュリティ強化が不要なため、
CubeMXの設定でシリアルデバッグを有効化するのが
Boot0切替の手間がなく便利です。



posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2017年04月13日

FreeRTOS TICK RATE 調査

今回はSTM32 CubeMXで自動生成できる
FreeRTOSについて紹介させて頂きます。

CubeMXでFreeRTOSにチェックを入れるだけで
簡単にFreeRTOSを導入することが可能です。

ロボット制御やモータ制御を専門としていると
リアルタイム性や高速制御周期が制御性能や制御安定性に
効いてくるため気になるポイントです。


今回は将来的に加速度制御系にFreeRTOSを導入する場合を考え、
標準のFreeRTOSのconfigTICK_RATE_HZをデフォルト1000から
10000~60000まで変更してリアルタイム性やスレッドが動作するかテストしてみました。

FreeRTOSはconfigTICK_RATE_HZをデフォルト1000となっていますが、
この場合、最小スレッド切替が1msとなってしまいます。
加速度制御系や電流制御系を構築する場合、
20us~200us程度の最小スレッド切替が欲しいところです。



環境は
・STM32F303K8
 +SW4STM32(System Workbench for STM32)
 +STM32CubeMX(HAL ライブラリ、F3 ver. 1.7.0)
です。


CubeMXの設定は下記の通りです。
MPU周波数は内臓RCで最大周波数の64MHzに設定しました。
ポイントはデフォルトでは無効のosDelayUntil関数を有効化する点です。

rtos-setting1.png

rtos-setting2.png



作成するスレッドは3つ。

void StartDefaultTask(void const * argument)
{
  uint32_t PreviousWakeTime = osKernelSysTick();
  for(;;)
  {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
      osDelayUntil (&PreviousWakeTime, 1);
  }
}

void StartTask02(void const * argument)
{
   uint32_t PreviousWakeTime = osKernelSysTick();
  for(;;)
  {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);
    osDelayUntil (&PreviousWakeTime, 1);
  }
 }

void StartTask03(void const * argument)
{
   uint32_t PreviousWakeTime = osKernelSysTick();
  for(;;)
  {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
      osDelayUntil (&PreviousWakeTime, 1);
  }
}

スレッドはそれぞれGPIOのトグルを実行し、
トグル実行時間含めて1tick分まで待機します。


スレッドの生成は3段階の優先度で設定しました。
スレッド1つor 2つの場合は2つ目、3つ目のスレッドをコメントアウトして
スレッドを減らして実行しました。

 /* definition and creation of myTask01 */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityRealtime, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of myTask02 */
  osThreadDef(myTask02, StartTask02, osPriorityHigh, 0, 128);
  myTask02Handle = osThreadCreate(osThread(myTask02), NULL);

  /* definition and creation of myTask03 */
  osThreadDef(myTask03, StartTask03, osPriorityAboveNormal, 0, 128);
  myTask03Handle = osThreadCreate(osThread(myTask03), NULL);




最小スレッド切替の定義は
FreeRTOSConfig.h内の
#define configTICK_RATE_HZ                       ((TickType_t)1000*10)
を変更して実験しました。



◆結果
結果一覧は下記の通り

configTICK_RATE  周期       スレッド1つ   スレッド2つ   スレッド3つ
10000           100us       ○           ○        ○
20000           50us        ○           ○        ○
30000           33us        ○           ○        ×
40000           25us        ○           △       ×
50000           20us        △           ×        ×
60000           17us        ×           ×        ×

○:スレッド通りの動作、△:ジッターが多く、時々スレッド通り動作していない
×:スレッド通り動作していない、他のスレッドが全く動作していない


◆スレッド1つ
スレッド1つの場合、configTICK_RATE_HZ 50000 が限界ラインのようです。
configTICK_RATE_HZ 60000 にすると
下記のように周期が一定でなく、非常にジッターが多い感じです。


1ch60t.png



◆スレッド2つ
スレッド2つの場合、configTICK_RATE_HZ 30000 が限界ラインのようです。
configTICK_RATE_HZ 40000 にすると
下記のようにスレッド1は周期一定ですが、
スレッド2の周期が一定でなく、非常にジッターが多い感じです。


2ch40t.png

更に周期を高く設定して、
configTICK_RATE_HZ 50000 にすると
下記のようにスレッド1は周期一定ですが、
スレッド2が全く動作していません。


2ch50t.png


◆スレッド3つ
スレッド3つの場合、configTICK_RATE_HZ 20000 が限界ラインのようです。
configTICK_RATE_HZ 30000 にすると
下記のようにスレッド1、スレッド2は周期一定ですが、
スレッド3は全く動作していません。

3ch30t.png


更に周期を高く設定して、
configTICK_RATE_HZ 40000 にすると
下記のようにスレッド1は周期一定ですが、
スレッド2の周期が安定せず、
スレッド3は全く動作していません。
3ch40t.png



◆スレッド切替時間
スレッド数2や3の場合は11us程度のようです。
厳密には同時にスレッドスタートできないため、
スレッド切替時間というよりも
スタート時の処理時間の差といった方が正しいかもしれません。

taskswitch.png



◆まとめ

スレッド1つ:25us周期、configTICK_RATE_HZ 40000が限界ライン
スレッド2つ:33us周期、configTICK_RATE_HZ 30000が限界ライン
スレッド3つ:50us周期、configTICK_RATE_HZ 20000が限界ライン
という感じです。
スレッド切替時間は11us程度。

ただ、今回のスレッド内のタスクはLEDトグルの最小限の処理のため、
実際に数値計算の処理やAD変換等の処理が入ると
もう少し限界ラインが変わってくると思います。


理想的な加速度制御系を構築するためには
電流制御周期20us程度が理想で
加速制御周期100us程度となると
スレッド2つでFreeRTOS+F3だとちょっと厳しいかなと思いました。

ということで理想的な加速度制御系を実現するには
MPU周波数が高いF4、F7、H7 を使ってみるか
今まで通り、RTOSなしでタイマ処理で分けるのが良さそうです...

続きを読む
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする