記事ディレクトリ
- 第2段階~理論的根拠~cortex-MシリーズCPUのコアを探る
第2段階~理論的根拠~cortex-MシリーズCPUのコアを探る
参考:Cortex-M3 Definitive Guide 中国語版
Cortex-M アーキテクチャ CPU コア ストレージ システム
記憶単位は1バイト、1バイト=8ビット
ストレージシステムの特徴
1 ストレージシステムの主な特長
4GB のリニア アドレス空間
B=byte bbit: bit 1byte=8bit
ARM 社が提供する定義済みのメモリ マップ。チップ メーカーは、
ビッグ エンディアン モードとリトル エンディアン モードをサポートするよう改良しています (両方とも設定可能で、デフォルト モードは次のとおりです: 必須データシート)
ビットバンド アクセスをサポート (オプション) 領域制限があり、直接 AND または演算
メモリ保護ユニットをサポート (オプション) CPU メーカーは、不正な読み取りおよび書き込み操作を防止するために、それを含めるかどうかを規定します
非整列送信をサポートします
ヒント 1: 4GB アドレス空間の起源
32 ビット ストレージ システム、32 個の 0 または 32 個の 1。
電卓は最初に 32 個の 1 を 2 進数で入力し、次にそれらを 10 進数表示に変換し、次に 1 を追加して (アドレス空間がアドレス 0 から始まるため)、バイトの合計サイズを示します
。 1024をまずKBにして1024を割って4096MBになり1024を割って4GBになるか、
2の32乗で1024を3割する。
Tip2: ビッグエンディアンモードとリトルエンディアンモードについて
ビッグエンディアン モード: 上位バイトはメモリの下位アドレスに格納され、下位バイトはメモリの上位アドレスに格納されます; 文字列として、アドレスは小さなものから大きなものへと増加します. リトルエンディアン モード
:ビッグエンディアンの反対。アドレスの上位ビットと下位ビットは、データの上位ビットと下位ビットに一致します。人の論理的な考え方に近い。
例: 0X1234
上位および下位の
ビッグ エンディアン 0x12 0x34
リトル エンディアン 0x34 0x12元の
記事への参照リンク
. 一般的なアーム チップは、デフォルトでリトル エンディアン ストレージ モードを使用します. CM3 の場合、REV/REVH およびその他の関連する命令を使用してリバースすることができますエンディアン モードを完了するためのバイト オーダー。
注: CM3 では、ストレージ モードはリセット時に決定され、実行時に変更することはできません。また、命令のプリフェッチでは常にリトル エンディアン モードが使用され、構成制御ストレージ スペースへのアクセスでは常にリトル エンディアン モード (NVIC、FPB などを含む) が使用されます。また、外部専用バスアドレス領域 0xE0000000 ~ 0xE00FFFFF は、常にリトル エンディアン モードを使用します。
STM32のサイズとサイズをテストする
int a = 0x12345678;
int i;
char b[4];
int main(void)
{
for (i = 0; i < 4; i++){
b[i] = *((char*)&a + i);
}
}
▲ ポインタを使用して、STM32 がスモール エンディアン ストレージであることを確認する
したがって、STM32 はデフォルトでスモール エンディアン ストレージを使用します。
もちろん、共用体を使用してテストすることもできます。
union B_t{
char b[4];
int a;
};
union B_t B;
int main(void)
{
B.a = 0x12345678;
}
Tip1: Cortex-MアーキテクチャCPUの割り込みとARM7アーキテクチャの割り込みの違い
FIQ 高速割り込み Cortex-M 12 ティック
IRQ 共通割り込み ARM72 種類が持つ
ヒント 2: 整列転送と非整列転送
ARM9、10 はアラインされた転送である必要があり、
coretx_m3、m4 はアラインされていない転送をサポートし、単一のデータ、複数のデータ、ビット ストリップ、スタックなどに限定されます
。アラインされていないコードは非効率的です。
後で使用するために、位置合わせして配置してみてください。
ストレージ システムのマップ
ストレージ システム マップの簡単な分析
内部プライベート ペリフェラル バスを含むプライベート ペリフェラル
0xFFFFFFFF
ビルトイン割り込みコントローラ
(NVIC) およびデバッグ
コンポーネント
OxEO000000
OXDFFFFFFF
主に外部外部
ペリフェラルに使用
OxA0000000OxSFFFFFF
主に外部外部メモリ
メモリに使用
Ox60000000
主にペリフェラルに使用 オンチップ ペリフェラル
Ox5FFFFFF0x40000000
主に使用データ メモリ
0x3FFFFFFF
(例: スタティック RAM)
Ox20000000
主にプログラム
0x1FFFFFF
コードに使用。例外
ベクタ テーブルにも使用
Ox00000000
スタック ストレージ モデル
1 スタックとは:プログラミング モデルにおけるLIFO モード (後入れ先出し) スタックの機能
(1) 関数呼び出し
(2) 割り込みおよび例外処理
(3) ローカル変数の保存
2 でのスタックの実装Cortex-M アーキテクチャ
が下位 成長するスタックがいっぱい システムが起動すると、スタック ポインタはシステム スタックの最後にある セグメントが入力されるたびに、SP コンテンツ -4 (スタック アライメント) が実行され、スタック操作は+4で、すべてのポジションが使用できます。
3 MDK-ARM5.13のシミュレーションデモ
Cortex-M アーキテクチャ CPU コアの割り込みおよび例外処理
☆割り込みと例外の考え方
1 例外と割り込みとは?
現在正常に動作しているプログラムの流れを変える事象で、プロセッサが現在のタスクを中断し、例外ハンドラを実行する.
割り込みが特殊な例外の場合、
2 割り込みの種類3
共通の割り込み要因
I/O 割り込み、タイマー割り込み、ソフトウェア割り込み…
☆例外処理の流れ
例外が処理条件を満たしているかどうかの判定
MCU の動作状態、
例外 EN (イネーブル) NMI、HardFault 常に
PR ハイの応答処理シーケンスをイネーブル
非マスク例外プッシュ操作: PSR、PC、LR、L12、R0-R13フェッチ ベクタ (例外ベクタ テーブル)更新レジスタ SP、PSR、PC 、LR例外処理 ハンドル:異常復帰処理を処理するシーケンス:スタック操作、NVIC
Tip1: 割り込みベクタテーブル
各例外ハンドラの開始アドレスを格納する配列。使用するたびに、NVIC はこの値を 0 に更新します。
典型的な割り込みベクタ テーブル:
最後のビットが 1 であることを観察します, これはサブ状態にあることを意味するので, 最後のビットは 1 に設定されます (最下位ビット LSB). 初期アドレスは MSP に格納されます (メインの初期
値スタックポインタ)
☆NVIC 紹介 (割り込みコントローラ) 1 NVICネスト割り込みベクタコントローラ
とは:機能: 優先度の設定、有効化、マスク、サスペンドネスト: 割り込み条件をトリガして、別の割り込みベクタをトリガできます: 割り込み/異常ローディングのサポート内部テーブル エントリ2 NVIC の機能柔軟な割り込みおよび例外管理ネストされた割り込み/例外のサポート内部テーブル エントリへの割り込み/異常ロードのサポート
Tip1: 割り込みをマスクできるコア特殊レジスタ群
PRIMASK 1 ビット、1 を設定、すべてのマスク可能な例外を
閉じます。NMI のみ、HardFault を閉じることはできません閉じて、数字が大きいほどレベルが低くなります。
Cortex-M アーキテクチャの CPU リセットとリセットのタイミング
☆3つのリセット方法
リセットには遅延があり、主にクロックソースがリセットして安定するまでの時間を待ちます。メーカーやCPUは異なります1.パワー
オンリセット
2.システムリセット(デバッグコンポーネントをリセットしないでください)
3.プロセッサのリセット (デバッグ コンポーネントとペリフェラルはリセットされません)
☆リセットのタイミングの説明
リセット状態を抜けた後、CM3 が最初に行うことは、次の 2 つの 32 ビット整数値を読み取ることです。 アドレス ox0000,0000 から MSP の初期値を取得します。
アドレス ox0000,0004 から PC の初期値を取得します。この値はリセット ベクターで、LSB は 1 でなければなりません。次に、この値に対応するアドレスから値を取得します。
ヒント 1: 例外がメイン スタック ポインターを内部テーブルの開始位置 (つまり、アドレス 0) に格納する理由
これは従来の ARM アーキテクチャとは異なることに注意してください。実際、他のほとんどの MCU とは異なります。従来の ARM アーキテクチャでは、常にアドレス 0 から最初の命令が実行されます。それらのアドレス 0 は常にジャンプ命令です。CM3 では、MSP の初期値がアドレス 0 で提供され、その後にベクター テーブルが続きます (ベクター テーブルは将来、他の場所に移動できます - 注釈)。ベクタテーブルの値はジャンプ命令ではなく32ビットアドレスです。ベクタ テーブルの最初のエントリは、リセット後に実行する必要がある最初の命令を指します。
CM3 は下方向に成長するフル スタックを使用するため、MSP の初期値はスタック メモリの最後のアドレス + 1 でなければなりません。たとえば、スタック領域が 0x20007C00 ~ 0x20007FFF の場合、MSP の初期値は 0x20008000 でなければなりません。
ベクタ テーブルは、MSP の初期値、つまり 2 番目のエントリに従います。CM3 は Thumb 状態で実行されるため、ベクタ テーブルの各値は LSB を 1 (つまり、奇数) に設定する必要があることに注意してください。このため、図 3.18 でアドレス 0x100 を表すために 0x101 が使用されています。0x100 の命令が実行されると、プログラムの実行が正式に開始されます。最初の命令が実行される前に NMI またはその他の障害が発生する可能性があるため、この前に MSP を初期化する必要があります。MSP が初期化された後、スタックはサービス ルーチン用に準備されます。
開発ツールが異なれば、MSP の初期値とリセット ベクトルを設定するために異なる形式を使用する必要があります。開発ツール自体によって計算および生成されるものもあります。詳細を知りたい場合は、開発ツールが提供するサンプル プロジェクトの 1 つを参照するのが最も簡単な方法です。この本の第 10 章と第 20 章では ARM が提供する開発ツールを紹介し、第 19 章では GCC ツール チェーンを紹介します。
☆スタートアップコードの説明
1.スタートアップコードの主な機能 スタック
空間の定義 割り込みベクタテーブルの
格納
リセット割り込み関数(Reset_Handler);
その他の割り込み例外サービス関数とweak[WEAK]文;weak文、ユーザー定義の場合、ユーザー定義を入力し、プログラムのクラッシュを防ぎます。
スタック アドレスをライブラリ関数に渡し、ライブラリ関数を使用してスタックを初期化し、ライブラリ関数自体を初期化します。
ヒント 1: スタートアップ コードを記述せずに以前の 8 ビットおよび 16 ビット MCU を使用する理由
2. ST が提供する Cortex-M4 スタートアップ コードの簡単な分析
以前のプロジェクトを開いて、次を開きます: F:\IOT\PRJ\first_prj\ RTE\Device \STM32F407ZGTx\startup_stm32f407xx.s
の最初の行の有効なコードは次のとおりです: Heap_Size EQU 0x00000200
カーソルを EQU に移動し、F1 を押してコメントを開きます:
AREA STACK, NOINIT, READWRITE, ALIGN=3; ここで 3 は 2 です3 乗、8 バイト アライン、
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;这里的3是2的3次方,8字节对齐,
Stack_Mem SPACE Stack_Size ;定义我们的0x00000400大小的存储块,值均为0
__initial_sp ;标号,指示当前堆栈的初始位置
具体地址见工程下的map文件:F:\IOT\PRJ\first_prj\Listings\first_prj.map
__initial_sp 0x20000670 Data 0 startup_stm32f407xx.o(STACK)
这个是最高地址,向下压栈。
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000200
AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;定义堆空间
__heap_base
Heap_Mem SPACE Heap_Size ;定义堆空间大小为 0x00000200
__heap_limit
PRESERVE8 ;指示当前堆栈是8字节对齐
THUMB ;告诉汇编器以下均为32位的THUMB指令
; Vector Table Mapped to Address 0 at Reset 向量表映射
AREA RESET, DATA, READONLY ;定义复位向量段
EXPORT __Vectors ;导出后,其他部位也能使用此全局标号
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack 分配4字节32位地址
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
; 取引をリセットする
Reset_Handler PROC ;标记函数的开始
EXPORT Reset_Handler [WEAK] ;弱声明
IMPORT SystemInit ;从其他文件导入.\first_prj\RTE\Device\STM32F407ZGTx\system_stm32f4xx.c
IMPORT __main ;从其他文件导入
LDR R0, =SystemInit ; 函数入口地址加入到R0, =把入口地址传给R0
;MOV R1,PC
BLX R0 ; 地址0x080002D1后面的1代表是sub状态
LDR R0, =__main
BX R0
ENDP ;函数结束
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B . ;死循环
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
;**************************************************** *** ****************************
; ユーザースタックとヒープの初期化 ユーザースタックの初期化
;******** ** ************************************************ ***** ********************
IF :DEF:__MICROLIB ;如果勾选了,就会执行
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory ;未勾选执行此部分,使用双堆栈
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END
デモコード
リセット後、まずスタック ポインタ sp を 0x20000670 にポイントします。
実際に実行されると、リセット ハンドラーに入り、前のハンドラーは CPU によって自動的に完了されます。つまり、
シングル ステップの実行、エントリ アドレスの取得、および SystemInit へのジャンプです。
ジャンプしてメイン関数に入ります。
参考書:
Cortex M3 and M4 Authoritative Guide.pdf 2014
Protel Schematic.pdfls 2009
STM32F4xx English Reference Manual.pdf 2014
STM32F4xx Chinese Reference Manual.pdf 2014
STM32F407ZGT6.pdf 2014