मैं माइक्रो-नियंत्रक हैकिंग में जा रहा हूं और जब मैं बिटवाई ऑपरेटरों के साथ बहुत सहज हूं और हार्डवेयर के ठीक से बात कर रहा हूं, तो मुझे परिणामस्वरूप कोड बहुत वर्बोज़ और बॉयलरप्लेट मिल रहा है। मेरे में उच्च स्तर का प्रोग्रामर इसे साफ करने के लिए एक प्रभावी लेकिन कुशल तरीका खोजना चाहता है।ए सी प्रीप्रोसेसर मैक्रो एक बाइट में बिटफील्ड पैक करने के लिए?
उदाहरण के लिए, रजिस्टरों में स्थापित करने के झंडे के लिए बहुत कुछ है:
/* Provided by the compiler */
#define SPIE 7
#define SPE 6
#define DORD 5
#define MSTR 5
#define CPOL 4
#define CPHA 3
void init_spi() {
SPCR = (1 << SPE) | (1 << SPIE) | (1 << MSTR) | (1 << SPI2X);
}
शुक्र है वहाँ मैक्रो कि वास्तविक पोर्ट आईओ परिचालन (बाएं हाथ की ओर) को छिपाने के हैं, तो यह एक सरल काम की तरह लग रहा है। लेकिन मेरे लिए यह वाक्यविन्यास गन्दा है।
आवश्यकताओं हैं:
- यह केवल 8 बिट को संभाल करने के लिए है,
- बिट पदों में सक्षम होना चाहिए किसी भी क्रम में पारित होने के लिए, और
- केवल सेट की आवश्यकता होती है चाहिए बिट्स होने के लिए बीतने के।
वाक्य रचना मैं चाहता है:
SPCR = बिट्स (एसपीई, SPIE, MSTR, SPI2X);
सबसे अच्छा मैं अब तक लेकर आए हैं एक कॉम्बो मैक्रो/समारोह है:
#define bits(...) __pack_bits(__VA_ARGS__, -1)
uint8_t __pack_bits(uint8_t bit, ...) {
uint8_t result = 0;
va_list args;
va_start(args, bit);
result |= (uint8_t) (1 << bit);
for (;;) {
bit = (uint8_t) va_arg(args, int);
if (bit > 7)
break;
result |= (uint8_t) (1 << bit);
}
}
यह मेरा विशेष आर्किटेक्चर पर 32 बाइट्स संकलित करता है तथा निष्पादित करने के लिए 61-345 चक्र लेता है (कितने पर निर्भर करता है बिट्स पास हुए थे)।
आदर्श रूप से यह प्रीप्रोसेसर में किया जाना चाहिए क्योंकि परिणाम निरंतर है, और आउटपुट मशीन निर्देशों को केवल एक रजिस्टर के लिए 8 बिट मान का असाइनमेंट होना चाहिए।
क्या यह बेहतर किया जा सकता है?
कि शायद है मैं क्या कर सकता है, तो नहीं बिट स्थिति परिभाषाओं पहले से ही वास्तुकला विशिष्ट संकलक समर्थन से परिभाषित किया जा रहा के लिए (में, इस मामले avr-gcc)। मुझे लगता है कि सुंदर गूंगा। यदि कहीं भी है तो उन्हें बाएं-शिफ्ट तर्क के अलावा अन्य उपयोग किया जाना चाहिए ... मुझे यह नहीं मिल रहा है। पर अब जो है वो है। –
इसके अलावा, मैंने जो कोड देखा है, वह अब तक << XX फ़ॉर्म का उपयोग करके और _BV (XX) का उपयोग करने के बीच भिन्न होता है। _BV एक प्रदत्त मैक्रो है जो (1 << n) करता है। लेकिन इसका अभी भी बहुत अधिक टाइपिंग का मतलब है। –
अच्छा विचार। लेकिन सुरक्षा कारणों से, मैं एन # बीआईटी (एन) (1 << (एन)) परिभाषित करता हूं, मैक्रोज़ बुरा हो सकता है। बीआईटी (5-1) के साथ मैक्रो का उपयोग कर किसी की कल्पना करें ... – Roland