前回の原稿の後で、STM32F105/7用のProjectを改変してSTM32F4-Discovery向けに変更しようと色々と作業をしてみたのだが、たとえばUSB Driverに含まれるusb_core.cは内部でcore_cm3.hを参照しており、これをcore_cm4.hに差し替えただけではうまくいかない(色々シンボルが異なっているため、結局関連モジュールを全部入れ替える必要がある)。いっそ既存のSTM32F4-Disocvery用のProjectに、新規にVCP関連モジュールだけを追加する方が早い、という結論に達した。

というわけで、IAR Embedded Workbenchで新規Projectを作って...と思ったのだが、実はこれが意外に大変だった。というのは、新規にSTM32F4用にProjectを作っても、必要になる関連モジュールを自動で追加してくれたりしないからで、これを手で追加してやる必要がある(何でもATOMIC TrueStudioではこのあたりがちゃんと対応されていて、デバイスを選ぶと関連モジュールが自動で追加されるらしい。もっともこれが便利かどうかは一概に言えないのだが)。ということで、既存のSTM32F4-Discovery用のProjectに手を入れて必要なモジュールを追加することにした。

で、ここから入手できる"STM32F4DISCOVERY board firmware package"を眺めていると、丁度おあつらえ向きにDemonstrationというプロジェクトが存在する。これを改変して色々組み込んでみることにした。

さて、まずはファイルの追加である。とりあえずfirmware packageを別の名前でまるごとコピーし、その下の要らないファイル(とりあえず筆者の場合Keil MDK-ARM/TASKING/TrueStudioの3つは不要なので全部削除した。その他のファイルは、後で不要なことが確定してから消せばいいので、当面残しておいた)を削除した上で、IAR Embedded Workbenchを2つ立ち上げ、片方では今コピーしたフォルダの\Project\Demonstration\EWARMにあるSTM32F4-Discovery_Demo.ewwを(Photo01)、もう片方ではSTM32F207VG用のVC PFirmwareのProjectを開き(Photo02)、両者を並べて比較したところ、ことファイルに関しては、

  • ProjectからUSB DeviceのHID Classを抜く。
  • ProjectにUSB DeviceのCDC Classをグループとして追加し、ここにusbd_cdc_core.cを追加する。

だけをやれば概ね一緒になることが判った。USB Driverそのものについては、USB_OTG_Driverのままで行けそう(というか、他にUSB Driverは含まれていないし、そもそもOTGという事はHostとDeviceの両方の動作モードを持っているわけなので、ここでDevice側を使えばすむ)ということになる。VCP関連で何かファイルをSTM32F207VG側からコピーする必要があるか? と思ったが、VCPに関係するusbd_cdc_core.cそのものは、STM32F4-Discovery用のファームウェアに含まれていたものと完全に一緒であった。

Photo01: クラス一覧。USB_Device_LibraryにはHID Classのみが含まれていた。

Photo02: こちらだと、USB Device Classの下にはCDC Classのみが含まれ、usbd_cdc_core.cが入っていた。

ちなみにファイル追加の手順だが、

(1) STM32_USB_Deveice_Library\Classから右クリックでコンテクストメニューを出し、ここで「グループの追加」を選び"CDC"と入力(Photo03)。
(2) 追加した"CDC" classをやはり右クリックし、「ファイルの追加」を選ぶ(Photo04)。
(3) "Libraries\STM32_USB_Device_Library\Class\cdc\src"の下にあるusbd_cdc_core.cを選択(Photo05)。

となる。

Photo03: もっともグループに関しては、これは理解とか管理に便利という話であって、別のグループにいきなりusbd_cdc_core.cを突っ込んでも問題はなさそう。

Photo04: この時点ではまだHID Classが残っているのがお分かりだろうか? この後でHID Classを削除した。

Photo05: 今回はusbd_cdc_if_template.cの方は使わない。

で、この状況でいきなりMakeを掛けるとどうなるか? というと、こんな感じ(Photo06)になる。これの対処にはInclude Pathを通す必要がある。そこでPhoto04のようにProject全体のプロパティを選択し、"C/C++コンパイラ"カテゴリの"プリプロセッサ"タブの中で、Includeの設定を変更する(Photo07)。ただ最初は書き換えたら、今度はHID系のものがコンパイルエラーで引っかかるようになってしまったので(Photo08)、最終的にはHID classとCDC Classの両方にPathを通した。

Photo06: 要するにusbd_cdc_core.hのおかれている場所にInclude Pathが通ってない。

Photo07: ここは本来、HID class用のPath($PROJ_DIR$\..\..\..\..\Libraries\STM32_USB_Device_Library\Class\hid\inc)だったものを書き換え、cdcのinclude directoryにPathを通している。

Photo08: 最終的にはHID関連は全部抜く予定だが、今回は順を追って変更してゆかないと訳がわからなくなるので、とりあえずHIDは残したままである。

Photo09: こんな具合にhid\incとcdc\incの両方にPathを通す。

さて、この状態でMakeを掛けた結果がこちら(Photo10)。usbc_cdc_core.cそのものはSTから提供されたコアライブラリだから、これが動かないのは何か釈然としない。これらのシンボルはSTM32F207VGでも普通に使われていて、こちらはちゃんとコンパイルが通る。

Photo10: いくつかのシンボルが未定義扱い。

色々調べた結果、Demonstrationディレクトリの直下にあるusbd_conf.hの定義が異なっている事が判った。オリジナルのusbd_conf.hはList 1の様になっており、本来入るべき定義がだいぶ抜けていた。で、色々検索してみると、STM32F4でVCPを動かすためのusbd_conf.hは別途書き換えが必要という事が判った。List 2が修正後のusbd_conf.hである。これがどこから来たのか、という話は次回するとして、こう修正するとリンクはともかくコンパイルは通るようになった(Photo11)。

Photo11: USBD_HD_SendReportが未定義な他、そもそもVCP周りのプログラムを呼び出してないからリンクが通らないのは当然。

List 1:

/**
  ******************************************************************************
  * @file    usbd_conf.h
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    19-September-2011
  * @brief   USB Device configuration file
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * 

© COPYRIGHT 2011 STMicroelectronics

****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USBD_CONF__H__ #define __USBD_CONF__H__ /* Includes ------------------------------------------------------------------*/ #include "stm32f4_discovery.h" /** @defgroup USB_CONF_Exported_Defines * @{ */ #define USBD_CFG_MAX_NUM 1 #define USBD_ITF_MAX_NUM 1 #define USB_MAX_STR_DESC_SIZ 64 #define USBD_DYNAMIC_DESCRIPTOR_CHANGE_ENABLED /** @defgroup USB_String_Descriptors * @{ */ /** @defgroup USB_HID_Class_Layer_Parameter * @{ */ #define HID_IN_EP 0x81 #define HID_OUT_EP 0x01 #define HID_IN_PACKET 4 #define HID_OUT_PACKET 4 /** * @} */ /** @defgroup USB_CONF_Exported_Types * @{ */ /** * @} */ /** @defgroup USB_CONF_Exported_Macros * @{ */ /** * @} */ /** @defgroup USB_CONF_Exported_Variables * @{ */ /** * @} */ /** @defgroup USB_CONF_Exported_FunctionsPrototype * @{ */ /** * @} */ #endif //__USBD_CONF__H__ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

List 2:

/**
  ******************************************************************************
  * @file    usbd_conf.h
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    19-September-2011
  * @brief   USB Device configuration file
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * 

© COPYRIGHT 2011 STMicroelectronics

****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USBD_CONF__H__ #define __USBD_CONF__H__ /* Includes ------------------------------------------------------------------*/ #include "stm32f4_discovery.h" /** @defgroup USB_CONF_Exported_Defines * @{ */ #define USBD_CFG_MAX_NUM 1 #define USBD_ITF_MAX_NUM 1 #define USB_MAX_STR_DESC_SIZ 64 #define USBD_DYNAMIC_DESCRIPTOR_CHANGE_ENABLED /** @defgroup USB_VCP_Class_Layer_Parameter * @{ */ #define CDC_IN_EP 0x81 /* EP1 for data IN */ #define CDC_OUT_EP 0x01 /* EP1 for data OUT */ #define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ #ifdef USE_USB_OTG_HS #define CDC_DATA_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ #define CDC_IN_FRAME_INTERVAL 40 /* Number of micro-frames between IN transfers */ #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL*8 */ #else #define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ #define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */ #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */ #endif /* USE_USB_OTG_HS */ #define APP_FOPS VCP_fops /** @defgroup USB_String_Descriptors * @{ */ /** @defgroup USB_HID_Class_Layer_Parameter * @{ */ #define HID_IN_EP 0x81 #define HID_OUT_EP 0x01 #define HID_IN_PACKET 4 #define HID_OUT_PACKET 4 /** * @} */ /** @defgroup USB_CONF_Exported_Types * @{ */ /** * @} */ /** @defgroup USB_CONF_Exported_Macros * @{ */ /** * @} */ /** @defgroup USB_CONF_Exported_Variables * @{ */ /** * @} */ /** @defgroup USB_CONF_Exported_FunctionsPrototype * @{ */ /** * @} */ #endif //__USBD_CONF__H__ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/