web-dev-qa-db-ja.com

開始方法ARM埋め込みCを使用したCortexプログラミング?

8051 Cプログラミングに精通しています。今、ARM cortex M3プログラミングを学びたいです。 ARM Cortex M3プロセッサを搭載したSTM32F103C8T6開発ボードがあり、プログラマーおよびKeilコンパイラーです。LED、SPI、I2Cプログラミングの点滅など、小規模なプロジェクトを行いたいです。アームアーキテクチャについてほとんど知識がありません。 。ブログの多くの人は、アーキテクチャを読んだり、100ページARMデータシートを読んだりする代わりに、直接プログラミングを開始すると言います。私はそれがどのように可能か理解していません。

それで、私の最初のステップは何ですか?

  1. STM32F103C8T6またはARM Cortex M3ユーザーマニュアルのデータシートを読む必要がありますか?

  2. 8051とARMプログラミングには大きな違いがあります。 8051では、ライブラリ/ヘッダーファイルを追加する必要はありません。 ARMには、多くのライブラリ/ヘッダーファイルを追加する必要があります。瞬きプログラムをしたい、またはSPI/I2C通信を学習したいとします。 KEILコンパイラまたはSTM CubeMXには、これらのヘッダーファイルがすでに存在しますが、自分ですべてをやり直したい場合(周辺機器、I/Oポート、SPI/I2Cプロトコルコードのヘッダーファイルコードの書き込み)、本当に可能ですか?はいの場合、どうすればよいですか?

私はそれに関して私を導く適切な人をまだ見つけていないので、私は非常に混乱して欲求不満です

enter image description here

7
user3559780

既存のライブラリコードを使用して、アーキテクチャ、起動、および周辺機器のドライバーの問題に対処する場合、可能です(つまり、データシートおよびリファレンスマニュアルの詳細な知識なしで起動すること)。 ARM Cortex-MおよびSTM32には、具体的に次のものが含まれます(さまざまなレベルの抽象化とスコープで):

多くの場合、商用ツールベンダー(Keil、IAR、Rowley、Green Hillsなど)は、サンプルプロジェクト、ドライバーライブラリ、および特定の開発ボード向けのミドルウェアを提供しています。

それはおそらく、ARM

"多くのライブラリ/ヘッダーファイルを追加する必要があります。"

まったく必要ありませんが、8051よりも複雑な部品であり、部品とベンダーによって異なる大規模で複雑な周辺機器セットがあり、そのようなライブラリを利用することで時間と労力を大幅に節約できます。

ARM Cortex-Mコア自体には、マイクロコントローラー周辺機器、CPUおよびNVIC割り込みコントローラーの外部、およびFPUの一部のハイエンド部品では、すべてがベンダー固有であり、ベンダーによって大きく異なるため、ベンダーのドキュメントを理解するか、チップまたはツールのベンダーまたはコミュニティが提供するライブラリを活用する必要があります。

Cortex-MまたはSTM32を完全に理解し、それらを最大限に活用したい場合は、参照資料を読むことに代わるものはありませんが、開始するだけでは決して必要ありません。

ARM参照資料よりも簡単にinin Cortex-Mが必要な場合は、Joseph Yiuの ARM®Cortex®-M3およびCortex®-M4プロセッサの決定版ガイド は良いソースですが、低レベルを書いている場合を除きますRTOSまたはベアメタルスタートアップコードまたは他のシステムレベルコードは、それほど多くの資料を必要としない場合があります。この本の以前のM3のみのエディションは、PDF in 一部の場所

メモリインターフェイス、メモリマップ、電源管理機能、フラッシュメモリプログラミング、割り込みマッピング、ハードウェア周辺機器などのベンダー固有の機能を説明するチップベンダーのリファレンスマニュアルは、おそらくより有用な資料です。

特にSTM32については、HitexのTrevor Martinによるやや幅広いガイドがあります。 The STM32 To Insider's Guide to the STM32 ARM Based Microcontroller 、Trevorによる有用な出版物の1つにすぎません。

3
Clifford

私はそこに行ったことがあります。しばらくしてから、最初のボードであっても、データシートから始める方が良いことに気付きました。

データシートは、ボード、ピン、および基本的な通信の包括的な機能を提供します。それは退屈かもしれませんが、それは価値があり、あなたがプログラミングを始めるときに気付くでしょう。

その後、ヘッダーファイルに直接ジャンプし、基本的な機能の実装を確認できます。これにより、最適化手法、プログラミングのスタイル、およびベストプラクティスに関する多くの洞察が得られます。

可能であれば、そのボード用に記述されたコードをさらに見つけてください(私は常にここで失敗します。ボードがまれな場合は難しいです)。

これで、ほとんどすべてのコードを書く準備ができているはずです。まばたきから始めましょう(ボードのこんにちは世界)

また、私の経験では、時間をかけても大丈夫です。忍耐と粘り強さがあります。

9

Cプログラマーとして、CPUコアアーキテクチャについて読む必要はありませんが、CPUマニュアルを簡単に読むことをお勧めします。レジスターやリソース、データキャッシュ、命令キャッシュなどを把握することで、より高品質のCコードを記述できるようになります。ただし、8051などのひどく不良なコアでは、これははるかに重要です。

MCU周辺機器のハードウェアとメモリに関しては、マニュアルのすべての行を読む必要があります使用する部品について。これには、ウォッチドッグ、クロック設定、MMU、割り込み処理などの基本が含まれます。

ただし、MCUのほとんどのツールチェーンには、現在、何らかの方法でシュガーコーティングライブラリが付属しています。彼らはあなたにほとんどのものが設定された作業プロジェクトを提供します。つまり、一度にすべてを学ぶ必要はありませんが、プロジェクトが進むにつれて少しずつ学ぶことができます。たとえば、いくつかのLEDを点滅させるには、マニュアルのGPIO部分以外を読むことなく、それを実行できる必要があります。

最終的には、事前に作成された高速でダーティなライブラリを高品質のコードに置き換える必要があります。これは、これらのライブラリを提供するシリコンメーカーが、ソフトウェアの作成が悪名高いためです。場合によっては、適切なMCUセットアップコードを提供できますが、多くの場合、低品質のコードを提供します。

これ は、おおよそのMCUセットアップの外観です。リストを使用して、メーカーから入手したものがすべて有用であるかどうか、またはプロの組み込みプログラマーによってリストを書き換える必要があるかどうかを確認できます。 ARM CMSISは、アプリケーションの要件に応じて、十分な場合もあれば不十分な場合もあります。ツールチェーンに応じて、さまざまなフレーバーがあります。

3
Lundin

これはいくつかの実用的な例とアドバイスですが、あなたが探しているものではない場合は、TL; DRは気にしません...

さまざまなパスをたどり、それを定期的に繰り返すことをお勧めします。専門的には、データシート/回路図だけでなく、ベンダーの缶詰ライブラリからfreertosまたは他のソリューションまでの範囲をカバーできるようにしたいと考えています。私の個人的な好みはデータシート/回路図です。これは時間がかからず、よりクリーンで、高速で、信頼性が高いと思います... YMMV。最初のルールはドキュメントがバグだということ、2番目のライブラリはバグがある(そして中を見ると怖い)。一部のベンダーは比較的良い仕事をしている傾向がありますが、時間の経過とともに、自分が好きなベンダーを自分で見つけることができる場合があります。趣味としての楽しみは確かにそれを行うことができます。これまでのところ、私は腕対8051対他のことについて話していません、彼らはすべてこのデータシート対ライブラリ、バグのあるドキュメントなどを持っています。とにかく、あなたはライブラリまたはさまざまなオンラインオープンソースの例を掘り下げて見つける必要があるかもしれませんどこにも文書化されていないビットを有効にし、いくつかのレジスタをプログラムする必要がある順序を見つけ、他の誰かが内部知識を持っているか、運が悪いかもしれません。

したがって、arm-whatever-gcc/as/ldのどのようなフレーバーでも動作する必要がある、最小限の例を投稿するだけです。 (arm-linux-gnueabi arm-none-eabiなど)。また、定期的に行うように、ソースからgnuツールを構築することもできます。事前に構築されたいくつかの問題から始めるのが最善ですが、一度に1つの問題について心配します。

写真に示したボードには、特定のコミュニティタイプ名、「青い錠剤」または「stm32青い錠剤」もあります。 eBayや他の安価なボードとは異なり、このボードはコミュニティ作業を行ってardunioサンドボックスに収まりましたが、知識と経験を追求する別の手段であり、他の多くを読む必要のないarduinoの道を歩んでいますgoogle stm32 blue pillよりも、非常に一般的な数行のコードをサンドボックスに持って行くと、点滅するLEDがあります。

あなたはstlinkをサポートするopenocdを望んでいる/必要としているので、バイナリを見つけるか、ソースからビルドするかのどちらかがとても簡単です。私の好みは、設定ファイルをtclディレクトリから取り出してプロジェクトに持ち込み、必要に応じて変更することです。それらがそこにあり、openocdのあるバージョンから、または私がいるマシンから別のマシンに変更されていないことを願っています。 YMMV、これは非常に個人的な好みです。たとえば、私はe-cheapo jlinkクローン、eBayで数ドル(パープルボード)を使用します。そして、jlink.cfgを持っています

interface jlink
transport select swd

あなたの写真のボードは、stlinkのフレーバーの1つであり、試行錯誤やlsusb、または他の手段で判断できます。たとえば次のようになります。

interface hla
hla_layout stlink
hla_device_desc "ST-LINK/V2"
hla_vid_pid 0x0483 0x3748

私の場合

openocd -f jlink.cfg -f target.cfg

target.cfgは、openocdのさまざまなstm32f1xxx構成ファイルを含む単一のファイルです。

青い錠剤にはPC13のLEDがあり、そのポート内にポートcピン13があります。

ここの例は単なるベアメタルではなく、bootstrapコードを含みます。他のコードやヘッダーは必要ありません。これらのファイルのみ、およびこれを実行しているかどうかに応じてgnu armコンパイラーまたはクロスコンパイラーが必要ですアーム開発マシン(Raspberry Piコンピューターなど)またはその他(x86ベースなど)上のコードです。コードは、ライブラリアプローチとしてではなく、移植性などのために設計されています。これを行うことができます」という方法で、より複雑なソリューションを検討することで、自分の好みに進むことができます。

sram.s

@.cpu cortex-m0
@.cpu cortex-m3
.thumb

.thumb_func
.global _start
_start:
    ldr r0,=0x20001000
    mov sp,r0
    bl notmain
    b hang
.thumb_func
hang:   b .

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.thumb_func
.globl dummy
dummy:
    bx lr

stm32f103 ...はcortex-m3ベースであり、ピン配列などのパッケージと部品番号の情報が記載されたデータシートからSTM32F103C8T6ドキュメントを取得したため、これまでに知っておく必要があります(フラッシュとRAMの量を教えてください)すべてのレジスタ、アドレス空間、およびそのような詳細を含むst用語のリファレンスマニュアル(一部のベンダーはデータシートにすべてのレジスタと説明もあります)。これらの間に、これにはarmからのcortex-m3が含まれていることがわかります。したがって、arms Webサイトにアクセスし、armv7-mアーキテクチャに基づいているcortex-m3のテクニカルリファレンスマニュアルを入手します。 armv7-mアーキテクチャリファレンスマニュアルを入手します。これは、このCHIPの一連の開始ドキュメントです。次に、回路図またはPC13がLEDの位置を把握する他の方法を見つけようとします。

そのため、armv7-mはthumb命令セットに対するthumb2拡張機能のはるかに幅広い配列をサポートしますが、一般的なフレームワークから始めるために、必要に応じて次に示すように、一般的に伝統的な親指命令から開始することを好みます(パフォーマンスのために)通常)armv7-m thumb2拡張、YMMVで許可するようにビルドツールまたはコードを変更します...

blinker01.c

void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void dummy ( unsigned int );

#define GPIOCBASE 0x40011000
#define RCCBASE 0x40021000

int notmain ( void )
{
    unsigned int ra;
    unsigned int rx;

    ra=GET32(RCCBASE+0x18);
    ra|=1<<4; //enable port c
    PUT32(RCCBASE+0x18,ra);
    //config
    ra=GET32(GPIOCBASE+0x04);
    ra&=~(3<<20);   //PC13
    ra|=1<<20;      //PC13
    ra&=~(3<<22);   //PC13
    ra|=0<<22;      //PC13
    PUT32(GPIOCBASE+0x04,ra);

    for(rx=0;;rx++)
    {
        PUT32(GPIOCBASE+0x10,1<<(13+0));
        for(ra=0;ra<400000;ra++) dummy(ra);
        PUT32(GPIOCBASE+0x10,1<<(13+16));
        for(ra=0;ra<400000;ra++) dummy(ra);
    }
    return(0);
}

チップ、ボード、チップおよびボードと周辺機器のシミュレーションの長年の経験に加えて、航空宇宙産業で20代だったときの古いタイマー、命令、32ビットのロードとストア、16ビットなどを強制したいasmを使用して適切な命令を取得し、非常にクリーンな抽象化レイヤー(必要に応じて同じソースコードを使用してマクロで解決できるパフォーマンスコストにもかかわらず)を使用して、シミュレーター、パンチをアタッチします。オペレーティングシステムなどを通じてYMMV。揮発性ポインタートリックがBTWで失敗し、誤った命令を生成しました。このトリックを使用することはほとんどありません。コンパイルドメイン全体で構造体をルールとして使用しないでください。また、ユニオンを誤用しないでください。そのようなライブラリを使用すると、そのリスクを負うことになります。しかし、専門家は、これらのライブラリがいくつかの理由、個人的な好みのいずれかで決定される可能性があるため、時々そのリスクを所有する必要があります、ボスはそう言いました、レガシープロジェクトを維持し、tcp-ipを書き直す時間/欲望を持っていないスタックまたはファイルシステムなど.

これは、PC13をプッシュプル出力として構成するために、詳細なread-modify-writeを実行していることがわかります。次に、便利なビットセットまたはリセットレジスタを使用して、そのポートの1つのピンの状態を変更します。個別の最適化ドメインにdummy()があると、コンパイラーはそのループを生成し、その時間を燃やさなければならないので、LEDを見ることができます。

for(x=0;x<0x80000;x++) continue;

意図的または偶発的に最適化しないことを避けるために何もしないので最適化します。または、xに触れるたびにコンパイラがロードおよび保存することを提案するようにxを揮発性にするか、xを使用する別のコンパイルドメインで関数を呼び出しますループを構築します。後でタイマーを台無しにできます。

リンカースクリプトはツールチェーンに非常に固有のものであり、gnuを使用しなくてもかまいませんが、時々発生する奇妙な現象があります(この場合は-Ttext = 0x20000000)。これよりも少しシンプルにすることもできますが、ほとんどの人はYMMVを大幅に複雑にします。

MEMORY
{
    ram : Origin = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > ram
    .rodata : { *(.rodata*) } > ram
    .bss : { *(.bss*) } > ram
}

.bssや.dataを初期化する必要がないため、これらの要件に付随するすべての荷物を簡単に削除できます。この例で満足しているC標準違反。また、私のエントリーポイントは少なくとも1つのツールチェーンと呼ばれるmain()ではないことに注意してください。エントリポイント名は一般的なものにする必要があります。ツールチェーンがエントリポイントをオペレーティングシステムで実行されるバイナリであるかのようにマークするために使用される_startでさえも。リンカーは警告をスローする必要はありませんが、バイナリをビルドする必要はありません。

建てる

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 sram.s -o sram.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 -march=armv6-m -mthumb -c blinker01.c -o blinker01.o
arm-none-eabi-ld -o blinker01.elf -T sram.ld sram.o blinker01.o
arm-none-eabi-objdump -D blinker01.elf > blinker01.list
arm-none-eabi-objcopy blinker01.elf blinker01.bin -O binary

-nostdlib -nostartfiles -ffreestandingはもはや必要ではないと思います。使用しているgnuツールのバージョンとフレーバーに依存します。

最初のビルド時、およびmakefile/infrastructureを台無しにするときは常に、逆アセンブリをチェックします。

20000000 <_start>:
20000000:   4805        ldr r0, [pc, #20]   ; (20000018 <dummy+0x4>)
20000002:   4685        mov sp, r0
20000004:   f000 f80a   bl  2000001c <notmain>
20000008:   e7ff        b.n 2000000a <hang>

2000000a <hang>:
2000000a:   e7fe        b.n 2000000a <hang>

2000000c <PUT32>:

必要なエントリポイントを確保するために、必要なコードは前もってあり、正しくビルドされています(この場合はこれです)。

さらに2つ以上のコマンドラインターミナルを開きます。一般に、openocdを起動する場所はファイルを検索するための参照ポイントであるため、バイナリがあるディレクトリで起動する場合、パスを追加したり、バイナリをコピーしたりする必要はありません。この場合、elfバージョンはopenocdを起動する場所よりも優先されます。または、パスを入力するだけです。また、openocd構成ファイルを引き継ぐことにより、独自のスクリプトを構成に書き込み、これらのステップを自動化できます。

1つのウィンドウでopenocdを起動します

openocd -f jlink.cfg -f target.cfg

Open On-Chip Debugger 0.10.0-dev-00325-g12e4a2a (2016-07-05-23:15)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
swd
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : No device selected, using first device.
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : Hardware version: 7.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

行xブレークポイント、yウォッチポイント(アームの場合)にならない場合、先に進む準備ができていない、デバッガーを正しく配線する、などです。デバッガーのvcc行は実際には電源を入れることができません。あなたが写真に持っている特定のドングルについて彼らが言うことにもかかわらず、ボードは、私はそれをしようとしている人々の最初のものを爆破したと思います。ターゲットに電源を供給したい場合、vccラインは実際にはvccセンスラインであり、デバッガーでIO電圧を駆動し、入力のサンプルポイントを設定します。 5.0v 3.3v 3.0v、1.8vなどでこのようなツールを使用できますvセンスラインは、この場合3.3vレベルを使用していることを確認するために使用されます。など、openocdがこのポイントに到達するまで。

最も単純な方法はtelnetインターフェースです。gdbは使用しませんが、それは次のレベルの強化です。telnetインターフェースが動作した後はそれを保存します。

他のコマンドラインターミナルウィンドウのいずれかで

telnet localhost 4444

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> 

それから

> halt
stm32f1x.cpu: target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000042 msp: 0x20001000
> 

停止後に再び停止すると、その出力は得られません。私はフラッシュに無限ループを持っています(以下の例を取り、bl notmainをコメントアウトしてください)このsramの例があなたのために働くことを自分に示すために、sramの例が働くためにスタックポインタ以外はフラッシュ上で何も必要ありません.

一旦停止したら

> load_image sram/blinker01.elf
144 bytes written at address 0x20000000
downloaded 144 bytes in 0.008081s (17.402 KiB/s)
> resume 0x20000000
> 

そして、LEDがゆっくり点滅し始めます。 0x20000001を再開する必要があると主張することもできますが、ツールはたまたま0x20000000で動作します。

これは通常フラッシュよりも小さいsramを使い果たしていますが、mcuをブリックする危険を冒すことなくこの方法で多くの教育を受けることができます(boot0ピンを使用すると、これらのstm32デバイスでジェイルフリーカードを入手できます。代替/安全なブートパス用のストラップピンを持たない部品の独自のプロジェクトは、代替/安全なブートパスでビルドして、チップ/ボードをブロックしないようにする必要があります(誤ってI/Oピンの構成を変更しますたとえば、チップにアクセスしてファームウェアを変更するために依存するjtagピンは、どれだけ多くの経験があっても、時々発生します。念のため、ボード。

フラッシュで同じことをするようになりました

フラッシュ

@.cpu cortex-m0
@.cpu cortex-m3
.thumb

.thumb_func
.global _start
_start:
stacktop: .Word 0x20001000
.Word reset
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang
.Word hang

.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.thumb_func
.globl dummy
dummy:
    bx lr

プロセッサがどのようにブートするかは、そのプロセッサに非常に固有であり、ドキュメントを読むだけです。この場合は、単に実行を開始するアドレスではなく、ベクターテーブルです。この詳細はarm docsにあります。リセットや例外、ベクトルや割り込みなどの単語を探してください。テーブルが見つかります。これらのcortex-m mcusは、コアおよびチップベンダーに応じて最大128または256以上のベクトルを持つことができます。使用しているものより多く指定する必要はありません。スタックポインターWordを消費するもので逃げることができます。おそらくあなたが望むスタックポインタの初期化)そしてそれはあなた次第であるリセットベクトルを持っている必要があります、あなたはハードフォールトまたは未定義の命令パスを提供してはならず、それをコード、呼び出し、デバッグの真ん中に置きます。同時に、割り込み用のベクトルをセットアップする(貴重なフラッシュスペースを消費する)ことはできません...呼び出し、デバッグを有効にしません。

flash.ld

MEMORY
{
    rom : Origin = 0x08000000, LENGTH = 0x1000
    ram : Origin = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

(フラッシュ/ RAMの量がこの実際の部分を反映しないように、一般的な例/開始点をリサイクルします。必要に応じて調整します)。

点滅バージョンを変更して、フラッシュバージョンとsramバージョンの違いを確認します。

for(rx=0;;rx++)
{
    PUT32(GPIOCBASE+0x10,1<<(13+0));
    for(ra=0;ra<200000;ra++) dummy(ra);
    PUT32(GPIOCBASE+0x10,1<<(13+16));
    for(ra=0;ra<200000;ra++) dummy(ra);
}

建てる

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 -march=armv6-m -mthumb -c blinker01.c -o blinker01.o
arm-none-eabi-ld -o blinker01.elf -T flash.ld flash.o blinker01.o
arm-none-eabi-objdump -D blinker01.elf > blinker01.list
arm-none-eabi-objcopy blinker01.elf blinker01.bin -O binary

そして、エントリーポイントを検査する必要が非常にあります

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000041    stmdaeq r0, {r0, r6}
 8000008:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800000c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000010:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000014:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000018:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800001c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000020:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000024:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000028:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800002c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000030:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000034:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000038:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800003c:   08000047    stmdaeq r0, {r0, r1, r2, r6}

08000040 <reset>:
 8000040:   f000 f808   bl  8000054 <notmain>
 8000044:   e7ff        b.n 8000046 <hang>

08000046 <hang>:
 8000046:   e7fe        b.n 8000046 <hang>

スタックポインターの初期値(ベクターテーブルの逆アセンブリは、これらの単語の意味を理解しようとしている逆アセンブラーだけで偽です、値は逆アセンブリを無視することを気にするものです)、ベクトル、リセットベクトルは1つの0x08000040 | 1 = 0x08000041を使用してORREDをリセットすると、ブートすることを期待してはいけません。ブートローダーを他のアドレスにホッピングしている場合は、このコードで自分のものをオーリングする必要はありません。ツールを正しく追加し、アドレスを台無しにした場合は追加することを強くお勧めします。ツールが正しく機能し、それを台無しにした場合は機能しません。

今ここにこすり...

これらの青い錠剤のいくつかはフラッシュがロックされた状態で来ましたが、そこから抜け出すためのopenocd方法がありますが、どこで記録したかわかりません、それを処理するためにartベースのローダーを変更しました、別のことに注意してくださいあなたのバックポケットに、このデバイスや他のベンダーの膨大な数のMCUと同様に、このデバイスは、ブートローダーまたは他の非ジャジーな方法で回路内のチップに付属している可能性があり、そのインターフェース用のツールを構築するいくつかの試みを行いますいつかは専門的にする必要があるかもしれません。この場合、write unprotectコマンドは実際にドキュメントが示すことを実行せず、成功を返さず、チップの電源を再投入する必要がありますが、その後は保護されず、uartブートローダーベースのツールまたはswd(jtagのような)を使用できますこの部分に入るためのツール。

パーツ内のデバッガーに接続するためにopenocdを使用する前と同じ取引。

> halt
stm32f1x.cpu: target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x20000014 msp: 0x20000ff0
> flash write_image erase blinker01.elf 
auto erase enabled
device id = 0x20036410
flash size = 64kbytes
wrote 1024 bytes from file blinker01.elf in 0.437904s (2.284 KiB/s)
>

代わりにあなたが得るなら

stm32x device protected
failed erasing sectors 0 to 0

あなたの部分は書き込み保護されているので、それを理解する必要があります。見つかった場合はここに投稿しますが、手元にある部分が保護されていないため、テストできません。そして、誰かからこれらの青い錠剤を購入するときにあなたが見つけるかもしれないものを示すために、彼らが保護されていることを望んで、本当に少数の部品を買いに行きたくない。同時に、これを扱うこのボードのこれらの例の多くは見当たらないので、たぶんこれを行ったのはたった1つのバッチおよび/または1つのメーカーであり、自分とオンラインの別の人が偶然不運になりました。

この時点で次のことができます

> reset

または

両方のジャンパーが0側に移動した状態でリセットボタンを押します。これは、boot0とboot1が0にストラップされていることを示します(実際にはboot0が0になる必要があるだけです)。画像では、ジャンパーが1に設定されており、少なくともリセットボタンの横にないものを移動する必要があります。リセットボタンの横にあるものはboot1と見なされます。

そして、LEDはsramの例の2倍速く点滅するはずです。ボードの電源をオフにしてから再度オンにすると、boot0 = 0でフラッシュからこのプログラムの実行が開始されます。

純粋なアセンブリは、例のさらに単純なものでしたが、揮発性ポインタのトリックはわずかに単純でした。ただし、このコードを機能させることができない場合は、おそらくより複雑な機能を使用することはないでしょう。これは、可能な限り単純に近いものです。

繰り返しますが、これらの例は.dataをサポートしておらず、.bssがゼロであると仮定していないため、これらの仮定を許可するにはもう少しコードと知識が必要になります。個人的にはこれらに依存せず、bootstrapもリンカスクリプト(ツールチェーン固有であり、ポートはありません)ですが、それは個人的な好みです。

google stm32 blue pillとSTM32duinoなどのページを見つけて、それらの例を試してください。おそらく、mbedは別のサンドボックスをサポートしています。このサンドボックスはARMが購入またはサポートしているほか、stには少なくとも2つのフレーバーcmsisとレガシーのライブラリがあります。事業を行うチップベンダーはライブラリセットを持っていることが多く、マーケティングやその他の理由で、それらを継続的に解き放つため、HAL、CMSIS、キューブなど、今日存在するものの1つ、最終的にはすべてが存在することを期待していることに注意してくださいCMSISでさえ道を進んだのは、それが少し混乱していて、本当の中央所有者ではないからです。付与されたCMSISは進化する可能性がありますが、そのままの形で残ることを期待しないでください。同時に、この業界の仕組みは、比較的新しく、および/または製品の生産を希望している限り、製品の一部を購入することです。ファームウェアを作成/デバッグ/ビルドし、触れないでください。その日のポピュラー/ FADライブラリが何であっても使用できます。理想的には、将来使用するために今日からビルドマシンを保存してください。実稼働に十分な時間。 Do it Yourselfアプローチはメンテナンスがはるかに簡単です。gpio、spi、uartなどの単純なものはライブラリよりもIMOが簡単で、USB、イーサネットなどは周辺機器とのインターフェースではなくベンダーライブラリよりも難しいかもしれませんUSBスタック、イーサネットIPスタック、ファイルシステムのサポートが含まれます。これらは、周辺ライブラリのサポートに統合される可能性が高く、周辺ライブラリのコードを回避するために必ずしも分離する価値はありません。

最終的に、専門的には、ライブラリを含む使用するすべてのコードを所有していると想定する必要があります。上司は、製品ラインに障害が発生したことを確認するだけであり、選択したのがサードパーティのライブラリであることに気を付けません。

3
old_timer

開発キットをすでに購入している場合は、最初にユーザーズマニュアルを読み、サンプルアプリケーションを実行する手順を説明します。手順に従って、基本的なアプリケーションから始めます。コードを理解します。コードに基づいて、データシートを読んでIOおよびその他の内部がどのように機能するかを理解します。8051の経験があるため、最初はすべてを理解できないかもしれません。次のステップは、開発ボードでそれらを実行または練習してみながら、ニースアームのチュートリアル/本を読むことです。

1
Anjan Rao