2015年08月31日

STM32F7 Discoveryを使ってみる のまとめ

STM32F7 Discoveryを使ってみる をまとめておきます。

STM32F7 Discoveryを使ってみる(1) ついに入手!  http://ewarmjp.seesaa.net/article/422926137.html
STM32F7 Discoveryを使ってみる(2) とりあえずつないでみる  http://ewarmjp.seesaa.net/article/422927119.html
STM32F7 Discoveryを使ってみる(3) STM32CubeF7を入手!  http://ewarmjp.seesaa.net/article/423226904.html
STM32F7 Discoveryを使ってみる(4) ADCサンプルを動かしてみる  http://ewarmjp.seesaa.net/article/423323727.html
STM32F7 Discoveryを使ってみる(5) ADCサンプルを動かしてみる 2  http://ewarmjp.seesaa.net/article/423372254.html
STM32F7 Discoveryを使ってみる(6) ADCサンプルを動かしてみる 3  http://ewarmjp.seesaa.net/article/423451321.html
STM32F7 Discoveryを使ってみる(7) ADCサンプルを動かしてみる 4  http://ewarmjp.seesaa.net/article/423451608.html
STM32F7 Discoveryを使ってみる(8) M7の性能評価  http://ewarmjp.seesaa.net/article/423547337.html
STM32F7 Discoveryを使ってみる(9) M7の性能評価2  http://ewarmjp.seesaa.net/article/423608967.html
STM32F7 Discoveryを使ってみる(10) M7の性能評価3  http://ewarmjp.seesaa.net/article/423665557.html
STM32F7 Discoveryを使ってみる(11) M7の性能評価4  http://ewarmjp.seesaa.net/article/423726713.html
STM32F7 Discoveryを使ってみる(12) M7の性能評価5  http://ewarmjp.seesaa.net/article/423799547.html
STM32F7 Discoveryを使ってみる(13) M7の性能評価6  http://ewarmjp.seesaa.net/article/423809897.html
STM32F7 Discoveryを使ってみる(14) M7の性能評価7  http://ewarmjp.seesaa.net/article/423885846.html
STM32F7 Discoveryを使ってみる(15) M7の性能評価8  http://ewarmjp.seesaa.net/article/423886347.html
STM32F7 Discoveryを使ってみる(16) M7の性能評価9  http://ewarmjp.seesaa.net/article/424032535.html
STM32F7 Discoveryを使ってみる(17) M7の性能評価10  http://ewarmjp.seesaa.net/article/424036696.html
STM32F7 Discoveryを使ってみる(18) M7の性能評価11  http://ewarmjp.seesaa.net/article/424037981.html
STM32F7 Discoveryを使ってみる(19) M7の性能評価12  http://ewarmjp.seesaa.net/article/424040512.html
STM32F7 Discoveryを使ってみる(20) M7の性能評価13  http://ewarmjp.seesaa.net/article/424041208.html
STM32F7 Discoveryを使ってみる(21) M7の性能評価14  http://ewarmjp.seesaa.net/article/424258721.html
STM32F7 Discoveryを使ってみる(22) STM32F4とF7を比較してみる  http://ewarmjp.seesaa.net/article/424259681.html
STM32F7 Discoveryを使ってみる(23) DSPを使ってみる1  http://ewarmjp.seesaa.net/article/424260869.html
STM32F7 Discoveryを使ってみる(24) DSPを使ってみる2  http://ewarmjp.seesaa.net/article/424262021.html
STM32F7 Discoveryを使ってみる(25) DSPを使ってみる3  http://ewarmjp.seesaa.net/article/424262417.html
STM32F7 Discoveryを使ってみる(26) DSPを使ってみる4  http://ewarmjp.seesaa.net/article/424263528.html
STM32F7 Discoveryを使ってみる(27) DSPを使ってみる5  http://ewarmjp.seesaa.net/article/424645588.html
STM32F7 Discoveryを使ってみる(28) DSPを使ってみる6  http://ewarmjp.seesaa.net/article/424646361.html
STM32F7 Discoveryを使ってみる(29) MPUをみてみる1  http://ewarmjp.seesaa.net/article/424647714.html
STM32F7 Discoveryを使ってみる(30) MPUをみてみる2  http://ewarmjp.seesaa.net/article/424659329.html
STM32F7 Discoveryを使ってみる(31) MPUをみてみる3  http://ewarmjp.seesaa.net/article/424660532.html
STM32F7 Discoveryを使ってみる(32) MPUをみてみる4  http://ewarmjp.seesaa.net/article/424661409.html
STM32F7 Discoveryを使ってみる(33) MPUをみてみる5  http://ewarmjp.seesaa.net/article/424661966.html
STM32F7 Discoveryを使ってみる(34) STM32CubeMXを使う  http://ewarmjp.seesaa.net/article/425026372.html
posted by EWRXJP at 12:00| Comment(0) | TrackBack(0) | まとめトップ | このブログの読者になる | 更新情報をチェックする

2015年08月30日

STM32F7 Discoveryを使ってみる(34) STM32CubeMXを使う

さて、ここまでSTM32CubeF7のサンプルやTutorialを見てきましたが、
ペリフェラルなどを使うときはSTM32CubeMXという設定ツールを使うと便利です。

Image 301.png
Downloadしてインストールします。


起動してNew Projectを選択
Image 302.png

MCU選択とBoard選択で、Board選択。
新規に基板を作るときはMCU選択を使うといいと思います。

Target BoardをDiscovery、MCUをF7を選択して
F7DISCOVERYボードを選択してOK。

Image 303.png


下記のような画面が出てきます。
F4のボードだとQFPだったので、今回はBGAということで
かなり賑やかなことに。
Image 304.png

左上がA1ピン
Image 305.png

右上がA15ピン
Image 306.png

右下がR15ピンです。
Image 307.png

設定したいピンはH/Wマニュアルで番号を見ておきましょう。


D14ピンを見てみます。PI1はユーザボタン横のLEDにつながっているので
GPIOに変更します。
Image 308.png
シングルクリックして、GPIO_Ouputに変更
Image 309.png
続けて右クリックして
Image 310.png
LED1に変更
Image 311.png

続けてコード生成の設定をします。
Image 312.png

プロジェクト名をつけて、保存先ディレクトリを設定してOK。
Image 313.png

Image 315.png

たぶん、STM32CubeF7のダウンロードが始まります。
結構時間かかるので、ただただ待ちます。

終わったらOpen Project
Image 316.png

こんなプロジェクトが生成されます。
Image 317.png

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration----------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DCMI_Init();
  MX_QUADSPI_Init();
  MX_SPDIFRX_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}


ユーザコードはBEGINとENDの間に書きます。

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */
  HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_1);
  }
  /* USER CODE END 3 */

HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_1);を
追加して、実行すると、通過する度に、GPIOがトグルします。
フリー実行だとDuty50%のPWM状態になりますが。


マイコンは初期設定が大変です。
STM32CubeMXを使うと、初期設定コードをはいてくれます。
ピン設定だけでなくて、クロック設定や、ペリフェラルの設定もしてくれます。

詳しくはCubeMXのヘルプを参照。

MXでは初期設定をしてくれるのですが、実際の動作コードは
CubeF7のサンプルを参照しながら、埋め込んでいきます。

  HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_1);
とか。

CubeF7で遊んで、MXで設定して、というのが良い流れかと。


posted by EWRXJP at 12:00| Comment(0) | TrackBack(0) | STマイクロ | このブログの読者になる | 更新情報をチェックする

2015年08月29日

STM32F7 Discoveryを使ってみる(33) MPUをみてみる5

ちょっと番外ですが、フォールトハンドラに入ったときの調査のしかたをみてみましょう。
まずは前回のように、System Control Blockレジスタの
xFSRレジスタで、怪しいビットが立っていないか確認します。

Image 245.png

要因のあたりをつけたらどこで発生したか見ます。
Cortex-Mは例外が発生したら、自動的に重要レジスタをスタックに積んでくれます。

スタックウィンドウを開きます。

Image 244.png

こんな感じで表示されています。
不具合調査で大事なのは直前のPCとLRです。
Image 246.png
ぱっと見でコードのアドレスっぽいのは0x0800156Bと0x20010134です。
逆アセンブリ画面にアドレスを打ち込んでEnterします。
0xを忘れずに。


Fibの次の関数であることがわかります。
0x0800156BはLRのようです。


0x20010134を打ってみます。
Fib関数の先頭にいきました。
直前のPCということになります。

MPUのフォールトだけでなく、汎用的に使えるテクニックです。

posted by EWRXJP at 12:00| Comment(0) | TrackBack(0) | STマイクロ | このブログの読者になる | 更新情報をチェックする

2015年08月28日

STM32F7 Discoveryを使ってみる(32) MPUをみてみる4

もう一つパラメータをみてみます。

XNビット、Execution Neverビットでコード実行を許すかのビットです。

PCやサーバの世界ではコードインジェクション攻撃を避けるために設定必須です。

今回SRAM上にコードは置いていないので、Fib関数を配置します。

関数名にセクションを指定
#pragma location="fib_code"
unsigned long Fib(int n)
{
    unsigned long f;

リンカ設定ファイル(icf)ファイルにRAM領域にfib_sectionを配置するよう指定

initialize by copy { readwrite,section fib_code };
do not initialize  { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region   { readonly };
place in RAM_region   { readwrite, section fib_code,
                        block CSTACK, block HEAP };


これでビルドするとFibが0x2001領域に配置されます。

DebugMon_Handler        0x08001ecd    0x2  Code  Gb  stm32f7xx_it.o [1]
Fib                     0x20010135   0x22  Code  Gb  main.o [1]
HAL_GetTick             0x080012cb    0x6  Code  Wk  stm32f7xx_hal.o [1]
HAL_IncTick             0x080012c1    0xa  Code  Wk  stm32f7xx_hal.o [1]


MPU設定を変えてみます。
  //MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

実行すると・・
Image 243.png
狙ったとおりですがメモリマネジメントフォールトに入りました。
CFSRのIACCVIOLがたっています。
命令アクセス違反ということがわかります。

通常は、FLASH領域を誰かに書き換えられる、ということはないので
RAM領域については、実行不許可を与えておくと、安全だと思います。


posted by EWRXJP at 12:00| Comment(0) | TrackBack(0) | STマイクロ | このブログの読者になる | 更新情報をチェックする

2015年08月27日

STM32F7 Discoveryを使ってみる(31) MPUをみてみる3

ここから実際にMPUのパラメータを変えて動作と性能を見ていきたいと思います。

Templateプロジェクトに設定されているのはSDRAM領域で、アクセス制限なく、キャッシュ有効でライトスルー設定になっています。

以前にみていたベンチマーク結果だと
237,195サイクルでした。

MPU設定をライトスルーからライトバックにしてみます。

  //MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 
結果は、
Image 241.png
236,018サイクル。

ほんの少しだけ早くなりましたね。
理論上は早くなるはずなので、少し安心。

今度はキャッシュ無効にしてみます。
//MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

Image 242.png
予想どおりですが、
530,903サイクル、と大幅に遅くなりました。

F7全体としてキャッシュを有効にしても個別ではキャッシュを無効にできる、ということですね。

posted by EWRXJP at 12:00| Comment(0) | TrackBack(0) | STマイクロ | このブログの読者になる | 更新情報をチェックする

2015年08月26日

STM32F7 Discoveryを使ってみる(30) MPUをみてみる2

MPUの説明はARM社のWebに公開されています。

下はM3用ですが、M4もM7も同じです。

ちなみにCortex-M以外のMPUはコプロで設定しなければいけないので、MCR、MRCを使いますが、
基本的に設定する内容は同じです。


Image 236.png

下の方はエイリアスレジスタとなっていて、いったん忘れて良いです。
Image 237.png

MCUの持つMPU機能を読み取るタイプレジスタと、MPU全体設定のMPU全体設定レジスタと、各領域ごとの属性レジスタがあります。
タイプはマイコンごとに固定なので一度読めば十分です。

制御レジスタは、通常は有効無効の切り替えだけ使います。

領域番号レジスタは、これから指定する領域の番号を指定するのですが、
他のレジスタで同じ機能を実現できるので、使いません。

ベースアドレスレジスタで、開始アドレスと、領域番号を指定します。

領域属性、サイズレジスタで、詳細設定をします。

Image 239.png
Image 240.png


SIZEはビットの組み合わせでサイズはもう決まっています。
こんな感じ。

b00100
32B
b0010164B
b00110128B
b00111256B
b01000512B
b010011KB
b010102KB

他の属性は少し面倒くさいです。
組み合わせで意味が変わったりします。


ARMのドキュメント見て、ある程度理解したらST社のコードの定義を使う方が良いです。

MPU_Configのソースを見てみます。

/**
  * @brief  Configure the MPU attributes as Write Through for SRAM1/2.
  * @note   The Base Address is 0x20010000 since this memory interface is the AXI.
  *         The Region Size is 256KB, it is related to SRAM1 and SRAM2  memory size.
  * @param  None
  * @retval None
  */
static void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct;
 
  /* Disable the MPU */
  HAL_MPU_Disable();
  /* Configure the MPU attributes as WT for SRAM */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x20010000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.SubRegionDisable = 0x00;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enable the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

構造体に設定をして、一気に反映させています。

  HAL_MPU_ConfigRegionの定義は以下。

void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
{
  /* Check the parameters */
  assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
  assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
  /* Set the Region number */
  MPU->RNR = MPU_Init->Number;
  if ((MPU_Init->Enable) != RESET)
  {
    /* Check the parameters */
    assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
    assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
    assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
    assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
    assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
    assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
    assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
    assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
   
    MPU->RBAR = MPU_Init->BaseAddress;
    MPU->RASR = ((uint32_t)MPU_Init->DisableExec             << MPU_RASR_XN_Pos)   |
                ((uint32_t)MPU_Init->AccessPermission        << MPU_RASR_AP_Pos)   |
                ((uint32_t)MPU_Init->TypeExtField            << MPU_RASR_TEX_Pos)  |
                ((uint32_t)MPU_Init->IsShareable             << MPU_RASR_S_Pos)    |
                ((uint32_t)MPU_Init->IsCacheable             << MPU_RASR_C_Pos)    |
                ((uint32_t)MPU_Init->IsBufferable            << MPU_RASR_B_Pos)    |
                ((uint32_t)MPU_Init->SubRegionDisable        << MPU_RASR_SRD_Pos)  |
                ((uint32_t)MPU_Init->Size                    << MPU_RASR_SIZE_Pos) |
                ((uint32_t)MPU_Init->Enable                  << MPU_RASR_ENABLE_Pos);
  }
  else
  {
    MPU->RBAR = 0x00;
    MPU->RASR = 0x00;
  }
}

assertを抜くとだいぶすっきりします。
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
{
  /* Set the Region number */
  MPU->RNR = MPU_Init->Number;
  if ((MPU_Init->Enable) != RESET)
  {
    MPU->RBAR = MPU_Init->BaseAddress;
    MPU->RASR = ((uint32_t)MPU_Init->DisableExec             << MPU_RASR_XN_Pos)   |
                ((uint32_t)MPU_Init->AccessPermission        << MPU_RASR_AP_Pos)   |
                ((uint32_t)MPU_Init->TypeExtField            << MPU_RASR_TEX_Pos)  |
                ((uint32_t)MPU_Init->IsShareable             << MPU_RASR_S_Pos)    |
                ((uint32_t)MPU_Init->IsCacheable             << MPU_RASR_C_Pos)    |
                ((uint32_t)MPU_Init->IsBufferable            << MPU_RASR_B_Pos)    |
                ((uint32_t)MPU_Init->SubRegionDisable        << MPU_RASR_SRD_Pos)  |
                ((uint32_t)MPU_Init->Size                    << MPU_RASR_SIZE_Pos) |
                ((uint32_t)MPU_Init->Enable                  << MPU_RASR_ENABLE_Pos);
  }
  else
  {
    MPU->RBAR = 0x00;
    MPU->RASR = 0x00;
  }
}

属性設定でいろいろなビットを立てていることがわかります。

こんな感じでシフト数がcore_cm7.hで宣言されています。

#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */

posted by EWRXJP at 12:00| Comment(0) | TrackBack(0) | STマイクロ | このブログの読者になる | 更新情報をチェックする