Mündəricat:

Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Addım
Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Addım

Video: Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Addım

Video: Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Addım
Video: Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo 2024, Noyabr
Anonim
Image
Image

Bu Təlimatın fokusu STM32 Nucleo mikro nəzarətçisidir. Çılpaq sümüklərdən bir montaj layihəsi yarada bilmə motivasiyası. Bu, artıq bir neçə Təlimat mövzusu olan MSP432 Launchpad layihəsini (TI-RSLK) daha dərindən öyrənməyimizə və başa düşməyimizə kömək edəcək.

Code Composer Studio istifadə edərək MSP432 üçün yalnız montaj üçün bir layihə yaratmaq üçün İnternetdə çox kömək yoxdur. İndiyə qədər əvvəlcədən mövcud olan montaj layihəsindən yalnız kopyalayırıq/yapışdırırıq. Bu yanaşma bizə yaxşı xidmət etdi.

Bununla birlikdə, indi Lab 7 üçün bir az problemlə qarşılaşdıq. Və ya heç olmasa müvəqqəti bir hıçqırıq. Lab 7, sonlu vəziyyət maşınlarını təqdim edir və qarşılaşdığımız ilk şey bir sıra dəyərlər yaratmaq və istifadə etməkdir. TI kursu əsasən C proqramlaşdırmasından istifadə etdiyi üçün bu problem deyil. Ancaq bu təlimatlar C -yə deyil, montaja yönəlmişdir.

Üstəlik, dizi yalnız oxunan dəyərlər olduğundan, onu RAM-a deyil, flash yaddaşa qoymaq yaxşı olar.

STM32 MCU istifadə edərək montaj layihələri üçün onlayn olaraq daha çox kömək olduğu görünür, buna görə də öyrəndiklərimizdən istifadə edərək MSP432 və Code Composer Studio -ya müraciət etmək məqsədi ilə bu Təlimatla başlayırıq.

Bu hədəfə gedən yolda, başqa bir populyar mikro nəzarətçi ilə də təcrübə əldə edəcəyik.

Addım 1: Cihazın İlkin Testi

Cihazın İlkin Testi
Cihazın İlkin Testi
Cihazın İlkin Testi
Cihazın İlkin Testi
Cihazın İlkin Testi
Cihazın İlkin Testi

Yenə niyə STM32 Nucleo -nu seçirsiniz?

Vicdanla? Çünki ARM nəzarətçiləri üçün çılpaq metal montaj layihələri haqqında yaxşı məqalələr axtarırdım və bu seriyaya rast gəldim. Həm də STM32 -nin populyar bir MCU olduğu göründüyü üçün.

Bir az araşdırma apardım (seçim etmək üçün bir çox versiya var - yuxarıdakı şəklə baxın), amma nəticədə Amazondan (ABŞ -da) istifadə edəcəyim üçün əldə edə biləcəyim şey oldu.

Bəzi başlanğıc təlimatları ilə sadə, lakin peşəkar bir paketdə gəlir. Nəzarətçiyə yandırılan demonun demək olar ki, keçmiş Instructables -da etdiyimiz şey olduğunu görmək bir az gülməli idi - bir LED yanıb -sönür və bir düyməni basmaqla sürəti dəyişir.

Görünür ki, bu inkişaf lövhəsi 2 LED və bir istifadəçi düyməsinin olması ilə MSP432-yə çox bənzəyir. MSP432-də 2 istifadəçi düyməsi var.

Fotoşəkillərdə gördüyünüz kimi, lövhədə mikro USB yox, mini var deyə bir az təəccübləndim. Kabel almaq üçün tükənmək məcburiyyətində qaldım.

Başqa bir yaxşı sınaq, kompüterinizə bağladığınızda (Linux qutusu istifadə edirəm), fayl menecerimdə "NODE_F303RE" adlı bir fayl sistemi olaraq görünməsidir. Açılış, bir HTML və bir mətn olmaqla iki faylı göstərir.

İş budur, amma ən azından əlaqənin olduqca asan göründüyünü söyləyir.

İndi başlamağa hazırıq.

IVONOMICON Çılpaq Metal məqalələr seriyasından olan yaxşı məlumatların heç birini təkrarlamamağa çalışacağam, əksinə artırmağa çalışacağam.

Addım 2: Essentials

Ehtiyac duyduğumuz ilk şey kompilyatordur.

Və sonra, bir ayıklayıcıya ehtiyacımız var:

devchu@chubox: ~ $ sudo apt-get install gdb-arm-none-eabiRaket paketlərinin siyahılarını oxuyun… Tamamlandı Asılılıq ağacını qurmaq Vəziyyət məlumatlarını oxuyun… Bitti Aşağıdakı YENİ paketlər quraşdırılacaq: gdb-arm-none-eabi 0 təkmilləşdirildi, 1 yeni quraşdırılıb, silmək üçün 0, təkmilləşdirilməmiş 8. 2, 722 kB arxiv almaq lazımdır. Bu əməliyyatdan sonra 7, 738 kB əlavə disk sahəsi istifadə ediləcək. Alın: 1 https://us.archive.ubuntu.com/ubuntu xenial/Universe amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3+9 [2, 722 kB] 1 saniyədə 2, 722 kB əldə edildi (1, 988 kB/s) Əvvəllər seçilməmiş gdb-arm-none-eabi paketinin seçilməsi. (Verilənlər bazası oxunur… Hal-hazırda quraşdırılmış 262428 fayl və kataloqlar.) Açılmağa hazırlaşır…/gdb-arm-none-eabi_7.10-1ubuntu3+9_amd64.deb… gdb-arm-none-eabi (7.10-1ubuntu3+9) paketindən çıxarılır… İşlənilir man-db (2.7.5-1) üçün tetikleyiciler… gdb-arm-none-eabi (7.10-1ubuntu3+9) qurulması …

Addım 3: Essentials - Windows

Yuxarıdakı addım Linux istifadə etdiyimizi güman etdi. Windows istifadə etsək nə olar?

Arm Developer saytına gedə bilərsiniz və bir neçə yükləmə variantı mövcuddur. Windows 8 maşınından istifadə edirəm.

Quraşdırma zamanı, cygwin istifadə etdiyim üçün Proqram Faylları yerinə kök "C: \" sürücüsünə quraşdırmağı seçdim və yerli zibil qutumdan kök C: qovluğuna bir keçid yaratmaq daha asan oldu. Proqram Faylları yolunda qarışıqlıq (boşluqlarla və s.).

Beləliklə, cygwin mühitim və yolum və s. Belə görünür:

C: / cygwin64 / home / bin / arm-none-eabi-gcc, burada arm-none-eabi-gcc C: / GNUToolsArmEmbedded / 7.2018.q2.pdate / bin / arm-none-eabi- bağlantısıdır gcc.

Sonra cygwin home altında "dev" qovluğu yaratdım və core. S faylını yerləşdirdiyim və tərtibçi əmrini işlədiyim yer budur. (tərtibçi məlumatları üçün aşağıya baxın).

Gdb (arm-none-eabi-gdb) üçün də eyni şeyi etdim.

Addım 4: Əsaslar nələrdir

Bəs "gcc-arm-none-eabi" nədir?

Gnu tərtibçisi (GCC), işlədiyi maşın üçün proqramlaşdırma dillərini (C kimi) yerli kodda tərtib edəcək. Məsələn, Windows maşınınızda GCC istifadə edərək bir neçə C kodu tərtib etsəniz, Windows maşınında çalışmaq üçün qurulacaqdır. Yaradılan icra olunan fayl (adətən) ARM mikro nəzarətçisində işləməyəcək.

Beləliklə, ARM mikro nəzarətçisinə yüklənəcək və yandırılacaq proqramlar qurmaq üçün (indiki halda bu STM32 Nucelo olardı) GCC-yə başqa bir şey verməliyik: "çarpaz tərtib etmə" qabiliyyəti. Yəni, doğma sistemi (və prosessoru) üçün deyil, hədəf sistemi (ARM mikro nəzarətçisi) üçün icra edilə bilən bir fayl yaratmaq qabiliyyəti. "Gcc-arm-none-eabi" nin işə düşdüyü yer budur.

Bəs onda "gdb-arm-none-eabi" nədir?

Yeni yaradılan icra faylını mikro nəzarətçiyə yükləyib yandırdıqdan (yandırdıqdan) sonra, ehtimal ki, kodun sətir-satır xətasını düzəltmək istəyəcəyik. GDB, gnu ayıklayıcısıdır və öz işini yerinə yetirmək üçün başqa bir sistemi hədəf alması lazımdır.

Beləliklə, gdb-arm-none-eabi GDB üçün, gcc-arm-none-eabi GCC üçün nə deməkdir.

Başqa bir təklif olunan paket qurulması "libnewlib-arm-none-eabi" idi. O nədir?

Newlib, əlaqədar sistemlərdə istifadə üçün nəzərdə tutulmuş C kitabxanası və riyaziyyat kitabxanasıdır. Bir çox kitabxana hissələrinin birləşməsidir, hamısı pulsuz proqram lisenziyaları altında, onları gömülü məhsullarda asanlıqla istifadə etməyə imkan verir.

Və nəhayət, "libstdc ++-arm-none-eabi" paketi. Bu olduqca aydındır; cross-compiler üçün C ++ kitabxanasıdır; quraşdırılmış ARM mikro nəzarətçiləri üçün.

Addım 5: Bağlayıcı Fayl

Bağlayıcı Fayl
Bağlayıcı Fayl
Bağlayıcı Fayl
Bağlayıcı Fayl

Bir bağlayıcı skript yaradaq.

Bu fayldakı bir əsas hissə və ya blok MEMORY əmri olacaq.

--- sourceware.org saytından:

Bağlayıcının standart konfiqurasiyası bütün mövcud yaddaşın ayrılmasına icazə verir. MEMORY əmrini istifadə edərək bunu ləğv edə bilərsiniz. MEMORY əmri hədəfdəki yaddaş bloklarının yerini və ölçüsünü təsvir edir. Bağlayıcı tərəfindən hansı yaddaş bölgələrinin istifadə edilə biləcəyini və hansı yaddaş bölgələrindən çəkinməli olduğunu izah etmək üçün istifadə edə bilərsiniz. Daha sonra xüsusi yaddaş bölgələrinə bölmələr təyin edə bilərsiniz. Bağlayıcı, yaddaş bölgələrinə əsaslanaraq bölmə ünvanlarını təyin edəcək və çox dolu olan bölgələr haqqında xəbərdarlıq edəcək. Bağlayıcı, mövcud bölgələrə uyğunlaşmaq üçün ətrafdakı bölmələri qarışdırmayacaq. Bağlayıcı skript MEMORY əmrinin bir çox istifadəsini ehtiva edə bilər, lakin müəyyən edilmiş bütün yaddaş blokları sanki bir MEMORY əmrində göstərildiyi kimi qəbul edilir.:

YADDAŞ

{ad [(attr)]: ORIGIN = mənşə, LENGTH = len…}

Məqalədə nümunə:

/* RAM sonunu və yığın yaddaşının limitini təyin edin* //* (STM32F031x6 xəttində 4KB SRAM, 4096 = 0x1000)*//* (RAM 0x20000000 ünvanından başlayır) _estack = 0x20001000;

YADDAŞ

{FLASH (rx): ORIGIN = 0x08000000, LENGTH = 32K RAM (rxw): ORIGIN = 0x20000000, LENGTH = 4K}

Beləliklə, xüsusi lövhəmiz üçün nə qədər FLASH (proqramımız və sabitlərimiz üçün) və nə qədər RAM (proqramın istifadəsi üçün; yığın və yığın və s.) Bu bir az maraqlı gəlir.

Nucleo ilə birlikdə gələn gözəl kart, flash yaddaşının 512 Kbayt, SRAM -ın isə 80 Kbayt olduğunu söyləyir. Bununla birlikdə, onu USB -yə bağlayaraq iki fayllı bir fayl sistemi olaraq quraşdırılır və həm fayl meneceri, həm də GParted, 540+ Kbaytdan çox yer tutduğunu göstərir. (RAM?).

AMMA, fayl menecerindən istifadə edərək iki faylı silməyə çalışarkən, cihazı ayırıb sonra yenidən bağlayaraq yenə də iki faylı göstərir. (və fayl meneceri bir şeyi tanıdı, çünki hər bir faylda kiçik bir "kilid" işarəsi var.

Beləliklə, kartdakı rəqəmlərlə gedək. Beləliklə, indi yuxarıdakı nümunəni götürüb xüsusi lövhəmizə çeviririk.

Ümumi KB -dən müəyyən bayt sayına keçmək üçün bu onlayn yaddaş çeviricisi kimi bir şey istifadə etmək istəyə bilərsiniz.

Sonra onlayn onluqdan hex çeviricisindən istifadə etmək istəyə bilərsiniz.

/ * RAM sonunu və yığma yaddaşının limitini təyin edin */

/* (STM32F031x6 xəttində 4KB SRAM, 4096 = 0x1000)* //* nümunə*/

/ * addım 1: (STM32F303RE -də 80KB SRAM, 81920 = 0x14000) * // * lövhəmiz */

/* addım 2, hex ölçüsünü hex başlanğıc ünvanına əlavə edin (aşağıda). */

/ * (RAM 0x20000000 ünvanından başlayır) */

_estack = 0x20001000; / * nümunə */

_estack = 0x20014000; / * lövhəmiz */

Xatirə {

FLASH (rx): ORIGIN = 0x08000000, LENGTH = 512K

RAM (rxw): ORIGIN = 0x20000000, LENGTH = 80K

}

Yuxarıdakı fayla "linker.script.ld" deyək.

Addım 6: Vektor Cədvəli

Vektor cədvəli
Vektor cədvəli

İndi çox əsas kəsilmə işlərini yerinə yetirmək üçün kiçik bir montaj faylı (direktivlərlə) yaradacağıq. Məqalənin nümunəsini izləyəcəyik və "core. S" adlı bir fayl yaradacağıq.

Yenə də nümunə fayl məzmunu budur, ancaq xüsusi lövhəmiz üçün bir dəyişiklik etdim:

// Bu təlimatlar çipimizin xüsusiyyətlərini və

// istifadə edəcəyimiz montaj dili:.syntax vahid /*Bu kod sahəsindən sonra aşağıya baxın* //*.cpu cortex-m0* / /*misalın bu sətrini şərh edin* /.cpu cortex-m4 /* lövhəmizin qabığını əlavə edin. bu addımda yuxarıdakı görüntüyə baxın * / /*.fpu softvfp * / / *misalın bu sətrini şərh edin * /.fpu vfpv4 / *əvəzinə lövhəmizi əlavə edin; bir FPU */.thumb // Qlobal yaddaş yerləri var..global vtable.global reset_handler / * * Həqiqi vektor cədvəli. * Sadəcə RAM ölçüsü və 'sıfırlama' işləyicisi * sadəliyə görə daxil edilmişdir. */.type vtable, %object vtable:.word _estack.word reset_handler. size vtable,.-vtable

Hmm.. Xeyr.hazırlama 'Direktivi

Ancaq bu kritik deyil. Bu barədə daha sonra (bəlkə də).

.syntax vahid

.syntax [vahid | bölünmüş]

Bu direktiv, ARM-Instruction-Set bölməsində göstərildiyi kimi Instruction Set Sintaksisini təyin edir

9.4.2.1 Təlimat Set Sintaksisi İki fərqli sintaksis ARM və THUMB təlimatlarını dəstəkləyir. Varsayılan, bölünmüş, ARM və THUMB təlimatlarının öz ayrı sintaksislərinin olduğu köhnə üslubdan istifadə edir.. Syntax direktivi vasitəsilə seçilə bilən yeni, vahid sintaksis.

.fpu vfpv4

GCC tərtibçisi üzən nöqtə ilə bağlı bir neçə variantla ikili fayllar istehsal edə bilər: yumşaq - FPU olmadan CPU -da çalışmaq üçün uyğundur - hesablamalar kompilyator tərəfindən yaradılan softfp proqramında aparılır - FPU ilə və ya olmadan CPU -da çalışmaq üçün əlverişlidir - əgər varsa FPU istifadə edəcək. Xüsusi vəziyyətimiz üçün (öz araşdırmanızı etməlisiniz), bu xüsusi lövhənin FPU vfpv4 -ə uyğundur. Bununla oynaya bilərsən. Və ya hətta softfp -də buraxın.

.barmaq (qola qarşı)

Bu ARM mikrokontrolörünün əslində bir çox təlimat dəsti var. Biri ARM, digəri isə THUMB. Bir fərq, 16 bit təlimatla 32 bit təlimatdır. Beləliklə, bu təlimat tərtibçiyə sonrakı təlimatlara ya THUMB, ya da ARM kimi baxmağı söyləyir.

Faylın qalan hissəsini olduğu kimi götürəcəyik, çünki bu Təlimatlar hələ də fasilə ilə idarə olunan montaj proqramlaşdırma sisteminə girməmişdir.

Addım 7: 'Hello World' Proqramının Məclis Versiyası

Aşağıdakılar əvvəllər yaradılmış "core. S" faylına da daxil ola bilər. Bu, yenə də məqalədəki nümunədəndir.

/ * * Sıfırlama işçisi. Sıfırlama çağırıldı. */.tip reset_handler, %function reset_handler: // Yığın göstəricisini yığının sonuna təyin edin. // '_estack' dəyəri bağlayıcı skriptimizdə müəyyən edilmişdir. LDR r0, = _estack MOV sp, r0

// Bəzi saxta dəyərlər təyin edin. Bu dəyərləri görəndə

// ayıklayıcımızda, proqramımızın // çipə yükləndiyini və işlədiyini biləcəyik. LDR r7, = 0xDEADBEEF MOVS r0, #0 main_loop: // 'r0' qeyd etmək üçün 1 əlavə edin. ADDS r0, r0, #1 // Geri dön. B main_loop.size sıfırlama_handler,.-Sıfırlama_handler

Beləliklə, yuxarıdakı proqramın məqsədi tək nüvəli MCU reyestrinə (bu halda R7) tanına bilən bir nümunə yükləmək və sıfırdan başlayan artan dəyəri başqa bir əsas MCU reyestrinə (bu halda R0) yükləməkdir. İcra kodunu keçsək, R0 -un məlumat artımını görməliyik.

Əgər MSP432 və TI-RSLK kursları/laboratoriyaları ilə əlaqədar Təlimatlarla birlikdə izləmisinizsə, demək olar ki, yuxarıdakı proqramların hamısı sizə tanış olmalıdır.

Gördüyüm yeni bir şey, R7 -ni qeyd etmək üçün "DEADBEEF" yükləyərkən "=" istifadə edilməsidir. Biz bundan istifadə etməmişdik.

Burada əlavə olunan "core. S" faylı artıq tam mənbəni ehtiva edir.

Addım 8: Kodun tərtib edilməsi

Bəzi əmr satırı işlərinin vaxtı gəldi. Nəhayət, real bir şey.

Halbuki, tam olaraq orada deyilik. Yenə də məqalədə verilən əmri dəyişdirməliyik və öz vəziyyətimizə uyğun olaraq dəyişdirməliyik.

İşdə nümunə kod:

arm -none -eabi -gcc -x -cpp -c -0 -assembler -cp -c -O0 -mcpu = cortex -m0 -mthumb -Wall core. S -o core.o

GCC üçün gnu.org saytına daxil olsaq, (bu halda versiya 7.3),

x

-X dili təyin etməkdir. Əks halda -x yoxdursa, tərtibçi fayl uzantısını istifadə edərək təxmin etməyə çalışacaq. (bizim vəziyyətimizdə *. S).

Məqalədəki yuxarıdakı nümunə cps ilə assembler təyin edir, ancaq montajçı edə bilərik.

c

-C deyir tərtib et, amma əlaqələndirmə.

O0

-O optimallaşdırma səviyyəsini təyin etməkdir. -O0 (oh -sıfır) istifadə edərək "tərtib müddətini azaldın və hata ayıklamanın gözlənilən nəticələr çıxarmasını təmin edin. Bu standartdır" deyir.

mcpu = korteks-m0

-Mcpu, hədəf prosessorun adını təyin edir. Bizim vəziyyətimizdə cortex-m4 olardı.

ayaq barmağı

-Mthumb, ARM və THUMB vəziyyətlərini icra edən kod yaratmaq arasında seçim etməyi təyin edir.

Divar

-Wall, əlbəttə ki, çox yayılmışdır və tanınır. Bütün xəbərdarlıq bayraqlarını yandırır.

Nəhayət, əmrin sonunda giriş faylı core. S və çıxış faylı core.o.

Xüsusi vəziyyətimizə uyğun olaraq ortaya çıxan yeni əmr xətti.

arm -none -eabi -gcc -x assembler -c -O0 -mcpu = cortex -m4 -mthumb -Wall core. S -o core.o

Və bu tərtib edildi.

Addım 9: Proqramı əlaqələndirin

Məqalədəki nümunədən birbaşa bunu əldə edirik:

arm -none -eabi -gcc core.o -mcpu = cortex -m0 -mthumb -Wall --specs = nosys.specs -nostdlib -lgcc -T./STM32F031K6T6.ld -o main.elf

Yuxarıda göstərilənlərin çoxunu gördünüz. Yeniliklər aşağıda verilmişdir.

specs = nosys.specs

Bunu izah etmək bir az çətindir.

"Semihosting" və "retargeting" ilə əlaqədardır və giriş / çıxışla əlaqəlidir. Sistem zəngləri və kitabxanalarla da əlaqəlidir.

Tipik olaraq, quraşdırılmış sistemlər standart giriş/çıxış cihazları təmin etmir. Bu sistem və ya kitabxana zənglərinə təsir edər (məsələn: printf ()).

Semihosting, hata ayıklayıcının (qırmızı ilə çevrilmiş hata ayıklayıcı hissəsi olan 11 -ci addıma baxın) xüsusi bir kanala sahib olduğunu və semihosting protokolundan istifadə etdiyini bildirir və ana maşındakı printf () çıxışını (ayıklayıcı vasitəsilə) görə bilərsiniz.

Yenidən təyin etmək, eyni sistem və ya kitabxana zənglərinin başqa bir şey ifadə etməsi deməkdir. Başqa bir şey edirlər ki, bu da gömülü sistem üçün məntiqlidir. Bir mənada, printf () üçün deyin, bu funksiyanın yeni bir tətbiqi, yenidən hədəflənmiş bir tətbiqi var.

Bütün bunları söylədikdən sonra --specs = nosys.specs semihosting etməyəcəyimiz deməkdir. Normalda bu, yenidən hədəf aldığımız anlamına gəlir. Bu bizi növbəti bayrağa aparır.

nostdlib

Bağlayıcı seçimi -nostdlib, müstəqil olaraq işləmək üçün hazırlanmış bir proqramı bağlamaq üçün istifadə olunur. -nostdlib fərdi seçimləri nəzərdə tutur -nodefaultlibs və -nostartfiles. Aşağıda iki variantı ayrıca müzakirə edirik, lakin ən tipik istifadə yalnız birdəfəlik alış-veriş üçün nostdlib-dir. Ev sahibi bir proqramı bağlayarkən libc kimi standart sistem kitabxanaları standart olaraq proqrama bütün standart funksiyalara (printf, strlen və dostlar). Bağlayıcı seçimi -nodefaultlibs, bu standart kitabxanalarla əlaqəni aradan qaldırır; əlaqələndirilən yeganə kitabxanalar, -l bayrağından istifadə edərək bağlayıcıya açıq şəkildə adlandırdığınız kitablardır.

lgcc

libgcc.a, müəyyən maşınların çatışmazlıqlarını aradan qaldırmaq üçün daxili proqramları təmin edən standart bir kitabxanadır. Məsələn, ARM prosessorunda bölmə təlimatı yoxdur. Libgcc.a -nın ARM versiyası bir bölmə funksiyasını ehtiva edir və lazım olduqda kompilyator bu funksiyaya zənglər göndərir.

T

Bu, bağlayıcıya bu faylı bağlayıcı skript olaraq istifadə etməsini söyləməyin bir yoludur. Bizim vəziyyətimizdə fayl adı linker.script.ld -dir.

əsas. özüm

Nəhayət, əlaqələndiriciyə cihazımıza yandırılacaq/yandırılacaq son çıxış görüntü faylının adının nə olacağını söyləyirik.

Xüsusi vəziyyətimiz üçün dəyişdirilmiş tam komanda xəttinin versiyası budur:

arm -none -eabi -gcc core.o -mcpu = cortex -m4 -mthumb -Wall --specs = nosys.specs -nostdlib -lgcc -T./linker.script.ld -o main.elf

Skript faylının və core.o faylının yuxarıdakı əmr satırını işlədəcəyimiz eyni qovluqda olduğundan əminik.

Və heç bir problem olmadan bağlanır.

Bir çek

Sonra qaçırıq:

qol-heç-eabi-nm main.elf

və əldə edirik:

devchu@chubox: ~/Development/Atollic/TrueSTUDIO/STM32_workspace_9.1 $ arm-none-eabi-nm main.elf 20014000 A _estack 08000010 t main_loop 08000008 T reset_handler 08000000 T vtable

Yaxşı görünür. Arm-none-eabi-nm əmri, obyekt sənədlərindəki simvolları sadalamağın bir yoludur.

Addım 10: STM32 Nucleo-64-ə TestingConnection

STM32 Nucleo-64-ə qoşulma testi
STM32 Nucleo-64-ə qoşulma testi
STM32 Nucleo-64-ə qoşulma testi
STM32 Nucleo-64-ə qoşulma testi

Qəbul etməyi seçsəniz, ilk missiyanız, sisteminizin inkişaf lövhənizi görməsini təmin etməkdir.

Windows istifadə

Windows üçün TrueSTUDIO -nu Atollic -dən (pulsuz versiya) quraşdırmağa qərar verdim. Ağrısız bir quraşdırma idi və sürücünü avtomatik olaraq quraşdırdı ki, əlaqəni yoxlamaq üçün st-linkdən istifadə edim. TrueSTUDIO qurduqdan və cihaz meneceri cihazı gördükdən sonra, izlədiyimiz Bare Metal məqaləsinin təklif etdiyi texan/stlink alətlərini yüklədim. Yenidən qovluğu birbaşa "C: \" altına qoydum və yenidən yerli cygwin ev qutumdan əmrlərə bəzi bağlantılar yaratdım.

ln -s /c/STM32. MCU/stlink-1.3.0-win64/bin/st-info.exe ~/bin/st-info

Cihazla həqiqətən ünsiyyət qura biləcəyimizi görmək üçün ilk sınaq olaraq qaçdım:

st-info-prob

Və geri qayıtdı:

1 stlink proqramçı tapıldı

İndi bilirik ki, inkişaf lövhəmizi danışa/sorğu edə bilərik.

Linux istifadə

Linux üçün həqiqətən sürücüyə ehtiyacınız yoxdur. Ancaq Debian üçün st alətlərini mənbədən qurmalı olacaqsınız.

git klonu

Libusb-1.0-0-dev quraşdırdığınızdan əmin olun.

uyğun siyahı | grep -E "*libusb.*dev*"

Görməlisiniz:

libusb-1.0-0-dev/xenial, indi 2: 1.0.20-1 amd64 [quraşdırılmış]

və ya buna bənzər bir şey.

Quraşdırmaq üçün:

sudo apt-get libusb-1.0-0-dev quraşdırın

Qeyd edək ki, yuxarıda göstərilənlər eyni deyil:

sudo apt-get libusb-dev quraşdırın

Düzgün itkin libusb dev cmake -də problemlərə səbəb ola bilər.

CMake Error: Bu layihədə aşağıdakı dəyişənlər istifadə olunur, lakin NOTFOUND olaraq təyin olunur. Zəhmət olmasa bunları təyin edin və ya CMake fayllarında düzgün qurulduğundan və sınaqdan keçirildiyindən əmin olun: LIBUSB_INCLUDE_DIR (ADVANCED)

Layihənin kök qovluğuna keçin (… blah /blah /stlink). "Sərbəst buraxın" edin.

Bundan sonra alətlər ".. /build /Release" altında olmalıdır.

Daha sonra "st-info --probe" işlədə bilərsiniz. Burada Nucleo ilə bağlı çıxış var, sonra yox.

devchu@chubox: ~/Development/stlink $./build/Release/st-info --probeFound 1 stlink proqramçılarının seriyası: 303636414646353034393535363537 openocd: "\ x30 / x36 / x36 / x41 / x46 / x46 / x35 / x30 / x34 / x39 / x35 / x35 / x36 / x35 / x37 "flaş: 524288 (səhifə ölçüsü: 2048) sram: 65536 çip: 0x0446 təsvir: F303 yüksək sıxlıqlı cihaz devchu@chubox: ~/Development/stlink $./build/Release/st- info --probe tapıldı 0 stlink proqramçıları devchu@chubox: ~/Development/stlink $

Addım 11: Linux ilə GDB istifadə edək

Linux ilə GDB istifadə edək
Linux ilə GDB istifadə edək
Linux ilə GDB istifadə edək
Linux ilə GDB istifadə edək

Bütün bunları sınamış olsanız və bu yerə qədər çatmısınızsa - əla! Əla. İndi bir az əylənək.

Bu ARM inkişaf lövhələrini satın aldığınız zaman, istər Texas Instruments-dan MSP432 Launchpad olsun, istərsə də indi müzakirə etdiyimiz Nucleo-F303 (STM32 Nucleo-64), ümumiyyətlə işləyən bir proqramla yanıb-sönürlər. LED -lərin yanıb -sönmə sürətini dəyişdirmək üçün bir düyməyə basmağı da ehtiva edən bəzi yanıb -sönən proqramlar.

Həddindən artıq yazmağa tələsməzdən əvvəl, görək və edəcəyimiz şeyi görək.

Linux ilə bir terminal açın, yeni qurduğumuz stlink git proyektini dəyişdirin və st-util alətini tapın.

devchu@chubox: ~/Development/stlink $ find. -st-util adı

./build/Release/src/gdbserver/st-util

Bu aləti işə salın. St-info-prob ilə əlaqəmizi əvvəllər sınaqdan keçirdiyimiz üçün belə bir nəticə əldə etməliyik:

devchu@chubox: ~/İnkişaf/stlink $./build/Release/src/gdbserver/st-util

st-util 1.4.0-50-g7fafee2 2018-10-20T18: 33: 23 INFO common.c: Cihaz parametrləri yüklənir…. 2018-10-20T18: 33: 23 BİLGİ ümumi: 2048 baytlıq səhifələrdə 0x80000 bayt (512 KiB) 2018-10-20T18: 33: 23 INFO gdb-server.c: Çip ID-si 00000446, Əsas ID-si 2ba01477-dir. 2018-10-20T18: 33: 23 INFO gdb-server.c: *: 4242 ünvanında dinlənir…

İndi işləyən GDB serveridir və inkişaf lövhəmizi görür və daha da əhəmiyyətlisi 4242 portunu (standart port) dinləyir.

İndi GDB müştərisini işə salmağa hazırıq.

Linux -da başqa bir terminal açın, bunu daxil edin:

qol-heç-eabi-gdb -tui

Bu, gdb-nin ciddi şəkildə əmr satırını işə salmaqla eynidir, lakin bunun əvəzinə mətn əsaslı bir terminal istehsal edir (təxminim budur ki, lənətlərdən istifadə edir).

GDB müştəri və GDB serverimiz var. Lakin müştəri serverə qoşulmayıb. Hal -hazırda bizim Nucleo (və ya seçdiyiniz lövhə) haqqında heç nə bilmir. Bunu deməliyik. Terminalda istəyiniz indi "(gdb)" olmalıdır. Daxil edin:

hədəfə kömək edin

Sizə bir siyahı verəcək. Diqqət yetirin ki, istədiyimiz uzadılmış uzaq hədəfdir - Uzaq bir kompüterdən serial xətti ilə istifadə edin.

Amma biz də onun yerini bildirməliyik. Beləliklə, (gdb) istəyində daxil edin:

(gdb) hədəf uzadılmış uzaq localhost: 4242

Belə bir cavabı geri qaytarmalısınız:

(gdb) hədəf uzadılmış uzaq localhost: 4242

Localhost istifadə edərək uzaqdan ayıklama: 4242 0x080028e4 in ?? ()

Bu vaxt, st-util gdbserver işləyən terminalda bunu əldə etdik:

2018-10-20T18: 42: 30 INFO gdb-server.c: 6 hw dayanma nöqtəsi tapıldı

2018-10-20T18: 42: 30 INFO gdb-server.c: GDB bağlıdır.

Addım 12: Proqramı Windows və Flash ilə təkrarlayaq

Windows və Flash ilə Proqramımızı Yenidən Təkrarlayaq
Windows və Flash ilə Proqramımızı Yenidən Təkrarlayaq
Windows və Flash ilə Proqramımızı Yenidən Təkrarlayaq
Windows və Flash ilə Proqramımızı Yenidən Təkrarlayaq
Windows və Flash ilə Proqramımızı Yenidən Təkrarlayaq
Windows və Flash ilə Proqramımızı Yenidən Təkrarlayaq

St-util gdbserver və arm-none-eabi-gdb müştərisini işə salmaq üçün addımlar, əvvəlki addımda etdiyimiz kimidir. İki terminal açırsınız (cygwin, DOS cmd və ya Windows Powershell), st-utilın yerini tapın, işə salın. Digər terminalda, arm-none-eabi-gdb müştərisini işə salın. Yeganə fərq, -tui (terminal əsaslı mətn görünüşü) rejiminin çox güman ki, dəstəklənməməsidir.

Yuxarıda göstərilənlər Windows -da işləyirsə, çox güman ki, dayandırmalı olacaqsınız (yalnız müştəri). Bu nöqtədə, bir şəkildə qurma faylınızın olduğu GDB müştərisini işə salmalısınız ("core.out") və ya bütün faylı GDB müştərisinə arqument olaraq əlavə edin.

Cygwin istifadə edərək və yerli $ HOME // bin qovluğumdan hər iki vasitənin yerləşdiyi yerə bağlantılar yaradaraq həyatımı asanlaşdırdım.

Tamam, əvvəlki kimi tərtib etdik və əlaqələndirdik və main.elf faylını işıqlandırmağa hazırıq.

Bir pəncərədə çalışan st-util var. GDB müştərisini yenidən başladıq, bu dəfə bunu edirik:

qol-heç-eabi-gdb main.elf

Başlamasına icazə verdik, (gdb) istəməsini gözləyin, eyni əlaqə əmrimizi GDB serverinə (st-util) edin və icra olunan faylları yanıb-sönməyə hazırıq. Çox iqlim əleyhinədir:

(gdb) yük

Cygwin terminalları ilə işləyərkən, bəzən konsol əmrlərinin çıxmadığı bilinən bir problem var. Beləliklə, bizim vəziyyətimizdə, serverin işlədiyi pəncərə tamamilə səssiz idi. Yükü idarə etdiyimiz müştəri işləyən, bunu çıxarır:

Bölmə yüklənir.mətn, ölçü 0x1c lma 0x8000000Başlangıç ünvanı 0x8000000, yük ölçüsü 28 Transfer sürəti: 1 KB/san, 28 bayt/yaz.

Addım 13: Linux ilə yanıb -sönmək - daha çox mükafatlandırma: D

Linux ilə yanıb -sönən - daha çox mükafat: D
Linux ilə yanıb -sönən - daha çox mükafat: D

Addım 14: Biraz daha dərinə dalaq

Bura gəlsəniz əla. Davam edək.

Niyə main.elf faylının içərisinə, icra olunan faylına baxmırsınız? Aşağıdakıları işə salın:

qol-heç-eabi-objdump -d main.elf

Bu kimi bir çıxış görməlisiniz:

main.elf: fayl formatı elf32-littlearm

Bölmənin sökülməsi. Mətn:

08000000:

8000000: 00 40 01 20 09 00 00 08.@. ….

08000008:

8000008: 4802 ldr r0, [pc, #8]; (8000014) 800000a: 4685 mov sp, r0 800000c: 4f02 ldr r7, [pc, #8]; (8000018) 800000e: 2000 film r0, #0

08000010:

8000010: 3001 r0, #1 əlavə edir 8000012: e7fd b.n 8000010 8000014: 20014000. Söz 0x20014000 8000018: ölü dana. Söz 0xdeadbeef

Yuxarıdakı çıxışdan hansı kiçik külçələr əldə edə bilərik?

Linker.script.ld faylını müzakirə edərkən və yaratarkən xatırlayırsınızsa, bu ARM cihazlarının 0x20000000 -dən başlayan RAM -a sahib olduğunu və FLASH yaddaşının 0x08000000 -dən başladığını bildirmişdik.

Beləliklə, həqiqətən proqramın hamısının FLASH yaddaşında yerləşdiyini görə bilərik.

Daha sonra, yuxarıda, amma daha sonrakı bir addım, "Hello World" hissəsini müzakirə edərkən, dərhal, sabit, hərfi dəyəri ("0xDEADBEEF") bir MCU əsas qeydinə ("R7") yüklədiyimiz bir bəyanat var idi.

Açıqlama belə idi:

LDR R7, = 0xDEADBEEF

Kodumuzda, DEADBEEF -dən bəhs etdiyimiz yeganə yer budur. Başqa yerdə yox. Yenə də yuxarıdakı sökülmüş/yenidən qurulmuş təlimatlara və s.

Beləliklə, tərtibçi/bağlayıcı bir şəkildə DEADBEEF dəyərini 0x8000018 yerindəki bir FLASH ünvanına daimi olaraq silmək qərarına gəldi. Və sonra tərtibçi yuxarıdakı LDR təlimatımızı dəyişdirdi:

LDR R7, [PC, #8]

Hətta bizim üçün bir şərh də yaratdı. Necə də gözəl. Və bizə cari proqram sayğacının dəyərini (PC reyestri) götürməyimizi, bu dəyərə 0x8 əlavə etməyimizi və DEADBEEF -in yandırıldığını və bu dəyəri əldə edib R7 -də doldurmağımızı söyləyir.

Bu, eyni zamanda proqram sayğacının (PC) main_loopun başlanğıcı olan 0x8000010 ünvanını göstərdiyini və DEADBEEF dəyərinin main_loop bitdikdən sonra iki ünvanda yerləşdiyini bildirir.

Addım 15: Nəhayət, Çalışan Proqrama Qısaca Baxış

GDB-dən çıxsanız da, əmri yenidən daxil edin. Hətta ona heç bir fayl vermək lazım deyil; artıq yanıb -sönmürük, sadəcə çalışırıq.

GDB müştərisini GDB serverinə yenidən bağladıqdan sonra (gdb) əmr satırında:

(gdb) məlumat qeydləri

Bənzər bir şey görməlisiniz:

r0 0x0 0

r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 sp 0x20014000 0x20014000 lr 0xffff00000 cx 0 0 x 0 0 x0 0 r0 0 x0 0

Ancaq sonra (gdb) istəyində daxil edin:

(gdb) davam edin

Və çox tez CTRL-C vurun. Bu, proqramı dayandırmalıdır. Yenidən "məlumat qeydləri" əmrini daxil edin.

Bu dəfə fərqli görünür:

(gdb) məlumat qeydləri

r0 0x350ffa 3477498 r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0xdeadbeef 3735928559 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0x00 0x00 0x1200x1200x1200 16777216

Nə olub? Tam olaraq istədiyimiz şey. DEADBEEF R7 -yə yükləndi və R0 (son dərəcə sürətli) artdı. Təkrar etsəniz, başqa bir dəyərlə yenidən R0 görəcəksiniz.

Addım 16: Flash-da Yalnız Oxunan Array Yaratmaq İstədik

Montaj və direktivlərdən istifadə edərək bir sıra ekvivalenti yaratmağın bir yolu aşağıdakı kimidir:

.type myarray, %object // adı və ya etiketi 'myarray' bir obyekt növü olaraq təyin olunur.

myarray: // bu 'myarray' elanının başlanğıcıdır // (nədən ibarət olacaq)..word 0x11111111 // 'myarray' da olan ilk üzv və ya dəyər..word 0x22222222 // ikinci dəyər (bitişik ünvanlar).. söz 0x33333333 // və s..size myarray,.-myarray // tərtibçi/assembler artıq 'myarray' ın sonunu və ya // sərhədini bilir.

İndi FLASH yaddaşına qurduqdan sonra proqramda istifadə edə bilərik. Aşağıda bir hissə var:

LDR R1, myarray // bu, 'myarray' ın 1 -ci yerində olan məlumatları yükləyir. ' // bu bizim istədiyimiz deyil.

LDR R1, = myarray // bu, yer dəyərinin özünü yükləyir (1 -ci ünvan), // məlumat deyil.. // istədiyimiz budur.

MOV R2, #0 // R2, getmədiyimizə əmin olmaq üçün sayacaq

// massivin sonu. LDR R3, = myarrsize // R3 'myarrsize' ekvivalenti olacaq.

// R0 məlumatlarımızı saxlayacaq

main_loop:

LDR R0, [R1] // R1 ('myarray') tərəfindən göstərilən məlumatları R0 -a yükləyin. CMP R2, R3 // Array limitindəyik? BEQ main_loop // Əgər olsaq, işimiz bitdi, buna görə də sonsuza qədər dönəcəyik.

ADD R2, #1 // Əks təqdirdə, serial vasitəsilə təkrarlanmağa davam edə bilərik.

R1, #4 ƏLAVƏ EDİN // R1 -i qeyd etmək üçün 4 əlavə edin, buna görə də sonrakı işarəyə düzgün işarə edir

// ünvan..

B main_loop // Geri dön.

Video bütün bunları keçir və içərisində bir səhv var. Bu yaxşıdır; işləmə və ayıklama kodunun vacib olduğunu göstərir. Klassik bir serialın sonundan çıxma halını göstərir.

Tövsiyə: