2010-06-15 8 views
7

मैं कॉर्टेक्स-एम 3 प्रोसेसर (एसटीएम 32) पर रैम से फ़ंक्शन निष्पादित करने का प्रयास कर रहा हूं। फ़ंक्शन आंतरिक फ्लैश को मिटा देता है और फिर से लिखता है, इसलिए मुझे निश्चित रूप से रैम में होना चाहिए लेकिन मैं यह कैसे कर सकता हूं?मैं कॉर्टेक्स-एम 3 (एसटीएम 32) पर रैम से फ़ंक्शन निष्पादित कैसे करूं?

मैंने जो कोशिश की है वह यह है: memcpy का उपयोग करके फ़ंक्शन में एक बाइट सरणी में फ़ंक्शन कॉपी करें (यह जांचकर कि यह सही ढंग से गठबंधन हो जाता है), बाइट सरणी को इंगित करने के लिए फ़ंक्शन पॉइंटर सेट करना, फिर फ़ंक्शन को कॉल करना (पॉइंटर) ।

यह 10 निर्देशों के लिए ठीक काम करता है (मैं डीबगर के साथ निष्पादन का पालन कर सकता हूं) लेकिन फिर मुझे एक गड़बड़ त्रुटि मिलती है और प्रोसेसर रीसेट हो जाता है। एक लूप के माध्यम से दूसरे पास पर बस त्रुटि होती है, इसलिए कोड ठीक होना चाहिए (क्योंकि यह पहला पास काम करता है)। मैं सोच रहा हूं कि तेजी से रैम पहुंच कुछ तरीकों से बस टाइम को मक्स कर देती है ...

वैसे भी ऐसा करने का कोई सही तरीका है? एक स्कैटर फ़ाइल कैसा दिखता है जो स्वचालित रूप से रैम में एक फ़ंक्शन रखता है (मैं कॉर्टेक्स-एम 3 के लिए केइल यूविजन का उपयोग कर रहा हूं)?

संपादित करें: अधिक जानकारी: Toolchain: RealView MDK-एआरएम वी 4.10 संकलक: Armcc v4.0.0.728 असेंबलर: Armasm v4.0.0.728 लिंकर: ArmLink v4.0.0.728 प्रोसेसर: STM32F103ZE

रीसेट होने पर IMPRECISERR बिट बस गलती रजिस्टर में सेट होता है।

+0

उम्मम मुझे लगता है कि निर्माता के मंच पर आपको कम या कम पोस्ट करना चाहिए क्योंकि आप एक विशिष्ट हार्डवेयर का उपयोग कर रहे हैं, फिर भी, क्या आप अधिक विवरण दे सकते हैं, आप किस कंपाइलर का उपयोग कर रहे हैं, आप इसे कैसे डिबग कर रहे हैं, कोई कोड नमूने, शायद * एक * व्यक्ति जिसके पास ज्ञान है, उसके अलावा इसका उत्तर देने में सक्षम हो सकता है .... – t0mm13b

+1

@ tommieb75: लेकिन मुझे आपसे ज्यादा पसंद है! – c0m4

उत्तर

7

लूप पुनरावृत्ति पर क्रैश शायद इसलिए है क्योंकि फ़ंक्शन एक पूर्ण पते पर ब्रांच कर रहा है और RAM में नए फ़ंक्शन स्थान के सापेक्ष नहीं है। उस बिंदु पर मूल कोड स्थान तक पहुंचने से फ्लैश मिट ऑपरेशन की वजह से बस त्रुटि हो सकती है?

मेरा मानना ​​है कि आप फ़ंक्शन परिभाषा के लिए __ram निर्देश को जोड़कर सीआरएम के साथ सही ढंग से संकलित और प्रतिलिपि बना सकते हैं। कैसे RealView संकलक के साथ भी ऐसा ही करने पर शिक्षा के लिए EXECUTING FUNCTIONS IN RAM तकनीकी सहायता आलेख देखें: - विकल्प -

μVision आप मॉड्यूल विशिष्ट स्मृति क्षेत्रों कि संवाद परियोजना में दर्ज किए गए हैं करने के लिए पता लगाने के लिए अनुमति देता है लक्ष्य। ऐसा करने के लिए, स्रोत फ़ाइल (या फ़ाइल समूह) पर क्लिक करें और संवाद विकल्प - गुण खोलें। फिर मेमोरी असाइनमेंट के तहत मेमोरी क्षेत्रों का चयन करें।

फ़ोल्डर ARMExamplesRAM_Function में एक उदाहरण है।

उसमें फ़ंक्शन को प्रतिलिपि बनाने और उस स्थान पर कॉल को सही तरीके से जोड़ने की देखभाल करने के लिए स्टार्टअप कोड उत्पन्न करना चाहिए।अन्यथा, यदि आपको गतिशील रूप से रैम पर मनमाने ढंग से कार्य करने की आवश्यकता है, तो रीयल व्यू के साथ position independent code (PIC) संकलित करने की आवश्यकता है।

+0

उत्कृष्ट जवाब! – c0m4

+0

मुझे एक ही समस्या मिली है, सिवाय इसके कि मैं आरटीएक्स या किसी भी पुस्तकालय का उपयोग नहीं कर रहा हूं, इसलिए मुझे कंपाइलर का कोड शामिल नहीं है जो स्वचालित रूप से रैम कार्यों को रैम में लोड करता है। मैं राम में एक लोड क्षेत्र या निष्पादन क्षेत्र रखना चाहता हूं जहां मेरा कोड वास्तव में लिंक होगा लेकिन मुझे कोड को दूसरे पते (फ्लैश में) लोड करने के लिए जेएजी प्रोग्रामर की आवश्यकता है। आदर्श रूप से .sct फ़ाइल में (मैं केइल एमडीके का उपयोग कर रहा हूं) मेरे पास एक ऐसा अनुभाग होगा जहां मैं स्टोरेज और लिंकेज पता निर्दिष्ट करता हूं। लेकिन मैंने अभी तक यह नहीं किया है कि अभी तक ऐसा कैसे किया जाए। –

+0

@ कैप्टन: आप अपने विनिर्देशों के साथ एक नया प्रश्न खोलने पर विचार करना चाहेंगे। हालांकि, मेरा मानना ​​है कि ऊपर दिया गया समाधान आपकी स्थिति में भी लागू होता है। –

2

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

1

आईएआर कंपाइलर के साथ (मुझे पता है कि आपका प्रश्न कील के बारे में है लेकिन मुझे इसके साथ खेलने की ज़रूरत नहीं है) आप या तो पूरी परियोजना या व्यक्तिगत फ़ाइल को "स्थिति स्वतंत्र" के रूप में चिह्नित कर सकते हैं। अतीत में अन्य प्रोसेसर के साथ इसका उपयोग करने से इसका मतलब है कि आप इसे "कहीं भी" ले जा सकते हैं और यह अभी भी ठीक काम करेगा

2

क्योंकि एआरएम के पास तत्काल डेटा लोड करने की सीमित क्षमता है, जो यूआरएम के लिए कोड उत्पन्न करने वाली उपयोगिताएं अक्सर जुटापोज़ कोड और डेटा। उदाहरण के लिए,

void myRoutine(void) 
{ 
    myVar1=0x12345678; 
    myVar2=0x87654321; 
} 

की तरह एक बयान की तरह कुछ के रूप में खत्म हो सकता है:

myRoutine:   
    ldr r0,=myVar1; Load the address of _myVar 
    ldr r1,=0x12345678 
    str r1,[r0] 
    ldr r0,=myVar1; Load the address of _myVar 
    ldr r1,=0x87654321 
    str r1,[r0] 
    bx lr 

which would get translated into: 
    ldr r0,dat1 
    ldr r1,dat2 
    str r1,[r0] 
    ldr r0,dat3 
    ldr r1,dat4 
    str r1,[r0] 
    bx lr 
... followed some time later by 
dat1 dcd _myVar1 
dat2 dcd 0x12345678 
dat3 dcd _myVar2 
dat4 dcd 0x12345678 

or perhaps even something like: 
    mar r0,dat1 
    ldrm r0,[r1,r2,r3,r4] 
    str r2,[r1] 
    str r4,[r3] 
    bx lr 
... followed some time later by 
dat1 dcd _myVar1 
dat2 dcd 0x12345678 
dat3 dcd _myVar2 
dat4 dcd 0x12345678 

ध्यान दें कि _myVar और 0x12345678 तुरंत दिनचर्या जिसमें वे प्रकट के लिए कोड निम्नलिखित रखा जा सकता है; यदि आप अंतिम निर्देश का पालन करने वाले लेबल का उपयोग करके दिनचर्या की लंबाई निर्धारित करने का प्रयास करते हैं, तो ऐसी लंबाई पूरक डेटा को शामिल करने में विफल रहेगी।

एआरएम के साथ नोट करने के लिए एक अतिरिक्त बात यह है कि ऐतिहासिक कारणों से, कोड पते में अक्सर कम से कम महत्वपूर्ण सेट सेट होता है, भले ही कोड वास्तव में आधा शब्द सीमाओं पर शुरू होता है। इस प्रकार, एक निर्देश जिसका पता 0x12345679 है 0x12345678 से शुरू होने वाले दो या चार बाइट्स पर कब्जा करेगा। यह memcpy जैसी चीजों के लिए पता गणना जटिल कर सकते हैं।

मेरी सिफारिश आपको जो चाहिए उसे करने के लिए असेंबली भाषा में एक छोटी दिनचर्या लिखनी होगी। यह केवल कुछ ही निर्देश हैं, आप जान सकते हैं कि कोड क्या कर रहा है और यह पता निर्भरता क्या हो सकती है, और आपको भविष्य में कंपाइलर संस्करणों के बारे में चिंता करने की ज़रूरत नहीं होगी जैसे कि कुछ तोड़ने के लिए अपने कोड को बदलना [उदा। उपरोक्त कोड के तीसरे संस्करण में कोई समस्या नहीं होगी, भले ही dat1 एक विषम आधा रेखा पर उतरे क्योंकि एम 3 के एलडीआर निर्देश अनियंत्रित पठन को संभाल सकते हैं, लेकिन एलडीआरएम का उपयोग करके चौथा (थोड़ा तेज़ और अधिक कॉम्पैक्ट) संस्करण इस तरह के मामले में विफल हो जाएगा; भले ही एक कंपाइलर का आज का संस्करण चार एलडीआर निर्देशों का उपयोग करता है, भविष्य का संस्करण एलडीआरएम का उपयोग कर सकता है]।

संबंधित मुद्दे