2012-06-10 9 views
5

मैं STM32F4 उपयोग कर रहा हूँ और सी के भीतर से समारोह एक सी समारोह के अंदर के नाम से जाना है और जो एक अवरोध में भी है कहा जाता है से एक एएसएम समारोह रिट की कोशिश कर रहा। मैं r4-r7 दबा रहा हूं और पॉपिंग कर रहा हूं। क्या मुझे कुछ और करने की ज़रूरत है? मेरी धारणा r0-r3 को धक्का देने की आवश्यकता नहीं है। मैं एएसएम फ़ंक्शन के साथ वैश्विक चर को भी संशोधित कर रहा हूं। मेरा अनुमान है कि इन्हें अस्थिर घोषित किया जाना चाहिए। किसी भी सुझाव का स्वागत किया जाएगा। मैंने यह भी देखा है कि एआरएम द्वारा उल्लिखित कॉर्टेक्स एम 4 निर्देश सेट जैसा नहीं है जो जीसीसी कंपाइलर के लिए उपलब्ध प्रतीत होता है। उदाहरण के लिए पोस्ट लिखने के लिए कोई लिखना वापस नहीं है अर्थात आर 0, [आर 1], # 4 अवैध है। क्या ऐसी सूची है जिसमें एएसएम निर्देशों की अनुमति है? मैं STM32F4 thumb2एएसएम समारोह एम्बेडेड

का उपयोग करता है अब तक यह सोचते हैं रहा हूँ यह काम किया जाना प्रतीत नहीं होता है और विधानसभा

+0

क्या आपने इसे आजमाया? क्या काम नहीं किया? आप कहते हैं कि आप एक असेंबली फ़ंक्शन कॉल करने का प्रयास कर रहे हैं, लेकिन आपका शेष प्रश्न ऐसा लगता है जैसे आप एक लिखने की कोशिश कर रहे हैं। बेहतर व्याख्या करने की कोशिश करें। –

+0

आपको निश्चित रूप से वैश्विक वैरिएबल को अस्थिर घोषित करना चाहिए, लेकिन मैंने थोड़ी देर के लिए एआरएम एएसएम नहीं किया है, इसलिए बाकी माफी के साथ मदद नहीं कर सकता है। – lxop

+1

वैश्विक वैरिएबल 'अस्थिर' घोषित करने का कोई कारण नहीं है जब तक कि यह प्रोग्राम के नियंत्रण के प्रवाह के बाहर बदल नहीं सकता है। एक असेंबली फ़ंक्शन को कॉल करना स्वयं को 'अस्थिर' की आवश्यकता के लिए पर्याप्त कारण नहीं है। * कोई * फ़ंक्शन कॉल वैश्विक के मान को बदल सकता है। –

उत्तर

2

मैं जब तक मेरे अपने सवाल का जवाब नहीं कर सका में सोच रहा हूँ क्या संभावित समस्याओं हो सकता है त्रुटियों के अलावा 8 घंटे इंतजार किया? वैसे भी मुझे मिला है और यह काम करता है !! इस फ़ंक्शन में काफी कुछ चल रहा है। यह मूल रूप से एक साइन वेव ऑसीलेटर है जो साइन मूल्यों के लिए एक LUT का उपयोग करता है। यह घातीय मूल्यों की एक तालिका का भी उपयोग करता है जिसे नियंत्रण के लिए एक बर्तन तक लगाए गए एडीसी का उपयोग करके असाइन किया जाता है। एक 32 बिट चरण संचयक है जो एक रैंप बनाता है जिसे लुकअप के लिए स्केल किया जाता है। साइन टेबल (जिसमें मैंने अधिक शामिल नहीं किया) 16 बिट तालिका आकार के लिए 16 बिट मानों को छोटा कर दिया गया है। मुझे यकीन है कि इस कोड में बहुत सारे अनुकूलन किए जा रहे हैं लेकिन कम से कम यह मुझे शुरू कर देता है। मैं इस समारोह के प्रत्येक पास के साथ 16 साइन लहर नमूने @ 48k उत्पन्न कर रहा हूं और एक बफर भर रहा हूं जो (इस फ़ंक्शन के बाहर) को डीएमए में स्थानांतरित किया जाता है और डिस्कवरी ऑन-बोर्ड कोडेक के माध्यम से आउटपुट किया जाता है। यह बहुत आसान लग रहा है मुझे कहना चाहिए। कुल निर्देश चक्र अब तक लगभग 1200 प्रतीत होते हैं। अगर मुझे उनकी ज़रूरत है तो मेरे पास 56000 चक्र हैं इसलिए यह बहुत अच्छा है। एक चीज जिसमें मुझे कठिनाई हो रही है, साइन आउट को स्केल कर रहा है। साइन टेबल int16_t मान है और मैं वॉल्यूम नियंत्रण प्राप्त करने के लिए इसे एक अंश से गुणा करने में सक्षम होना चाहता हूं। अब तक कुछ भी नहीं मैं smul का उपयोग कर, mul आदि

@ void get_sine(void) 
     .align 2     @ Align to word boundary 
     .global get_sine  @ This makes it a real symbol 
     .thumb_func 
     .type get_sine STT_FUNC @ Declare get_sine to be a function. 

    get_sine:     @ Start of function definition 
     push {r4-r7} 
     ldr  r0,=pitch  @ get pitch address 
     ldr  r1,=expoLUT  @ expo_tab address 
     ldr  r7,[r0,#0]  @ pitch val into r7 
     lsl  r7,r7,#2 
     ldr  r7,[r1,r7]  @ move lookup expo tab value with r7 into r7 

     ldr  r2,=sineLUT  @ sine_tab base addy 
     ldr  r4,=WaveBuffer @ storage array addy 
     ldr  r5,=writePos @ get writepos addr 
     mov  r6,#0   @ clear increment r6 

    outloop: 
     ldr  r3,=phase  @ phase address to r3 
     ldr  r1,[r3,#0]  @ get current phase 
     add  r1,r1,r7  @ add current phase and ph_inc 
     str  r1,[r3,#0]  @ store phase 
     lsr  r0,r1,#18  @ shift it right by 18 into r0 for sine_tab lookup 
     lsl  r0,r0,#2  @ align it 
     ldr  r0,[r2,r0]  @ lookup sine val with r0 into r1 
     lsl  r1,r0,#16  @ shift to left channel 
     add  r0,r0,r1  @ add right channel 
     ldr  r1,[r5,#0]  @ get writePos 
     push {r1}   @ push it before align 
     lsl  r1,r1,#2  @ align address 4 
     str  r0,[r4,r1]  @ store sine to WaveBuffer 
     pop  {r1}   @ pop writepos back 
     add  r1,r1,#1  @ increment array pointer writepos 
     ldr  r3,=1024  @ load BUFFERSIZE compare 
     cmp  r1,r3   @ skip if less than BUFFERSIZE 
     bne  skip 
     mov  r1,#0   @ clr writepos if >=BUFFERSIZE 

    skip: 
     str  r1,[r5,#0]  @ store writepos value 
     add  r6,r6,#1  @ increment loop counter 
     ldr  r0,=dataSize @ get datasize counter addr 
     ldr  r1,[r0,#0]  @ get val 
     add  r1,r1,#1  @ increment datasize counter 
     str  r1,[r0,#0]  @ store counter 
     cmp  r6,#16   @ compare with 16 (i=0;i<16;i++) 
     bne  outloop 
     pop  {r4-r7} 
     bx  lr 



    .section .rodata 
     sineLUT: 
     @ Array goes in here. Type can be .byte, .hword or .word 
     @ NOTE! No comma at the end of a line! This is important 

    .word 0x0000,0x000c,0x0018,0x0024,0x0030,0x003c,0x0048,0x0054 
    .word 0x0064,0x0070,0x007c,0x0088,0x0094,0x00a0,0x00ac,0x00bc 
    .word 0x00c8,0x00d4,0x00e0,0x00ec,0x00f8,0x0104,0x0114,0x0120 
    .word 0x012c,0x0138,0x0144,0x0150,0x015c,0x016c,0x0178,0x0184 
    .word 0x0190,0x019c,0x01a8,0x01b4,0x01c4,0x01d0,0x01dc,0x01e8 
    .word 0x01f4,0x0200,0x020c,0x021c,0x0228,0x0234,0x0240,0x024c 
    .word 
1

कुछ जवाब अपने प्रश्नों के पुस्तक "एआरएम वास्तुकला के लिए प्रक्रिया कॉल मानक" में हैं काम करता है की कोशिश की है। यहां link है।

पुस्तक का कहना है कि पहले चार रजिस्टरों r0-R3 (और एफपीयू के लिए s0-15) एक सबरूटीन में तर्क मान पास करने के लिए और एक समारोह से एक परिणाम मान देने के लिए उपयोग किया जाता है। इन्हें नियमित रूप से मध्यवर्ती मूल्यों को रखने के लिए भी उपयोग किया जा सकता है (लेकिन, सामान्य रूप से, केवल सबराउटिन कॉल के बीच)। पंजीयक आर 4-आर 8, आर 10 और आर 11 (और एफपीयू के लिए एस 16-एस31) नियमित रूप से स्थानीय चर के मूल्यों को पकड़ने के लिए उपयोग किए जाते हैं। एक subroutine इस रजिस्टरों की सामग्री को संरक्षित करना चाहिए।

अब volatile के बारे में। मुझे लगता है कि हाँ, आपको इसका उपयोग कंपाइलर ऑप्टिमाइज़ेशन को रोकने के लिए करना चाहिए जो प्रोग्राम प्रोग्राम को 'ब्रेक' कर सकता है।

और आपके साइन के बारे में। अंग्रेजी मेरी प्राकृतिक भाषा नहीं है, इसलिए मुझे समझ में नहीं आता कि आपको क्या चाहिए, लेकिन अगर आपको अपनी समस्या के हिस्से के रूप में कुछ तेज़ और सटीक साइन अपरिपक्वता की आवश्यकता है, तो आपको इस लेख में रुचि हो सकती है: http://devmaster.net/forums/topic/4648-fast-and-accurate-sinecosine/ http: //www.coranac। कॉम/2009/07/जीवाओं /।

और अंतिम। मैं लगभग कॉर्टेक्स-एम 4 के लिए अपने साइन सन्निकटन समारोह समाप्त कर चुका हूँ। यह एफपीयू का उपयोग करता है, लगभग 30 चक्र लेता है और एकल फ्लोटिंग पॉइंट रेंज में ज़ीरो त्रुटि परिणाम लाता है।

+0

टिप्पणियों के लिए धन्यवाद। साइन के बारे में मैं एक टेबल का उपयोग कर रहा हूं क्योंकि यह अभी मेरे लिए सबसे तेज़ तरीका है। मुझे टिप्पणियों के लिए धन्यवाद 384 साइन –

+0

उत्पन्न करने की आवश्यकता है। साइन के बारे में मैं एक टेबल का उपयोग कर रहा हूं क्योंकि यह अभी मेरे लिए सबसे तेज़ तरीका है। मैं योजक संश्लेषण पर काम कर रहा हूं और 48k नमूना दर के लिए प्रत्येक के लिए 24 साइन लहरों और एडीएसआर लिफाफे उत्पन्न करने में सक्षम होना चाहिए ताकि गति बहुत महत्वपूर्ण हो। –

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