विषयसूची:

भाग 1 एआरएम असेंबली टीआई आरएसएलके रोबोटिक्स लर्निंग करिकुलम लैब 7 एसटीएम 32 न्यूक्लियो: 16 चरण
भाग 1 एआरएम असेंबली टीआई आरएसएलके रोबोटिक्स लर्निंग करिकुलम लैब 7 एसटीएम 32 न्यूक्लियो: 16 चरण

वीडियो: भाग 1 एआरएम असेंबली टीआई आरएसएलके रोबोटिक्स लर्निंग करिकुलम लैब 7 एसटीएम 32 न्यूक्लियो: 16 चरण

वीडियो: भाग 1 एआरएम असेंबली टीआई आरएसएलके रोबोटिक्स लर्निंग करिकुलम लैब 7 एसटीएम 32 न्यूक्लियो: 16 चरण
वीडियो: 【Multi Sub】《最强反套路系统》第1~87集 | 穿越者徐缺踏上了一条套路之路,每天不是在套路,就是正在去套路的路上!套路横扫修仙界,就问一声还有谁?!#热血 #穿越 #修仙 #逆袭 2024, जुलाई
Anonim
Image
Image

इस निर्देश का फोकस STM32 न्यूक्लियो माइक्रो-कंट्रोलर है। इसके लिए प्रेरणा नंगे हड्डियों से असेंबली प्रोजेक्ट बनाने में सक्षम होना। यह हमें MSP432 लॉन्चपैड प्रोजेक्ट (TI-RSLK) को गहराई से समझने और समझने में मदद करेगा जो पहले से ही कई इंस्ट्रक्शंस का विषय रहा है।

कोड कम्पोज़र स्टूडियो का उपयोग करके MSP432 के लिए केवल-असेंबली प्रोजेक्ट बनाने के लिए ऑनलाइन बहुत अधिक मदद नहीं है। अब तक हम पहले से मौजूद असेंबली प्रोजेक्ट से सिर्फ कॉपी/पेस्ट कर रहे हैं। इस दृष्टिकोण ने हमारी अच्छी सेवा की है।

हालाँकि, अब, लैब 7 के लिए, हम थोड़ी समस्या में पड़ गए हैं। या कम से कम एक अस्थायी हिचकी। लैब 7 परिमित-राज्य-मशीनों का परिचय देता है, और पहली चीज जो हमें मिलती है वह है मूल्यों की एक सरणी बनाने और उपयोग करने की आवश्यकता। चूंकि TI पाठ्यक्रम मुख्य रूप से C प्रोग्रामिंग का उपयोग करता है - यह कोई समस्या नहीं है। लेकिन इन इंस्ट्रक्शंस ने असेंबली पर ध्यान केंद्रित किया है, सी पर नहीं।

इसके अलावा, चूंकि सरणी केवल-पढ़ने के लिए है, इसे फ्लैश मेमोरी में रखना अच्छा होगा, रैम नहीं।

एसटीएम 32 एमसीयू का उपयोग करके असेंबली परियोजनाओं के लिए ऑनलाइन बहुत अधिक सहायता प्रतीत होती है, इस प्रकार, हम इस निर्देश के साथ शुरू करते हैं, जो सीखा है उसका उपयोग करने के लक्ष्य के साथ, फिर एमएसपी 432 और कोड कम्पोज़र स्टूडियो पर लागू होता है।

उस लक्ष्य की ओर बढ़ते हुए, हमें एक अन्य लोकप्रिय माइक्रो-कंट्रोलर के साथ भी अनुभव प्राप्त होगा।

चरण 1: डिवाइस का प्रारंभिक परीक्षण

डिवाइस का प्रारंभिक परीक्षण
डिवाइस का प्रारंभिक परीक्षण
डिवाइस का प्रारंभिक परीक्षण
डिवाइस का प्रारंभिक परीक्षण
डिवाइस का प्रारंभिक परीक्षण
डिवाइस का प्रारंभिक परीक्षण

फिर, STM32 न्यूक्लियो को विशेष रूप से क्यों चुनें?

ईमानदारी से? क्योंकि मैं एआरएम नियंत्रकों के लिए बेयर-मेटल असेंबली परियोजनाओं पर अच्छे लेख खोज रहा था, और मैं इस श्रृंखला में आया। और इसलिए भी कि STM32 एक लोकप्रिय MCU लगता है।

मैंने कुछ शोध किया (इसमें से चुनने के लिए बहुत सारे संस्करण हैं - ऊपर की छवि देखें), लेकिन अंत में यह वही बन गया जो मुझे वास्तव में मिल सकता है, क्योंकि मैं अमेज़ॅन (यू.एस. में) का उपयोग करने जा रहा था।

यह कुछ स्टार्ट-अप निर्देशों के साथ एक सरल लेकिन पेशेवर पैकेज में आता है। यह देखना थोड़ा मज़ेदार था कि कंट्रोलर में बर्न किया गया डेमो लगभग वैसा ही था जैसा हमने पिछले इंस्ट्रक्शंस में किया है - एक एलईडी फ्लैश और एक बटन के प्रेस के अनुसार गति को बदलता है।

ऐसा लगता है कि यह विकास बोर्ड MSP432 के समान है जिसमें 2 LED और एक उपयोगकर्ता-पुशबटन है। MSP432 में 2 उपयोगकर्ता-बटन हैं।

जैसा कि आप तस्वीरों में देख सकते हैं, मैं थोड़ा अचंभित था कि बोर्ड में एक मिनी है न कि माइक्रो यूएसबी। तार खरीदने के लिए भागना पड़ा।

एक और अच्छा परीक्षण यह है कि जब आप इसे अपने कंप्यूटर से जोड़ते हैं (मैं एक लिनक्स बॉक्स का उपयोग कर रहा हूं), तो यह मेरे फाइल मैनेजर में एक फाइल सिस्टम के रूप में दिखाई देता है, जिसे "NODE_F303RE" कहा जाता है। ओपनिंग जो दो फाइलों को प्रकट करती है, एक HTML और एक टेक्स्ट।

बस इतना ही, लेकिन कम से कम यह भी कहता है कि कनेक्टिविटी काफी आसान लगती है।

अब हम शुरू करने के लिए तैयार हैं।

मैं IVONOMICON बेयर मेटल लेख श्रृंखला से किसी भी अच्छी जानकारी को दोहराने की कोशिश नहीं करने जा रहा हूं, बल्कि इसे बढ़ाऊंगा।

चरण 2: अनिवार्य

पहली चीज जो हमें चाहिए वह है एक कंपाइलर।

और फिर, हमें एक डीबगर की आवश्यकता है:

devchu@chubox:~$ sudo apt-get install gdb-arm-none-eabiपठन पैकेज सूचियाँ… पूर्ण निर्भरता ट्री राज्य की जानकारी पढ़ना… हो गया निम्नलिखित नए पैकेज स्थापित किए जाएंगे: gdb-arm-none-eabi 0 अपग्रेड किया गया, 1 नया स्थापित, 0 हटाने के लिए और 8 अपग्रेड नहीं किए गए। 2, 722 kB संग्रह प्राप्त करने की आवश्यकता है। इस ऑपरेशन के बाद, 7, 738 kB अतिरिक्त डिस्क स्थान का उपयोग किया जाएगा। प्राप्त करें:1 https://us.archive.ubuntu.com/ubuntu xenial/universe amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3+9 [2, 722 kB] 1s (1, 988) में 2, 722 kB प्राप्त किया गया kB/s) पहले अचयनित पैकेज का चयन करना gdb-arm-none-eabi. (डेटाबेस पढ़ना … 262428 फाइलें और निर्देशिकाएं वर्तमान में स्थापित हैं।) अनपैक करने की तैयारी …/gdb-arm-none-eabi_7.10-1ubuntu3+9_amd64.deb … gdb-arm-none-eabi को अनपैक करना (7.10-1ubuntu3+9) … संसाधन मैन-डीबी (2.7.5-1) के लिए ट्रिगर … जीडीबी-आर्म-नोन-ईबी सेट करना (7.10-1ubuntu3+9) …

चरण 3: अनिवार्य - विंडोज़

उपरोक्त चरण ने माना कि हम लिनक्स का उपयोग कर रहे हैं। क्या होगा अगर हम विंडोज का उपयोग कर रहे हैं?

आप आर्म डेवलपर साइट पर जा सकते हैं, और कई डाउनलोड विकल्प उपलब्ध हैं। मैं विंडोज 8 मशीन का उपयोग कर रहा हूं।

स्थापना के दौरान, मैंने इसे प्रोग्राम फ़ाइलों के बजाय रूट "C:\" ड्राइव में स्थापित करने के लिए चुना, क्योंकि मैं भी साइबरविन का उपयोग कर रहा हूं, और मेरे स्थानीय बिन से रूट C: फ़ोल्डर में सभी की तुलना में एक लिंक बनाना आसान था। प्रोग्राम फ़ाइलें (रिक्त स्थान, आदि के साथ) के पथ में गड़बड़ी।

इस प्रकार, मेरा साइबर पर्यावरण और पथ, आदि ऐसा दिखता है:

C:\cygwin64\home\bin\arm-none-eabi-gcc, जहां arm-none-eabi-gcc C:\GNUToolsArmEmbedded\7.2018.q2.update\bin\arm-none-eabi- का लिंक है। जीसीसी

मैंने तब साइबरविन होम के तहत एक "देव" फ़ोल्डर बनाया, और यहीं पर मैंने कोर.एस फ़ाइल रखी और कंपाइलर कमांड चलाया। (संकलक सामग्री के लिए और नीचे देखें)।

मैंने जीडीबी (आर्म-नो-ईबी-जीडीबी) के लिए ठीक यही काम किया।

चरण 4: अनिवार्य क्या हैं

तो "gcc-arm-none-eabi" क्या है?

जीएनयू कंपाइलर (जीसीसी) प्रोग्रामिंग भाषाओं (जैसे सी) को उस मशीन के मूल कोड में संकलित करेगा जिस पर वह चल रहा है। उदाहरण के लिए, यदि आप अपनी विंडोज मशीन पर जीसीसी का उपयोग करके कुछ सी कोड संकलित करते हैं, तो इसे विंडोज मशीन पर चलाने के लिए बनाया जाएगा। उत्पन्न निष्पादन योग्य (आमतौर पर) एआरएम माइक्रो-कंट्रोलर पर नहीं चलेगा।

इसलिए, एआरएम माइक्रो-कंट्रोलर (हमारे वर्तमान मामले में जो एसटीएम 32 न्यूसेलो होगा) में डाउनलोड और जलाए जाने वाले प्रोग्राम बनाने के लिए, हमें जीसीसी को कुछ और देना होगा: "क्रॉस-कंपाइल" करने की क्षमता। यही है, एक निष्पादन योग्य उत्पन्न करने की क्षमता, अपने मूल सिस्टम (और प्रोसेसर) के लिए नहीं, बल्कि लक्ष्य प्रणाली (एआरएम माइक्रो-कंट्रोलर) के लिए। यहीं से "gcc-arm-none-eabi" चलन में आता है।

तो फिर "gdb-arm-none-eabi" क्या है?

एक बार जब हम माइक्रो-कंट्रोलर में नव-निर्मित निष्पादन योग्य को डाउनलोड और बर्न (फ्लैश) कर लेते हैं, तो हम शायद इसे डिबग करना चाहेंगे - कोड की लाइन से लाइन के माध्यम से कदम। GDB ग्नू डिबगर है, और इसे भी अपना काम करने के लिए एक तरीके की आवश्यकता है, लेकिन एक अलग प्रणाली को लक्षित करना।

इस प्रकार, gdb-arm-none-eabi GDB के लिए है, GCC के लिए gcc-arm-none-eabi क्या है।

एक अन्य सुझाया गया पैकेज इंस्टाल "लिबन्यूलिब-आर्म-नोन-ईबी" था। वह क्या है?

न्यूलिब एक सी पुस्तकालय और गणित पुस्तकालय है जो एम्बेडेड सिस्टम पर उपयोग के लिए है। यह कई पुस्तकालय भागों का एक समूह है, सभी मुफ्त सॉफ्टवेयर लाइसेंस के तहत जो उन्हें एम्बेडेड उत्पादों पर आसानी से प्रयोग करने योग्य बनाते हैं।

और अंत में, पैकेज "libstdc++-arm-none-eabi"। वह बहुत स्पष्ट है; यह क्रॉस-कंपाइलर के लिए C++ लाइब्रेरी है; एम्बेडेड एआरएम माइक्रो-नियंत्रकों के लिए।

चरण 5: लिंकर फ़ाइल

लिंकर फ़ाइल
लिंकर फ़ाइल
लिंकर फ़ाइल
लिंकर फ़ाइल

आइए एक लिंकर स्क्रिप्ट बनाएं।

इस फ़ाइल का एक मुख्य भाग या ब्लॉक MEMORY कमांड होगा।

--- sourceware.org से:

लिंकर का डिफ़ॉल्ट कॉन्फ़िगरेशन सभी उपलब्ध मेमोरी के आवंटन की अनुमति देता है। आप मेमोरी कमांड का उपयोग करके इसे ओवरराइड कर सकते हैं। मेमोरी कमांड लक्ष्य में मेमोरी के ब्लॉक के स्थान और आकार का वर्णन करता है। आप इसका उपयोग यह वर्णन करने के लिए कर सकते हैं कि लिंकर द्वारा कौन से मेमोरी क्षेत्रों का उपयोग किया जा सकता है, और किन मेमोरी क्षेत्रों से इसे बचना चाहिए। फिर आप विशेष स्मृति क्षेत्रों के लिए अनुभाग निर्दिष्ट कर सकते हैं। लिंकर स्मृति क्षेत्रों के आधार पर अनुभाग पते सेट करेगा, और उन क्षेत्रों के बारे में चेतावनी देगा जो बहुत भरे हुए हैं। लिंकर उपलब्ध क्षेत्रों में फिट होने के लिए वर्गों को फेरबदल नहीं करेगा। एक लिंकर स्क्रिप्ट में मेमोरी कमांड के कई उपयोग हो सकते हैं, हालांकि, परिभाषित सभी मेमोरी ब्लॉक को एक ही मेमोरी कमांड के अंदर निर्दिष्ट किया गया माना जाता है। मेमोरी के लिए सिंटैक्स है:

याद

{नाम [(attr)]: मूल = मूल, लंबाई = लेन …}

लेख में उदाहरण:

/* RAM के अंत और स्टैक मेमोरी की सीमा को परिभाषित करें *//* (STM32F031x6 लाइन पर 4KB SRAM, 4096 = 0x1000) */ /* (RAM 0x20000000 पते पर शुरू होता है) _estack = 0x20001000;

याद

{ फ्लैश (आरएक्स): मूल = 0x08000000, लंबाई = 32K रैम (आरएक्सडब्ल्यू): मूल = 0x20000000, लंबाई = 4K}

इसलिए हमें यह पता लगाने की जरूरत है कि हमारे विशेष बोर्ड के लिए कितना फ्लैश (हमारे कार्यक्रम और स्थिरांक, आदि के लिए) और कितनी रैम (कार्यक्रम द्वारा उपयोग के लिए; ढेर और ढेर, आदि)। यह थोड़ा दिलचस्प हो जाता है।

न्यूक्लियो के साथ आने वाला अच्छा सा कार्ड कहता है कि इसकी फ्लैश मेमोरी 512 Kbytes है, और SRAM 80 Kbytes है। हालाँकि, इसे USB से जोड़ने पर, यह दो फ़ाइलों के साथ एक फ़ाइल सिस्टम के रूप में माउंट हो जाता है, और फ़ाइल प्रबंधक और GParted दोनों इंगित करते हैं कि इसमें 540+ Kbytes से अधिक स्थान है। (टक्कर मारना?)।

लेकिन, फ़ाइल प्रबंधक का उपयोग करके दो फ़ाइलों को हटाने का प्रयास, डिस्कनेक्ट करने के बाद डिवाइस को फिर से कनेक्ट करना, फिर भी दो फ़ाइलों को दिखाता है। (और फ़ाइल प्रबंधक ने कुछ पहचान लिया क्योंकि प्रत्येक फ़ाइल पर थोड़ा "लॉक" आइकन होता है।

तो चलिए कार्ड के आंकड़ों के साथ चलते हैं। तो अब हम उपरोक्त उदाहरण लेते हैं और इसे अपने विशिष्ट बोर्ड में परिवर्तित करते हैं।

सामान्य KB से विशिष्ट संख्या में बाइट्स पर जाने के लिए आप इस ऑनलाइन मेमोरी कनवर्टर की तरह कुछ उपयोग करना चाह सकते हैं।

तब आप एक ऑनलाइन दशमलव से हेक्स कनवर्टर का उपयोग करना चाह सकते हैं।

/* RAM के अंत और स्टैक मेमोरी की सीमा को परिभाषित करें */

/* (STM32F031x6 लाइन पर 4KB SRAM, 4096 = 0x1000) *//* उदाहरण*/

/* चरण 1: (STM32F303RE पर 80KB SRAM, 81920 = 0x14000) *//* हमारा बोर्ड */

/* चरण 2, हेक्स आकार को हेक्स प्रारंभिक पते (नीचे) में जोड़ें। */

/* (रैम 0x20000000 पते पर शुरू होता है) */

_estack = 0x20001000; /* उदाहरण */

_एस्टैक = 0x20014000; /* हमारा बोर्ड */

याद {

फ्लैश (आरएक्स): मूल = 0x08000000, लंबाई = 512K

रैम (आरएक्सडब्ल्यू): मूल = 0x20000000, लंबाई = 80K

}

आइए उपरोक्त फ़ाइल को "linker.script.ld" कहते हैं।

चरण 6: वेक्टर तालिका

वेक्टर तालिका
वेक्टर तालिका

अब हम कुछ बहुत ही बुनियादी इंटरप्ट-हैंडलिंग करने के लिए एक छोटी असेंबली फ़ाइल (निर्देशों के साथ) बनाने जा रहे हैं। हम लेख के उदाहरण का अनुसरण करेंगे और "core. S" नाम की फ़ाइल बनाएंगे।

फिर, यहाँ उदाहरण फ़ाइल सामग्री है, लेकिन मैंने अपने विशिष्ट बोर्ड के लिए एक बदलाव किया है:

// ये निर्देश हमारे चिप की विशेषताओं को परिभाषित करते हैं और

// हम जिस असेंबली भाषा का उपयोग करेंगे:.syntax यूनिफाइड /* इस कोड क्षेत्र के बाद नीचे देखें */ /*.cpu प्रांतस्था-m0 */ /*उदाहरण की इस पंक्ति पर टिप्पणी करें */.cpu प्रांतस्था-m4 /* इसके बजाय हमारे बोर्ड के कोर्टेक्स को जोड़ें। इस चरण में ऊपर की छवि देखें */ /*.fpu softvfp */ /* उदाहरण की इस पंक्ति पर टिप्पणी करें */.fpu vfpv4 /* इसके बजाय हमारे बोर्ड का जोड़ें; इसमें एक FPU */.thumb // ग्लोबल मेमोरी लोकेशन है।.global vtable.global reset_handler /* * वास्तविक वेक्टर तालिका। * सरलता के लिए केवल RAM का आकार और 'रीसेट' हैंडलर * शामिल हैं। */. प्रकार vtable,% वस्तु vtable:.word _estack.word reset_handler.size vtable,.-vtable

हम्म.. नहीं '.संरेखित करें' निर्देश

हालाँकि, यह महत्वपूर्ण नहीं है। उस पर (शायद) बाद में।

.सिंटैक्स एकीकृत

.सिंटैक्स [एकीकृत | अलग करना]

यह निर्देश एआरएम-निर्देश-सेट अनुभाग में वर्णित निर्देश सेट सिंटैक्स को सेट करता है

9.4.2.1 निर्देश सेट सिंटैक्स ARM और THUMB निर्देशों के लिए दो अलग-अलग सिंटैक्स समर्थन हैं। डिफ़ॉल्ट, विभाजित, पुरानी शैली का उपयोग करता है जहां ARM और THUMB निर्देशों का अपना, अलग सिंटैक्स होता है। नया, एकीकृत सिंटैक्स, जिसे.syntax निर्देश के माध्यम से चुना जा सकता है।

.एफपीयू वीएफपीवी4

जीसीसी कंपाइलर फ्लोटिंग पॉइंट के संबंध में कई विकल्पों के साथ बायनेरिज़ का उत्पादन कर सकता है: सॉफ्ट - बिना एफपीयू के सीपीयू पर चलने के लिए उपयुक्त - कम्पाइलर जेनरेटेड सॉफ्टएफपी द्वारा सॉफ्टवेयर में गणना की जाती है - सीपीयू के साथ या बिना एफपीयू पर चलने के लिए उपयुक्त - यदि मौजूद हो तो एफपीयू का उपयोग करेगा. हमारे विशिष्ट मामले के लिए (आपको अपना शोध स्वयं करना होगा), इस विशेष बोर्ड का FPU vfpv4 के अनुरूप है। आपको इसके साथ खेलना पड़ सकता है। या इसे softfp पर भी छोड़ दें।

.अंगूठा (बनाम.arm)

इन एआरएम माइक्रोकंट्रोलर में वास्तव में निर्देश सेट का मिश्रण होता है। एक एआरएम है, दूसरा थंब है। एक अंतर 16-बिट निर्देश बनाम 32-बिट निर्देश है। इस प्रकार, यह निर्देश संकलक को बाद के निर्देशों को THUMB या ARM के रूप में मानने के लिए कहता है।

हम फ़ाइल के शेष भाग को वैसे ही लेने जा रहे हैं, क्योंकि ये निर्देश अभी तक बाधित-संचालित असेंबली प्रोग्रामिंग में नहीं आए हैं।

चरण 7: 'हैलो वर्ल्ड' कार्यक्रम का असेंबली संस्करण

निम्नलिखित पहले से बनाई गई "core. S" फ़ाइल में भी जा सकते हैं। यह, फिर से, लेख में उदाहरण से है।

/* * रीसेट हैंडलर। रीसेट पर कॉल किया गया। */.type reset_handler, %function reset_handler: // स्टैक पॉइंटर को स्टैक के अंत में सेट करें। // '_estack' मान हमारी लिंकर स्क्रिप्ट में परिभाषित किया गया है। LDR r0, =_estack MOV sp, r0

// कुछ डमी मान सेट करें। जब हम इन मूल्यों को देखते हैं

// हमारे डिबगर में, हम जानेंगे कि हमारा प्रोग्राम // चिप पर लोड है और काम कर रहा है। LDR r7, =0xDEADBEEF MOVS r0, #0 main_loop: // 'r0' रजिस्टर करने के लिए 1 जोड़ें। ADDS r0, r0, #1 // लूप बैक। बी main_loop.size reset_handler,.-reset_handler

तो, उपरोक्त कार्यक्रम का जोर एक पहचानने योग्य पैटर्न को एक कोर एमसीयू रजिस्टर (इस मामले में आर 7) में लोड करना है, और एक अन्य कोर एमसीयू रजिस्टर (इस मामले में आर 0) में शून्य से शुरू होने वाला एक वृद्धिशील मूल्य है। यदि हम निष्पादन कोड के माध्यम से कदम रखते हैं, तो हमें R0 का डेटा वृद्धि देखना चाहिए।

यदि आप MSP432 और TI-RSLK पाठ्यक्रम/प्रयोगशालाओं के बारे में निर्देशों का पालन कर रहे हैं, तो उपरोक्त सभी कार्यक्रमों से आपको परिचित होना चाहिए।

एक नई चीज़ जो मैं देख सकता हूँ वह है R7 को पंजीकृत करने के लिए "DEADBEEF" लोड करते समय "=" का उपयोग। हमने इसका इस्तेमाल नहीं किया था।

यहाँ संलग्न "core. S" फ़ाइल में अब पूरा स्रोत है।

चरण 8: कोड संकलित करना

कुछ कमांड-लाइन सामान करने का समय आ गया है। कुछ वास्तविक, अंत में।

हालाँकि, हम काफी वहाँ नहीं हैं। हमें लेख में दिए गए आदेश को फिर से बदलना होगा, और इसे अपनी स्थिति में संशोधित करना होगा।

यहाँ उदाहरण कोड है:

arm-none-eabi-gcc -x असेंबलर-साथ-cpp -c -O0 -mcpu=cortex-m0 -mthumb -Wall core. S -o core.o

अगर हम GCC के लिए gnu.org साइट पर जाते हैं, (इस मामले में संस्करण 7.3),

एक्स

-x भाषा निर्दिष्ट करना है। अन्यथा यदि नहीं -x, तो संकलक फ़ाइल एक्सटेंशन का उपयोग करके अनुमान लगाने का प्रयास करेगा। (हमारे मामले में, *.एस).

लेख से उपरोक्त उदाहरण असेंबलर-साथ-सीपीपी निर्दिष्ट करता है, लेकिन हम सिर्फ असेंबलर कर सकते हैं।

सी

-c कहता है संकलित करें लेकिन लिंक न करें।

ओ0

-O अनुकूलन स्तर निर्धारित करना है। -O0 (ओह-शून्य) का उपयोग करना कहता है "संकलन समय कम करें और डिबगिंग को अपेक्षित परिणाम दें। यह डिफ़ॉल्ट है"।

एमसीपीयू = कोर्टेक्स-एम0

-एमसीपीयू लक्ष्य प्रोसेसर का नाम निर्दिष्ट करता है। हमारे मामले में, यह कोर्टेक्स-एम4 होगा।

मथंब

-मथंब एआरएम और थंब राज्यों को निष्पादित करने वाले कोड उत्पन्न करने के बीच चयन को निर्दिष्ट करता है।

दीवार

दीवार बेशक बहुत ही सामान्य और प्रसिद्ध है। यह सभी चेतावनी झंडों को चालू करता है।

अंत में, कमांड के अंत में हमारे पास इनपुट फ़ाइल core. S और आउटपुट फ़ाइल core.o है।

हमारे विशिष्ट मामले में फिट होने के लिए परिणामी नई कमांड लाइन यहां दी गई है।

arm-none-eabi-gcc -x असेंबलर -c -O0 -mcpu=cortex-m4 -mthumb -Wall core. S -o core.o

और वह संकलित।

चरण 9: कार्यक्रम को जोड़ना

सीधे लेख में उदाहरण से, हमारे पास यह है:

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

उपरोक्त में से अधिकांश आपने देखा है। नीचे नया क्या है।

specs=nosys.specs

यह समझाने में थोड़ा मुश्किल है।

इसे "सेमीहोस्टिंग" और "रिटारगेटिंग" के साथ करना है, और इसे इनपुट/आउटपुट के साथ करना है। इसे सिस्टम कॉल और लाइब्रेरी से भी लेना-देना है।

आमतौर पर, एम्बेडेड सिस्टम मानक इनपुट/आउटपुट डिवाइस प्रदान नहीं करते हैं। यह सिस्टम या लाइब्रेरी कॉल को प्रभावित करेगा (उदाहरण: प्रिंटफ ())।

सेमीहोस्टिंग का अर्थ है डिबगर (लाल रंग में परिचालित डिबगर भाग के साथ चरण 11 की छवि देखें) में एक विशेष चैनल है और सेमीहोस्टिंग प्रोटोकॉल का उपयोग करता है, और आप होस्ट मशीन (डीबगर के माध्यम से) पर प्रिंटफ () का आउटपुट देख सकते हैं।

दूसरी ओर, रिटारगेटिंग का मतलब है कि वही सिस्टम या लाइब्रेरी कॉल का मतलब कुछ और है। वे कुछ और करते हैं, जो एम्बेडेड सिस्टम के लिए समझ में आता है। एक अर्थ में, प्रिंटफ () के लिए कहें, एक नया कार्यान्वयन है, उस फ़ंक्शन का एक पुनर्लक्षित कार्यान्वयन।

इतना सब कहने के बाद, --specs=nosys.specs का अर्थ है कि हम सेमीहोस्टिंग नहीं करेंगे। इसका सामान्य अर्थ यह होगा कि हम पुनः लक्ष्यीकरण कर रहे हैं। यह हमें अगले झंडे पर लाता है।

नोस्टडलिब

लिंकर विकल्प -नोस्टडलिब का उपयोग स्टैंडअलोन चलाने के उद्देश्य से प्रोग्राम को लिंक करने के लिए किया जाता है। -नोस्टडलिब का तात्पर्य अलग-अलग विकल्पों -नोडेफॉल्टलिब्स और -नोस्टार्टफाइल्स से है। नीचे हम दो विकल्पों पर अलग-अलग चर्चा करते हैं, लेकिन एक-स्टॉप खरीदारी के लिए सबसे विशिष्ट उपयोग सिर्फ नॉस्टडलिब है। होस्ट किए गए प्रोग्राम को लिंक करते समय, मानक सिस्टम लाइब्रेरी जैसे कि libc डिफ़ॉल्ट रूप से लिंक होते हैं, जिससे प्रोग्राम को सभी मानक कार्यों (प्रिंटफ,) तक पहुंच मिलती है। स्ट्रेल और दोस्त)। लिंकर विकल्प -nodefaultlibs उन डिफ़ॉल्ट पुस्तकालयों से लिंक करना अक्षम करता है; लिंक किए गए एकमात्र पुस्तकालय ठीक वही हैं जिन्हें आप -l ध्वज का उपयोग करके लिंकर को स्पष्ट रूप से नाम देते हैं।

एलजीसीसी

libgcc.a एक मानक पुस्तकालय है जो विशेष मशीनों की कमियों को दूर करने के लिए आंतरिक सबरूटीन प्रदान करता है। उदाहरण के लिए, एआरएम प्रोसेसर में एक डिवीजन निर्देश शामिल नहीं है। libgcc.a के एआरएम संस्करण में एक डिवीजन फ़ंक्शन शामिल है और कंपाइलर उस फ़ंक्शन पर कॉल करता है जहां आवश्यक हो।

टी

लिंकर को इस फ़ाइल को लिंकर स्क्रिप्ट के रूप में उपयोग करने के लिए कहने का यह एक तरीका है। हमारे मामले में, फ़ाइल का नाम linker.script.ld है।

ओ मेन.एल्फ

अंत में, हम लिंकर को बताते हैं कि अंतिम आउटपुट इमेज फ़ाइल का नाम क्या होगा जिसे हमारे डिवाइस में बर्न/फ्लैश किया जाएगा।

यहाँ पूरी कमांड-लाइन का हमारा संस्करण है, जिसे हमारी विशिष्ट स्थिति के लिए संशोधित किया गया है:

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

हम सुनिश्चित करते हैं कि स्क्रिप्ट फ़ाइल, और core.o फ़ाइल, दोनों एक ही निर्देशिका में हैं, जहाँ हम उपरोक्त कमांड-लाइन चलाएंगे।

और यह बिना किसी समस्या के लिंक करता है।

एक चेक

हम तब दौड़ते हैं:

arm-none-eabi-nm main.elf

और हमें मिलता है:

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

अछा लगता है। arm-none-eabi-nm कमांड ऑब्जेक्ट फ़ाइलों के भीतर प्रतीकों को सूचीबद्ध करने का एक तरीका है।

चरण 10: STM32 न्यूक्लियो-64 से कनेक्शन का परीक्षण

STM32 न्यूक्लियो-64 से परीक्षण कनेक्शन
STM32 न्यूक्लियो-64 से परीक्षण कनेक्शन
STM32 न्यूक्लियो-64 से परीक्षण कनेक्शन
STM32 न्यूक्लियो-64 से परीक्षण कनेक्शन

आपका पहला मिशन, क्या आप इसे स्वीकार करना चुनते हैं, अपने सिस्टम को अपने विकास बोर्ड को देखने के लिए प्राप्त करना है।

विंडोज़ का उपयोग करना

विंडोज़ के लिए, मैंने एटॉलिक (मुफ्त संस्करण) से ट्रूस्टूडियो स्थापित करने का निर्णय लिया। यह एक दर्द रहित इंस्टाल था और इसने ड्राइवर को स्वचालित रूप से स्थापित कर दिया ताकि मैं कनेक्शन का परीक्षण करने के लिए सेंट-लिंक का उपयोग कर सकूं। एक बार जब मैंने ट्रूस्टूडियो स्थापित किया और डिवाइस मैनेजर ने डिवाइस देखा, तो मैंने बेयर मेटल आलेख द्वारा सुझाए गए टेक्सन/स्टलिंक टूल्स को डाउनलोड किया जिसका हम अनुसरण कर रहे हैं। मैंने फिर से फ़ोल्डर को सीधे "सी: \" के नीचे रखा, और फिर से मेरे स्थानीय साइबरविन होम बिन से कमांड के लिए कुछ लिंक बनाए।

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

प्रारंभिक परीक्षण के रूप में यह देखने के लिए कि क्या हम वास्तव में डिवाइस के साथ संवाद कर सकते हैं, मैं भाग गया:

सेंट-जानकारी --जांच

और वापस आ गया:

1 स्टलिंक प्रोग्रामर मिले

तो अब हम जानते हैं कि हम अपने विकास बोर्ड से बात कर सकते हैं/पूछ सकते हैं।

लिनक्स का उपयोग करना

लिनक्स के लिए, आपको वास्तव में ड्राइवर की आवश्यकता नहीं है। लेकिन डेबियन के लिए, आपको स्रोत से सेंट टूल्स बनाना होगा।

गिट क्लोन

सुनिश्चित करें कि आपके पास libusb-1.0-0-dev स्थापित है।

उपयुक्त सूची | grep -E "*libusb.*dev*"

तुम्हें देखना चाहिए:

libusb-1.0-0-dev/xenial, अब 2:1.0.20-1 amd64 [स्थापित]

या कुछ इस तरह का।

इसे स्थापित करने के लिए:

sudo apt-libusb-1.0-0-dev install स्थापित करें

ध्यान दें कि उपरोक्त समान नहीं है:

sudo apt-libusb-dev install स्थापित करें

सही लापता libusb देव सेमेक को समस्याएँ पैदा कर सकता है।

सीएमके त्रुटि: इस परियोजना में निम्नलिखित चर का उपयोग किया गया है, लेकिन वे NOTFOUND पर सेट हैं। कृपया उन्हें सेट करें या सुनिश्चित करें कि वे सीएमके फाइलों में सही ढंग से सेट और परीक्षण किए गए हैं: LIBUSB_INCLUDE_DIR (ADVANCED)

प्रोजेक्ट की रूट डायरेक्टरी में बदलें (…blah/blah/stlink)। एक "रिलीज़ करें" करें।

उसके निर्माण के बाद, उपकरण "../बिल्ड/रिलीज़" के अंतर्गत होना चाहिए।

फिर आप "st-info --probe" चला सकते हैं। यहाँ न्यूक्लियो के साथ आउटपुट जुड़ा हुआ है, फिर नहीं।

devchu@chubox:~/Development/stlink$./build/Release/st-info --probeFound 1 stlink प्रोग्रामर सीरियल: 303636414646353034393535363537 openocd: "\x30\x36\x36\x41\x46\x46\x35\x30\x34\ x39\x35\x35\x36\x35\x37" फ्लैश: 524288 (पेजसाइज: 2048) sram: 65536 चिपिड: 0x0446 descr: F303 हाई डेंसिटी डिवाइस devchu@chubox:~/Development/stlink$./build/Release/st- info --probe मिला 0 स्टलिंक प्रोग्रामर devchu@chubox:~/Development/stlink$

चरण 11: आइए लिनक्स के साथ GDB का उपयोग करें

आइए लिनक्स के साथ जीडीबी का प्रयोग करें
आइए लिनक्स के साथ जीडीबी का प्रयोग करें
आइए लिनक्स के साथ जीडीबी का प्रयोग करें
आइए लिनक्स के साथ जीडीबी का प्रयोग करें

यदि आप यह सब करने की कोशिश कर रहे हैं, और आप इसे बहुत दूर कर चुके हैं - बढ़िया! उत्कृष्ट। चलो अब थोड़ा मजे करो।

जब आप इन एआरएम विकास बोर्डों को खरीदते हैं, चाहे वे टेक्सास इंस्ट्रूमेंट्स से एमएसपी 432 लॉन्चपैड हों, या यह हम अभी चर्चा कर रहे हैं, न्यूक्लियो-एफ 303 (एसटीएम 32 न्यूक्लियो -64), वे आम तौर पर पहले से ही एक चल रहे प्रोग्राम के साथ आते हैं, आमतौर पर कुछ ब्लिंकी प्रोग्राम जिसमें एलईडी के फ्लैश की दर को बदलने के लिए एक स्विच को दबाना भी शामिल है।

इससे पहले कि हम इसे ओवर-राइट करने के लिए इतनी जल्दी हों, आइए देखें कि क्या देखना है और क्या करना है।

Linux के साथ, एक टर्मिनल खोलें, stlink git प्रोजेक्ट की निर्देशिका बदलें जिसे हमने अभी बनाया है, और st-util टूल ढूंढें।

devchu@chubox:~/Development/stlink$ find । -नाम

./बिल्ड/रिलीज़/src/gdbserver/st-util

उस टूल को चलाएं। चूंकि हमने पहले ही st-info --probe के साथ अपने कनेक्शन का परीक्षण कर लिया है, इसलिए हमें कुछ आउटपुट प्राप्त करना चाहिए:

st-util 1.4.0-50-g7fafee2 2018-10-20T18:33:23 INFO common.c: डिवाइस पैरामीटर लोड हो रहा है…। 2018-10-20T18:33:23 INFO common.c: कनेक्टेड डिवाइस है: F303 हाई डेंसिटी डिवाइस, id 0x10036446 2018-10-20T18:33:23 INFO common.c: SRAM साइज: 0x10000 बाइट्स (64 KiB), फ्लैश: 0x80000 बाइट्स (512 KiB) 2048 बाइट्स के पृष्ठों में 2018-10-20T18:33:23 INFO gdb-server.c: चिप आईडी 00000446 है, कोर आईडी 2ba01477 है। 2018-10-20T18:33:23 जानकारी gdb-server.c: *:4242 पर सुन रहा है…

वह GDB सर्वर अभी चल रहा है, और यह हमारे विकास बोर्ड को देखता है, और इससे भी महत्वपूर्ण बात यह है कि यह पोर्ट 4242 (डिफ़ॉल्ट पोर्ट) पर सुन रहा है।

अब हम GDB क्लाइंट को सक्रिय करने के लिए तैयार हैं।

लिनक्स में, एक और टर्मिनल खोलें, इसे दर्ज करें:

arm-none-eabi-gdb -tui

यह जीडीबी सख्ती से कमांड लाइन चलाने जैसा ही है, हालांकि यह इसके बजाय टेक्स्ट-आधारित टर्मिनल उत्पन्न करता है (मेरा अनुमान है कि यह शाप का उपयोग करता है)।

हमारे पास GDB क्लाइंट और GDB सर्वर चल रहा है। हालाँकि, क्लाइंट सर्वर से कनेक्ट नहीं है। फिलहाल यह हमारे न्यूक्लियो (या आपकी पसंद के बोर्ड) के बारे में कुछ नहीं जानता है। हमें यह बताना होगा। टर्मिनल में, आपका संकेत अब "(gdb)" होना चाहिए। प्रवेश करना:

मदद लक्ष्य

यह आपको एक सूची देगा। ध्यान दें कि हम जो चाहते हैं वह लक्ष्य विस्तारित-रिमोट है - एक सीरियल लाइन के माध्यम से एक दूरस्थ कंप्यूटर का उपयोग करें।

लेकिन हमें इसे लोकेशन भी देनी होगी। तो, (जीडीबी) प्रॉम्प्ट पर, दर्ज करें:

(जीडीबी) विस्तारित-रिमोट लोकलहोस्ट को लक्षित करें:4242

आपको कुछ इस तरह की प्रतिक्रिया वापस मिलनी चाहिए:

(जीडीबी) विस्तारित-रिमोट लोकलहोस्ट को लक्षित करें:4242

लोकलहोस्ट का उपयोग करके रिमोट डिबगिंग: 4242 0x080028e4 में ?? ()

इस बीच, st-util gdbserver चलाने वाले टर्मिनल पर, हमें यह मिला:

2018-10-20T18:42:30 जानकारी gdb-server.c: 6 hw ब्रेकप्वाइंट रजिस्टर मिले

2018-10-20T18:42:30 जानकारी gdb-server.c: GDB कनेक्टेड।

चरण 12: विंडोज के साथ दोहराएं और हमारे प्रोग्राम को फ्लैश करें

आइए दोहराएं, विंडोज़ और फ्लैश के साथ हमारा प्रोग्राम
आइए दोहराएं, विंडोज़ और फ्लैश के साथ हमारा प्रोग्राम
आइए दोहराएं, विंडोज़ के साथ और हमारे प्रोग्राम को फ्लैश करें
आइए दोहराएं, विंडोज़ के साथ और हमारे प्रोग्राम को फ्लैश करें
आइए दोहराएं, विंडोज़ के साथ और हमारे प्रोग्राम को फ्लैश करें
आइए दोहराएं, विंडोज़ के साथ और हमारे प्रोग्राम को फ्लैश करें

st-util gdbserver, और arm-none-eabi-gdb क्लाइंट को चलाने के चरण अनिवार्य रूप से वही हैं जो हमने पिछले चरण के दौरान किए थे। आप दो टर्मिनल (साइगविन, डॉस सीएमडी, या विंडोज पावरहेल) खोलते हैं, सेंट-यूटिल का स्थान ढूंढते हैं, इसे चलाते हैं। दूसरे टर्मिनल में, arm-none-eabi-gdb क्लाइंट चलाएँ। अंतर केवल इतना है कि -तुई (टर्मिनल-आधारित टेक्स्ट व्यू) मोड सबसे अधिक समर्थित नहीं है।

यदि उपरोक्त विंडोज़ में काम करता है, तो आपको शायद रुकना होगा (केवल क्लाइंट)। इस बिंदु पर, किसी तरह आपको GDB क्लाइंट चलाने की आवश्यकता होगी जहाँ आपकी बिल्ड फ़ाइल ("core.out") है, या GDB क्लाइंट के तर्क के रूप में उस फ़ाइल में संपूर्ण पथ जोड़ें।

मैंने साइबरविन का उपयोग करके और अपनी स्थानीय $HOME//bin निर्देशिका से लिंक बनाकर अपने जीवन को सरल बनाया जहां वे दोनों उपकरण रहते हैं।

ठीक है, हमने पहले की तरह ही संकलित और लिंक किया है, और हमारे पास फ़ाइल main.elf फ्लैश करने के लिए तैयार है।

हमारे पास एक विंडो में st-util चल रहा है। हम GDB क्लाइंट को फिर से शुरू करते हैं, इस बार हम करते हैं:

arm-none-eabi-gdb main.elf

हम इसे शुरू होने देते हैं, (जीडीबी) प्रॉम्प्ट की प्रतीक्षा करते हैं, जीडीबी सर्वर (एसटी-यूटिल) के लिए हमारा समान कनेक्शन कमांड करते हैं, और हम निष्पादन योग्य फ्लैश करने के लिए तैयार हैं। यह बहुत ही जलवायु-विरोधी है:

(जीडीबी) लोड

साइगविन टर्मिनलों के साथ चल रहा है, कुछ समय के साथ एक ज्ञात समस्या है कंसोल कमांड आउटपुट नहीं करते हैं। तो हमारे मामले में, सर्वर चलाने वाली विंडो पूरी तरह से चुप थी। क्लाइंट चलाने वाला, जहां हमने लोड चलाया, इसे आउटपुट करें:

लोड हो रहा है अनुभाग.पाठ, आकार 0x1c lma 0x8000000 प्रारंभ पता 0x8000000, लोड आकार 28 स्थानांतरण दर: 1 केबी/सेकंड, 28 बाइट्स/लिखें।

चरण 13: लिनक्स के साथ चमकना - अधिक फायदेमंद:D

Linux के साथ चमकना - अधिक फायदेमंद:D
Linux के साथ चमकना - अधिक फायदेमंद:D

चरण 14: चलो थोड़ा गहरा गोता लगाएँ

यदि आप यहाँ पहुँच गए हैं, तो बहुत बढ़िया। पर चलते हैं।

निष्पादन योग्य main.elf फ़ाइल के अंदर क्यों न देखें? निम्नलिखित चलाएँ:

arm-none-eabi-objdump -d main.elf

आपको आउटपुट कुछ इस तरह देखना चाहिए:

main.elf: फ़ाइल स्वरूप elf32-littlearm

खंड.पाठ का निराकरण:

08000000:

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

08000008:

८०००००८: ४८०२ एलडीआर r0, [पीसी, #८]; (८००००१४) ८०००००ए: ४६८५ मूव एसपी, आर० ८०००००सी: ४एफ०२ एलडीआर आर७, [पीसी, #८]; (८००००१८) ८०००००ई: २००० मूव्स r0, #०

08000010:

८००००१०: ३००१ r0, #1 ८००००१२ जोड़ता है: e7fd b.n ८००००१० ८००००१४: २००१४०००।

उपरोक्त आउटपुट से हमें कौन सी छोटी डली मिल सकती है?

यदि आपको याद है जब हम लिंकर.स्क्रिप्ट.एलडी फ़ाइल पर चर्चा और निर्माण कर रहे थे, तो हमने कहा था कि इन एआरएम उपकरणों में रैम 0x20000000 से शुरू होती है, और फ्लैश मेमोरी 0x08000000 से शुरू होती है।

इस प्रकार, हम देख सकते हैं कि वास्तव में कार्यक्रम ऐसा है कि यह सभी फ्लैश मेमोरी में रहता है।

फिर, ऊपर, लेकिन एक बाद का चरण, जब हम "हैलो वर्ल्ड" भाग पर चर्चा कर रहे थे, तो एक बयान था जहां हम एक तत्काल, स्थिर, शाब्दिक मूल्य ("0xDEADBEEF") को एक MCU कोर रजिस्टर ("R7") में लोड करते हैं।

बयान था:

एलडीआर R7, =0xDEADBEEF

हमारे कोड में, यही एकमात्र स्थान है जहां हम DEADBEEF का भी उल्लेख करते हैं। कहीं नहीं। और फिर भी, यदि आप उपरोक्त अलग-अलग/पुनर्निर्मित निर्देशों आदि को देखते हैं, तो हमने जितना सोचा था, उससे कहीं अधिक DEADBEEF से संबंधित है।

इसलिए, कंपाइलर/लिंकर ने किसी तरह DEADBEEF के मान को स्थायी रूप से 0x8000018 स्थान पर फ्लैश पते में फ्लैश करने का निर्णय लिया। और फिर, कंपाइलर ने हमारे उपरोक्त एलडीआर निर्देश को बदल दिया:

LDR R7, [पीसी, #8]

इसने हमारे लिए एक टिप्पणी भी उत्पन्न की। कितना अच्छा। और यह हमें वर्तमान प्रोग्राम काउंटर वैल्यू (पीसी रजिस्टर) लेने के लिए कहता है, उस मान में 0x8 जोड़ें, और यहीं पर DEADBEEF को जला दिया गया है, और वह मान प्राप्त करें और इसे R7 में भर दें।

तो इसका मतलब यह भी है कि प्रोग्राम काउंटर (पीसी) 0x8000010 पते की ओर इशारा कर रहा था, जो कि main_loop की शुरुआत है, और यह कि DEADBEEF मान main_loop के अंत के बाद दो पते पर बैठता है।

चरण 15: अंत में, चल रहे कार्यक्रम पर एक संक्षिप्त नज़र

भले ही आपने GDB छोड़ दिया हो, बस कमांड को फिर से दर्ज करें। आपको इसे कोई फाइल देने की भी जरूरत नहीं है; हम अब और नहीं चमक रहे हैं, बस इसे चला रहे हैं।

एक बार जब आप GDB क्लाइंट को GDB सर्वर से फिर से कनेक्ट कर लेते हैं, तो (gdb) कमांड प्रॉम्प्ट पर:

(जीडीबी) जानकारी रजिस्टर

आपको कुछ इस तरह देखना चाहिए:

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 0x000ff000000cps

लेकिन फिर, (gdb) प्रांप्ट पर, दर्ज करें:

(जीडीबी) जारी रखें

और बहुत जल्दी CTRL-C मारा। कि कार्यक्रम को रोकना चाहिए। फिर से "सूचना रजिस्टर" कमांड दर्ज करें।

इस बार, यह अलग दिखता है:

(जीडीबी) जानकारी रजिस्टर

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 0x072 0 r9 0x200 0 r10 0x0 r11 0x10000000000 0x10000 १६७७७२१६

क्या हुआ? ठीक वही जो हम चाहते थे। DEADBEEF को R7 में लोड किया गया था, और R0 (अत्यंत तेज) वृद्धिशील रहा है। यदि आप दोहराते हैं, तो आपको R0 फिर से दूसरे मान के साथ दिखाई देगा।

चरण 16: हम फ्लैश में केवल-पढ़ने के लिए ऐरे बनाना चाहते थे

असेंबली और निर्देशों का उपयोग करके एक सरणी के बराबर बनाने का एक तरीका इस प्रकार है:

.type myarray, %object // नाम या लेबल 'myarray' को एक वस्तु प्रकार के रूप में परिभाषित किया गया है।

myarray: // यह 'myarray' की घोषणा की शुरुआत है // (इसमें क्या शामिल होगा)।.word 0x11111111 // 'myarray' में समाहित पहला सदस्य या मान।.word 0x22222222 //दूसरा मान (सन्निहित पते)।.वर्ड 0x33333333 // और इसी तरह।.size myarray,.-myarray // कंपाइलर/असेंबलर अब जानता है कि 'myarray' का अंत या // सीमा कहां है।

अब जब हमने इसे फ्लैश मेमोरी में सेट कर दिया है, तो हम इसे प्रोग्राम में इस्तेमाल कर सकते हैं। नीचे एक अंश है:

LDR R1, myarray // यह 'myarray' के पहले स्थान पर निहित डेटा को लोड करता है। // यह वह नहीं है जो हम चाहते हैं।

LDR R1, =myarray // यह स्थान मान को ही लोड करता है (पहला पता), // डेटा नहीं.. // यह वही है जो हम चाहते हैं।

MOV R2, #0 // R2 यह सुनिश्चित करने के लिए एक गिनती रखेगा कि हम बाहर न निकलें

// सरणी का अंत। LDR R3, =myarrsize // R3 'myarrsize' के बराबर होगा।

// R0 हमारे डेटा को होल्ड करेगा

मुख्य घेरा:

LDR R0, [R1] // R1 ('myarray') द्वारा इंगित डेटा को R0 में लोड करें। CMP R2, R3 // क्या हम सरणी की सीमा पर हैं? BEQ main_loop // अगर हम हैं, तो हम कर चुके हैं, इसलिए हम हमेशा के लिए लूप करेंगे।

R2, #1 // जोड़ें अन्यथा, हम सरणी के माध्यम से पुनरावृति जारी रख सकते हैं।

R1 जोड़ें, #4 // R1 को पंजीकृत करने के लिए 4 जोड़ें, इसलिए यह अगले पर सही ढंग से इंगित करता है

// पता..

बी मेन_लूप // लूप बैक।

वीडियो इस सब से गुजरता है, और इसमें एक बग है। यह अच्छा है; यह दिखाता है कि यह महत्वपूर्ण रन और डीबग कोड है। यह एक सरणी के अंत से चलने का एक क्लासिक मामला दिखाता है।

सिफारिश की: