CMSIS: Cortex Microcontroller Software Interface Standard

出典: Wikimura

目次

About

ARMはCMSISレイヤの一部として、あらゆるコンパイラで利用できる以下のソフトウェアレイヤを提供する。

Core Peripheral Access Layer
名前定義、アドレス定義、コアレジスタやペリフェラルへアクセスするヘルパ関数を含む。また、デバッグチャネル定義を含む、デバイスに依存しないRTOSカーネル用インターフェースも定義されている。
Middleware Access Layer
ペリフェラルへの共通のアクセス手段を手供する。Middleware Access Layerはシリコンベンダによってデバイス固有のペリフェラルに適応され、ミドルウェアコンポーネントから利用される。

Middleware Access Layerは現在開発中で、この文書では紹介しない。

以下のソフトウェアレイヤはシリコンパートナ(ARMコアの製品を製造しているところ)によって拡張される。

Device Peripheral Access Layer
全てのペリフェラル定義を提供する
Access Functions for Peripherals(optional)
ペリフェラルの追加的なヘルパ関数を提供する

CMSISはCortex-Mxマイクロコントローラシステムを定義する:

  • ペリフェラルレジスタへの共通のアクセス方法と、共通の例外ベクトルの定義方法
  • Core Peripheralの名前とCore Exception Vectorの名前
  • デバッグチャネルを含む、デバイス非依存のRTOSカーネルインターフェース
  • ミドルウェアコンポーネント(TCP/IPスタック、Flash File System等)へのインターフェース

CMSIS準拠のソフトウェアコンポーネントを使用することで、ユーザはテンプレートコードを再利用しやすくなる。CMSISは複数のミドルウェアベンダから提供されるソフトウェアコンポーネントを組み合わせることを可能にすることを意図している。

コーディング規則・命名規則

以降の節では、CMSIS実装におけるコーディング規則と命名規則について示す。 また、データ型やバージョン情報に関する情報も含む。

要件

  • CMSIS CコードはMISRA 2004ルールに則っている。MISRAに違反する場合については、PC-LINT(C言語ソース整形ツール)用disable/enableシーケンスが挿入されている。
  • ANSI Cヘッダファイル<stdint.h>で定義されたANSI標準データ型を使用。
  • #defineで定義される定数は全て括弧で括られている。
  • 変数、パラメータは完全データ型を持つ(単にデータ型を持つと考えてOK?)
  • Code Peripheral Access Layerの関数は全てリエントラント(re-entrant:再入可能)
  • Core Peripheral Access Layer)はノンブロッキングコード(waitやqueryループは、他のソフトウェアレイヤ...Middleware Access Layerなどによってなされる)
  • 各例外、割り込みは以下のように定義される:
    • 例外ハンドラの接尾辞は_Handler、割り込みハンドラの接尾辞は_IRQHandlerとなっている。
    • デフォルトの例外/割り込みハンドラ(weak定義:同名の定義があればそちらを使う、弱い定義)は、無限ループを含む
    • 割り込み番号の#defineは、接尾辞が_IRQnとなっている。

推奨

CMSISは識別子の命名規則として以下を推奨する:

  • CAPITAL名はコアレジスタ、ペリフェラルレジスタ、CPUの命令を表す
  • CamelCase名はペリフェラルアクセス関数、割り込みを表す
  • PERIPHERAL_接頭辞は、特定のペリフェラルに属する関数を表す
  • Doxygenコメントは全ての関数でFunction Commentsに含まれる

コメント

TBD.

データ型とIO型修飾子

Cortex-Mx HALは標準ANSI Cヘッダファイル<stdint.h>で定義される標準的な型を使用している。 IO Type Qualifierは、ペリフェラル変数へのアクセスを指定する。 IO Type Qualifierは、ペリフェラルレジスタのデバッグ情報を自動的に生成することを意図している。

IO Type Qualifier #define 説明
__I volatile const Read access only
__O volatile Write access only
__IO volatile Read and write access

CMSIS バージョン番号

core_cm3.hはCMSISバージョン番号を以下のように定義する。

#define __CM3_CMSIS_VERSION_MAIN  (0x00)      /* [31:16] main version       */
#define __CM3_CMSIS_VERSION_SUB   (0x03)      /* [15:0]  sub version        */
#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB)

core_cm0.hはCMSISバージョン番号を以下のように定義する。

#define __CM0_CMSIS_VERSION_MAIN  (0x00)      /* [31:16] main version       */
#define __CM0_CMSIS_VERSION_SUB   (0x00)      /* [15:0]  sub version        */
#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB)

CMSIS Cortex Core

core_cm3.hはCMSIS Cortex-Mxのタイプ(Cortex-M3だから3?)を以下のように定義する。

#define __CORTEX_M                (0x03)

core_cm0.hはCMSIS Cortex-Mxのタイプを以下のように定義する。

#define __CORTEX_M                (0x00)

CMSISファイル

この節では、Cortex-Mxハードウェアおよびペリフェラルへアクセスするために提供されたCMSISファイルについて説明する。

ファイル 提供者 説明
device.h デバイス固有(シリコンパートナ提供) 実デバイスのペリフェラルを定義する。このファイルは、ペリフェラルを定義する他のインクルードファイルを使用する場合がある。
core_cm0.h ARM( RealView ARMCC, IAR, GNU GCC用) Cortex-M0 CPU用core peripheral定義
core_cm3.h ARM( RealView ARMCC, IAR, GNU GCC用) Cortex-M3 CPU用core peripheral定義
core_cm0.c ARM( RealView ARMCC, IAR, GNU GCC用) Core registerへアクセスするヘルパ関数を提供する
core_cm3.c ARM( RealView ARMCC, IAR, GNU GCC用) Core registerへアクセスするヘルパ関数を提供する
startup_device ARM(コンパイラ/シリコンパートナによって適応される) Cortex_Mxスタートアップコード、デバイス固有の割り込みベクタテーブル
system_device ARM(コンパイラ/シリコンパートナによって適応される) デバイス固有の設定ファイル。デバイス初期化(オシレータ設定など)を行う。

device.h

device.hは、シリコンベンダによって提供され、アプリケーションプログラマがCソースコードからインクルードする中心となるインクルードファイル(central include file)。これは以下を含む:

割り込み番号定義
全てのデバイス固有例外、割り込みに対する割り込み番号(IRQn)を提供する。
core_cm0.h/core_cm3.hの設定
実際の設定?を実デバイスへ反映する。core_cm0.h/core_cm3.hでは、プロセッサのレジスタやコアペリフェラルへのアクセス手段を実装している。
Device Peripheral Access Layer
全てのペリフェラル定義を提供する。デバイス固有のペリフェラルに対するデータ構造とアドレスマップを提供する。
Access Functions for Peripherals(optional)
ペリフェラルを操作するのに有用な追加的なヘルパ関数を提供する。アクセス関数はインライン関数か、シリコンベンダが提供する他のライブラリへの外部参照として提供される。

割り込み番号定義

デバイス固有の割り込みにアクセスするために、device.hはIRQnを以下のようなenumで定義する。

typedef enum IRQn
{
/******  Cortex-M3 Processor Exceptions/Interrupt Numbers ************************************************/
  NonMaskableInt_IRQn             = -14,      /*!< 2 Non Maskable Interrupt                              */
  MemoryManagement_IRQn           = -12,      /*!< 4 Cortex-M3 Memory Management Interrupt               */
  BusFault_IRQn                   = -11,      /*!< 5 Cortex-M3 Bus Fault Interrupt                       */
  UsageFault_IRQn                 = -10,      /*!< 6 Cortex-M3 Usage Fault Interrupt                     */
  SVCall_IRQn                     = -5,       /*!< 11 Cortex-M3 SV Call Interrupt                        */
  DebugMonitor_IRQn               = -4,       /*!< 12 Cortex-M3 Debug Monitor Interrupt                  */
  PendSV_IRQn                     = -2,       /*!< 14 Cortex-M3 Pend SV Interrupt                        */
  SysTick_IRQn                    = -1,       /*!< 15 Cortex-M3 System Tick Interrupt                    */
/******  STM32 specific Interrupt Numbers ****************************************************************/
  WWDG_STM_IRQn                   = 0,        /*!< Window WatchDog Interrupt                             */
  PVD_STM_IRQn                    = 1,        /*!< PVD through EXTI Line detection Interrupt             */
  :
  :
  } IRQn_Type;

core_cm0.h/core_cm0.cの設定

Cortex-Mxコア設定のオプションは、デバイス実装ごとに定義されている。いくつかの設定は、以下の#defineによって反映される。

コアペリフェラルファイルにアクセスするために、device.hcore_cm0.h/core_cm3.hをインクルードする。 core_cm0.h/core_cm3.hのいくつかの機能は、これらのファイルがインクルードされる前に設定されなくてはならない。

#define File Value Description
__NVIC_PRIO_BITS core_cm0.h (2) NVICで実装されている割り込み優先度ビット数(デバイス固有)
__NVIC_PRIO_BITS core_cm3.h (2 ... 8) NVICで実装されている割り込み優先度ビット数(デバイス固有)
__MPU_PRESENT || core_cm0.h, core_cm3.h || (0, 1) || MPUが存在するかどうかを定義(?) __Vendor_SysTickConfig || core_cm0.h, core_cm3.h || (1) || これが1にセットされると、core_cm3.hSysTickConfig関数が除外される。この場合、device.hでベンダ固有のSysTickConfig実装を含まなくてはならない。

Device Peripheral Access Layer

PERIPHERAL_接頭辞により、各ペリフェラルにアクセスするためのペリフェラルレジスタや関数を表す。 同じペリフェラルが一つ以上ある場合、識別子は接尾辞(?)として数字や文字をもつ。

  • UART_Type: デバイスのもつUARTの一般化されたレジスタ配置を定義
  • UART1: 特定のUARTレジスタ構造体へのポインタ。例えば、UART1->DRはUART1のデータレジスタを表す。
  • UART_SendChar( UART1, c): デバイス内の全てのUARTで動作する関数。第一引数はUARTレジスタ構造体へのポインタ。
  • UART1_SendChar(c):UART1特定の実装

最小限の要求

ペリフェラルレジスタと関連する機能へアクセスするために、device.h及びcore_cm0.h/core_cm3.hは最小でも以下を定義する。

  • Register Layout Typedefは各ペリフェラルのレジスタ名を定義する。RESERVEから始まる名前は、ペリフェラルのアドレスを調節するためのスペースを設けるために使われる。
typedef struct {
  __IO uint32_t CTRL;      /* SysTick Control and Status Register */
  __IO uint32_t LOAD;      /* SysTick Reload Value Register       */
  __IO uint32_t VAL;       /* SysTick Current Value Register      */
  __I  uint32_t CALIB;     /* SysTick Calibration Register        */
  } SysTick_Type;
  • 各ペリフェラルに対する基底アドレス(Base Address):同名の複数のペリフェラルがある場合、同じRegister Layout Typedefが複数の基底アドレスで定義される。
#define SysTick_BASE (SCS_BASE + 0x0010)            /* SysTick Base Address */
  • 各ペリフェラルに対するアクセス定義(Access Definition):同じRegister Layout Typedefを使用するペリフェラルが複数ある場合、アクセス定義はUART0,UART1のように複数存在する。
#define SysTick ((SysTick_Type *) SysTick_BASE)     /* SysTick access definition */

これらの定義は、ユーザコードからペリフェラルレジスタへ、簡単な代入でアクセスすることを可能にする。

SysTick->CTRL = 0;

オプション機能

device.hでは更に以下のものが定義される場合がある。

  • ペリフェラルレジスタへ簡単にアクセスするための#define定数。これらの定数は、ペリフェラルのプログラミングで必要となるビット位置や特定のパターンを定義している。識別子はPERIPHERAL_から始まる。#define定数では大文字をつかうことが推奨される。
  • より複雑なペリフェラル機能を提供する関数(送信レジスタアクセス前にステータスを調べるなど)。これらの関数名もまた、PERIPHERAL_から始まる。

core_cm0.h/core_cm0.c

core_cm0.hはCortex-M0コアペリフェラルのデータ構造と、アドレスマップを記述している。 また、Cortex-M0コアレジスタ、コアペリフェラルへの基本的なアクセス手段を効率的な関数(static inlineなど)を提供する。

core_cm0.cはプロセッサレジスタへアクセスするためのいくつかのヘルパ関数を定義している。

これらのファイルがセットで、Cortex-M0のCore Peripheral Acceses Layerが実装されている。

core_cm3.h/core_cm3.c

core_cm3.hはCortex-M3コアペリフェラルのデータ構造と、アドレスマップを記述している。 また、Cortex-M3コアレジスタ、コアペリフェラルへの基本的なアクセス手段を効率的な関数(static inlineなど)を提供する。

core_cm3.cはプロセッサレジスタへアクセスするためのいくつかのヘルパ関数を定義している。

これらのファイルがセットで、Cortex-M3のCore Peripheral Acceses Layerが実装されている。


startup_device

startup_deviceのテンプレートファイルはARMが対応するコンパイラ用に提供している。シリコンベンダによって割り込みベクタと割り込みハンドらが組み込まれている。各割り込みハンドラは、ダミーハンドラへのweak関数として定義される。従って、割り込みハンドラはstartup_deviceに適合するよう作ること(名前と型を合わせるということ)以外の要求なしに、アプリケーションで直接利用できる。

以下の例外名は固定で、Cortex-M0のベクタテーブルの初めの部分を定義している。(アセンブリコード?)

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler               ; SVCall Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     PendSV_Handler            ; PendSV Handler
                DCD     SysTick_Handler           ; SysTick Handler

以下の例外名は固定で、Cortex-M3のベクタテーブルの初めの部分を定義している。

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler               ; SVCall Handler
                DCD     DebugMon_Handler          ; Debug Monitor Handler
                DCD     0                         ; Reserved
                DCD     PendSV_Handler            ; PendSV Handler
                DCD     SysTick_Handler           ; SysTick Handler

以下はデバイス固有の割り込みの例。

; External Interrupts
                DCD     WWDG_IRQHandler           ; Window Watchdog
                DCD     PVD_IRQHandler            ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler         ; Tamper

デバイス固有割り込みは、ユーザコードにより上書きされるダミー関数を持っている。

Default_Handler PROC
                EXPORT WWDG_IRQHandler   [WEAK]
                EXPORT PVD_IRQHandler    [WEAK]
                EXPORT TAMPER_IRQHandler [WEAK]
                :
                :
                WWDG_IRQHandler
                PVD_IRQHandler
                TAMPER_IRQHandler
                :
                :
                B .
                ENDP

ユーザアプリケーションでは、単純に割り込みハンドラ関数を定義すればよい。

void WWDG_IRQHandler(void)
{
  :
  :
}

system_device.c

system_device.cのテンプレートファイルはARMにより提供され、シリコンベンダによって実デバイスに適応される。 最小限の要求として、このファイルはデバイス固有のシステムコンフィギュレーション関数と、システム周波数を含むグローバル変数を提供しなくてはならない。これはデバイスを設定し、オシレータを初期化する。(提供するのはベンダ...)

system_device.cは最小限の要求として、以下に示すSystemInit関数を提供しなくてはならない。

関数定義 説明
void SystemInit (void) マイクロコントローラのセットアップを行う。通常この関数はデバイス内のオシレータ設定を行う。可変クロック周波数の場合、SystemFrequency変数の更新も行われる。

system_device.cには、CPUクロックを保持する変数SystemFrequencyが含まれる。

変数定義説明
uint32_t SystemFrequency システム周波数を保持する(システムクロック周波数はSysTickタイマやプロセッサコアクロック?から供給される)。この変数は関数SystemInit()が呼び出され、SysTickタイマがセットアップされ、他のパラメータの設定が終了した後、ユーザアプリケーションから使用することができる。

これはデバッガが周波数を取得し、トレースクロック周波数を設定するのにも使われる。
この変数は定数領域で定義されることも可能。 ただし、アプリケーションプログラムがこの変数を使用しない場合に、コンパイラがこの変数を除去してしまうことが内容設定しなくてはならない。 デバッガの設定に必要なため、この変数はメモリ上に存在しなくてはならない。

注記
上記の定義はsystem_device.cの最小限の要求である。このファイルは、よりフレキシブルなシステム設定を可能にするために、他の関数や変数をエクスポートすることもある。

Core Peripheral Access Layer

Cortex-Mx Core Register Access

以下の関数は、core_cm0.h/core_cm3.hで定義された、Cortex-Mxコアレジスタへのアクセスを行う関数である。

関数定義 コア コアレジスタ 説明
void __enable_irq (void) M0, M3 PRIMASK = 0 Global Interrupt enable (using the instruction CPSIE i)
void __disable_irq (void) M0, M3 PRIMASK = 1 Global Interrupt disable (using the instruction CPSID i)
void __set_PRIMASK (uint32_t value) M0, M3 PRIMASK = value Assign value to Priority Mask Register (using the instruction MSR)
uint32_t __get_PRIMASK (void) M0, M3 return PRIMASK Return Priority Mask Register (using the instruction MRS)
void __enable_fault_irq (void)
M3 FAULTMASK = 0 Global Fault exception and Interrupt enable (using the instruction CPSIE f)
void __disable_fault_irq (void) M3 FAULTMASK = 1 Global Fault exception and Interrupt disable (using the instruction CPSID f)
void __set_FAULTMASK (uint32_t value)
M3 FAULTMASK = value Assign value to Fault Mask Register (using the instruction MSR)
uint32_t __get_FAULTMASK (void) M3 return FAULTMASK Return Fault Mask Register (using the instruction MRS)
void __set_BASEPRI (uint32_t value) M3 BASEPRI = value Set Base Priority (using the instruction MSR)
uiuint32_t __get_BASEPRI (void) M3 return BASEPRI Return Base Priority (using the instruction MRS)
void __set_CONTROL (uint32_t value) M0, M3 CONTROL = value Set CONTROL register value (using the instruction MSR)
uint32_t __get_CONTROL (void) M0, M3 return CONTROL Return Control Register Value (using the instruction MRS)
void __set_PSP (uint32_t TopOfProcStack) M0, M3 PSP = TopOfProcStack Set Process Stack Pointer value (using the instruction MSR)
uint32_t __get_PSP (void) M0, M3 return PSP Return Process Stack Pointer (using the instruction MRS)
void __set_MSP (uint32_t TopOfMainStack) M0, M3 MSP = TopOfMainStack Set Main Stack Pointer (using the instruction MSR)
uint32_t __get_MSP (void) M0, M3 return MSP Return Main Stack Pointer (using the instruction MRS)

Cortex-Mx Instruction Access

名前 コア CPU命令 説明
void __WFI (void) M0, M3 WFI Wait for Interrupt
void __WFE (void) M0, M3 WFE Wait for Event
void __SEV (void) M0, M3 SEV Set Event
void __ISB (void) M0, M3 ISB Instruction Synchronization Barrier
void __DSB (void) M0, M3 DSB Data Synchronization Barrier
void __DMB (void) M0, M3 DMB Data Memory Barrier
uint32_t __REV (uint32_t value) M0, M3 REV Reverse byte order in integer value.
uint32_t __REV16 (uint16_t value) M0, M3 REV16 Reverse byte order in unsigned short value.
sint32_t __REVSH (sint16_t value) M0, M3 REVSH Reverse byte order in signed short value with sign extension to integer.
uint32_t __RBIT (uint32_t value) M3 RBIT Reverse bit order of value
uint8_t __LDREXB (uint8_t *addr) M3 LDREXB Load exclusive byte
uint16_t __LDREXH (uint16_t *addr) M3 LDREXH Load exclusive half-word
uint32_t __LDREXW (uint32_t *addr) M3 LDREXW Load exclusive word
uint32_t __STREXB (uint8_t value, uint8_t *addr) M3 STREXB Store exclusive byte
uint32_t __STREXB (uint16_t value, uint16_t *addr) M3 STREXH Store exclusive half-word
uint32_t __STREXB (uint32_t value, uint32_t *addr) M3 STREXW Store exclusive word
void __CLREX (void) M3 CLREX Remove the exclusive lock created by __LDREXB, __LDREXH, or __LDREXW

NVIC Access Functions

CMSISはレジスタインターフェース構造体と、NVICの設定を簡素化するヘルパ関数により、NVICへのアクセス手段を提供している。CMSIS HALは割り込み番号IRQnにより、割り込みを識別する。最初の割り込み番号はIRQn=0であり、負のIRQnはプロセッサコア例外で使われる。

コア例外で使われるIRQnは、device.hで以下のenumで定義される。

コア例外enum値 コア IRQn 説明
NonMaskableInt_IRQn M0, M3 -14 Cortex-Mx Non Maskable Interrupt
MemoryManagement_IRQn M3 -12 Cortex-Mx Memory Management Interrupt
BusFault_IRQn M3 -11 Cortex-Mx Bus Fault Interrupt
UsageFault_IRQn M3 -10 Cortex-Mx Usage Fault Interrupt
SVCall_IRQn M0, M3 -5 Cortex-Mx SV Call Interrupt
DebugMonitor_IRQn M3 -4 Cortex-Mx Debug Monitor Interrupt
PendSV_IRQn M0, M3 -2 Cortex-Mx Pend SV Interrupt
SysTick_IRQn M0, M3 -1 Cortex-Mx System Tick Interrupt

The following functions simplify the setup of the NVIC. The functions are defined as static inline.

以下の関数はNVICの設定を簡素化する関数である。関数はstatic inlineで定義される。

名前 コア パラメータ 説明
void NVIC_SetPriorityGrouping(uint32_t priority_grouping) M0, M3 Priority Grouping Value Priority Grouping(Groups . Subgroups)設定
void NVIC_EnableIRQ(IRQn_Type IRQn) M0, M3 IRQ Number Enable IRQn
void NVIC_DisableIRQ(IRQn_Type IRQn) M0, M3 IRQ Number Disable IRQn
uint32_t NVIC_GetPendingIRQ (IRQn_Type IRQn) M0, M3 IRQ Number Return true (IRQ-Number) if IRQn is pending
void NVIC_SetPendingIRQ (IRQn_Type IRQn) M0, M3 IRQ Number Set IRQn Pending
void NVIC_ClearPendingIRQ (IRQn_Type IRQn) M0, M3 IRQ Number Clear IRQn Pending Status
uint32_t NVIC_GetActive (IRQn_Type IRQn) M3 IRQ Number Return the IRQn of the active interrupt
void NVIC_SetPriority (IRQn_Type IRQn, uint32_t priority) M0, M3 IRQ Number, Priority IRQnの優先度を設定
(Cortex-M0ではスレッドセーフではない...内部変数を持つ)
uint32_t NVIC_GetPriority (IRQn_Type IRQn) M0, M3 IRQ Number IRQnの優先度を習得
void NVIC_SystemReset (void) M0, M3 (void) システムをリセット

注記

プロセッサ例外は負の列挙値(enum value)を持つ。デバイス固有の割り込みは0から始まる正の列挙値を持つ。値はdevice.hで定義される。


SysTick設定関数

以下の関数はSysTickタイマを設定し、SysTick割り込みを開始する。

名前 パラメータ 説明
uint32_t SysTickConfig (uint32_t ticks) ticks is SysTick counter reload value SysTickタイマを設定し、SysTick割り込みを有効化する。

この呼び出しののち、SysTickタイマは指定された感覚で割り込みを生成する。 戻り値:成功したら0、失敗したら1


以下TBD.

メモ

  • プログラムを作るときは、プロジェクトにCMSISファイルをコピーして使うらしい
  • ベクタテーブルについて
    • スタートアップルーチンでベクタテーブルが用意されている
    • ベクタテーブルの配置されるセクション名は指定されている
    • リンカスクリプトでベクタテーブルが正しい場所に配置されるよう指定すること
  • startup_stm32f10x_xdスタートアップルーチンについて
    • デフォルトではC言語が動く前に、静的変数の初期化を行うだけ
    • 初期値あり静的変数のROM上の番地とコピー先番地(開始・終了)がシンボルとして必要
    • 初期値なし静的変数の開始・終了番地がシンボルとして必要
    • スタックポインタの初期番地がシンボルとして必要
    • 必要なシンボルはリンカスクリプトで定義すること
    • プロセッサのタイプ(High/Medium/Low-density)に合ったものを使用すること
      • ファイル名の接尾辞hd/md/ldがHigh/Medium/Low-densityに対応
  • stm32f10x.hについて
    • ペリフェラルを使用する全てのソースコードはstm32f10x.hをインクルードする
    • stm32f10x.hインクルード時は、2種類のマクロが必要(ここには書かれていない)
      • STM32F10x Standard Peripherals Firmware Library: Overview参照
      • プロセッサタイプを選択するSTM32F10X_[L M H]Dマクロ
      • ドライバ関数の使用を選択するUSE_STDPERIPH_DRIVERマクロ
        • このマクロ定義でstm32f10x_conf.hがインクルードされる
        • stm32f10x_conf.hはプログラマが用意する
      • マクロ定義はコンパイラオプションで行うとよい
        • GCCの場合、[-imacros header.h]でヘッダ内のマクロだけ読み込める
  • core_cm0/3.c/hについて
    • プロジェクトにコピーして使う
  • system_stm32f10x.h/c
    • システム初期化ルーチンを含むテンプレート
    • プロセッサの周波数設定を行うこと(デフォルト72MHz)
    • 外部RAMの設定など、必要なコードを追加すること