सी मानक पुस्तकालय नंगे धातु पर


24

मैं ज्यादातर उन उपकरणों पर विकास कर रहा हूं जिन्होंने लिनक्स को पोर्ट किया है इसलिए मानक सी लाइब्रेरी सिस्टम कॉल को लागू करने के माध्यम से बहुत सारी कार्यक्षमता प्रदान करती है जिसमें एक मानकीकृत व्यवहार होता है।

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


4
आपके प्रश्न के लिए गलत साइट।
ott--

8
मैं इस प्रश्न को ऑफ-टॉपिक के रूप में बंद करने के लिए मतदान कर रहा हूं क्योंकि यह स्टैक ओवरफ्लो पर आधारित है
uint128_t

1
आम तौर पर आप बिना करते हैं। उन्हें समर्थन देने के लिए आपको ऑपरेटिंग सिस्टम के बिना ऐसी चीजों की आवश्यकता क्यों होगी? यादगार और ऐसा यकीन है। फ़ाइल सिस्टम, आवश्यक नहीं, हालांकि कार्यान्वित फोपेन, बंद, आदि उदाहरण के लिए राम के खिलाफ तुच्छ है। प्रिंटफ () बहुत बहुत भारी है, टन और आवश्यक टन के टन, बिना करें। कोई भी I / O प्रतिस्थापित करता है या बिना करता है। newlib बहुत चरम है, लेकिन अगर आप बिना मदद नहीं कर सकते हैं, लेकिन आपको बैकएंड पर सिस्टम को वैसे भी लागू करना होगा, तो क्या आपको अतिरिक्त परत की आवश्यकता है?
Old_timer

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

1
जबकि उत्तर में newlib का उल्लेख किया गया है, आप newlib-nano को उपयोगी भी पा सकते हैं - इसका उद्देश्य संसाधन की कमी वाले एम्बेडेड सिस्टम में उपयोग के लिए एक स्ट्रिप्ड -बैक संस्करण होना चाहिए। मैं इसका उपयोग Cortex M0 MCUs की परियोजनाओं में करता हूं। कई संकलक (एटॉलिक ट्रूस्टुडिओ एक होने के नाते) न्यूलिब या न्यूलिब-नैनो का उपयोग करने का विकल्प देगा।
jjmilburn

जवाबों:


20

हां, एक मानक है, बस सी मानक पुस्तकालय । पुस्तकालय के कार्यों के लिए "पूर्ण विकसित" ओएस या किसी भी ओएस की आवश्यकता नहीं होती है, और "नंगे धातु" कोड के अनुरूप कई कार्यान्वयन हैं, न्यूलिब शायद सबसे अच्छी तरह से जाना जाता है।

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

यदि आप लिनक्स का उपयोग कर रहे हैं (शायद OSX और शायद साइबर / एमएसआई भी?) और टाइप करें man strlen, तो इसमें एक खंड होना चाहिए CONFORMING TO, जैसे कुछ , जो आपको बताएगा कि कार्यान्वयन एक विशिष्ट मानक के अनुरूप है। इस तरह से आप यह पता लगा सकते हैं कि आप जो उपयोग कर रहे हैं वह एक मानक फ़ंक्शन है या यदि यह किसी विशिष्ट ओएस पर निर्भर करता है।


1
मैं कैसे ओएस पर निर्भर होने के बिना एक stdlibऔजार के रूप में उत्सुक हूँ stdio। जैसे fopen(), fclose(), fread(), fwrite(), putc()और getc()? और malloc()ओएस से बात किए बिना कैसे काम करता है ?
रॉबर्ट ब्रिस्टो-जॉनसन

4
न्यूलिब के साथ, नीचे एक परत है, जिसे "लिबग्लॉस" कहा जाता है, जिसमें आपके प्लेटफॉर्म पर कुछ दर्जन फ़ंक्शन शामिल हैं (या आप लिखते हैं)। उदाहरण के लिए, एक getcharऔर putcharजो आपके हार्डवेयर के UART के बारे में जानता है; फिर इनमें printfसे ऊपर Newlib लेयर्स । फ़ाइल I / O इसी तरह कुछ आदतों पर निर्भर करेगा।
ब्रायन ड्रमंड बाद

हाँ, मैंने पाइप के 2 पैरा को ध्यान से नहीं पढ़ा। के साथ काम करने के अलावा stdinऔर stdoutऔर stderr (जो का ख्याल रखता है putchar()और getchar()) जो मैं एक UART के लिए निर्देशित होता / / से हे, यदि आपके मंच एक फ्लैश के साथ की तरह, फ़ाइल भंडारण है, तो आप भी उस के लिए लिखने गोंद करने के लिए है। और आप के लिए साधन के लिए है malloc()और free()। मुझे लगता है कि यदि आप उन मुद्दों का ध्यान रखते हैं, तो आप अपने एम्बेडेड लक्ष्य (न argvही argc) में पोर्टेबल सी को बहुत अधिक चला सकते हैं ।
रॉबर्ट ब्रिस्टो-जॉनसन

2
यदि आप MCU के साथ कोड स्थान के 1 या 2kB के साथ काम कर रहे हैं तो Newlib बहुत बड़ा है ...
ब्रायन ड्रमंड बाद

2
@dwelch आप अपना खुद का OS नहीं बना रहे हैं, आप C लाइब्रेरी बना रहे हैं। यदि आप ऐसा नहीं चाहते हैं, तो हाँ, यह अनावश्यक बड़ा है।
पाइप

8

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

सबसे पहले, सी मानक "फ्रीस्टैंडिंग" कार्यान्वयन नामक कुछ को परिभाषित करता है, "होस्टेड" कार्यान्वयन के विपरीत (जो कि हम में से अधिकांश परिचित हैं, अंतर्निहित ओएस द्वारा समर्थित सी फ़ंक्शन की पूरी श्रृंखला)।

एक "फ्रीस्टैंडिंग" कार्यान्वयन को केवल सी लाइब्रेरी हेडर के एक उपसमूह को परिभाषित करने की आवश्यकता है, अर्थात जिन्हें समर्थन की आवश्यकता नहीं है, या यहां तक ​​कि कार्यों की परिभाषा (वे केवल #defineएस और typedefएस करते हैं):

  • <float.h>
  • <iso646.h>
  • <limits.h>
  • <stdalign.h>
  • <stdarg.h>
  • <stdbool.h>
  • <stddef.h>
  • <stdint.h>
  • <stdnoreturn.h>

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

  • getenv()( extern char * * environ)
  • system()( fork()/ execve()/ wait())
  • malloc()और free()( brk()/ sbrk())
  • _Exit()( _exit())
  • time() (अभी तक लागु नहीं किया)

और <stdio.h>(निश्चित रूप से C99 हेडर के सबसे "OS- शामिल"):

  • फ़ाइल खोलने का कोई तरीका ( open())
  • इसे बंद करने का कोई तरीका ( close())
  • इसे हटाने का कोई तरीका ( unlink())
  • इसका नाम बदलने का कोई तरीका ( link()/ unlink())
  • इसे लिखने का कुछ तरीका ( write())
  • इससे पढ़ने का कोई तरीका ( read())
  • किसी तरह से इसके भीतर ( lseek())

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

  • time()समारोह कानूनी तौर पर सिर्फ वापस आ सकते हैं (time_t)-1यदि कोई समय-कीपिंग यांत्रिकी उपलब्ध हैं।

  • <signal.h>आवश्यकता के लिए वर्णित सिग्नल हैंडलर को कॉल के अलावा किसी अन्य चीज से नहीं बुलाया जाता है raise(), इस बात की कोई आवश्यकता नहीं है कि सिस्टम वास्तव में एप्लिकेशन को कुछ भेजता है SIGSEGV

  • C11 हेडर <threads.h>, जो (स्पष्ट कारणों के लिए) OS पर बहुत निर्भर है, यदि कार्यान्वयन परिभाषित करता है, तो बिल्कुल भी प्रदान करने की आवश्यकता नहीं है __STDC_NO_THREADS__...

और भी उदाहरण हैं, लेकिन अभी मेरे पास उनके हाथ नहीं हैं।

बाकी पुस्तकालय को पर्यावरण की मदद के बिना लागू किया जा सकता है। (*)


(*) कैविएट: PDCLib का कार्यान्वयन अभी पूरा नहीं हुआ है, इसलिए मैंने एक या दो चीजों की अनदेखी की होगी। ;-)


4

मानक सी वास्तव में ऑपरेटिंग वातावरण से अलग परिभाषित किया गया है। होस्ट OS के मौजूद होने के बारे में कोई धारणा नहीं बनाई गई है, और जो हिस्से होस्ट आश्रित हैं, उन्हें इस तरह परिभाषित किया गया है।

यही है, सी मानक पहले से ही बहुत नंगे धातु है।

बेशक, उन भाषा भागों को हम बहुत प्यार करते हैं, पुस्तकालय, अक्सर होते हैं जहां मुख्य भाषा उस विशिष्ट सामग्री को होस्ट करती है। इसलिए, कई नंगे धातु प्लेटफ़ॉर्म टूल के लिए विशिष्ट "xxx-lib" क्रॉस कंपाइलर सामान मिला।


3

न्यूलिब न्यूनतम रननीय उदाहरण

यहां मैं एक अत्यधिक स्वचालित और प्रलेखित उदाहरण प्रदान करता हूं जो QEMU में कार्रवाई में न्यूलिब दिखाता है

Newlib के साथ, आप अपने नंगे प्लेटफॉर्म के लिए अपने सिस्टम कॉल को लागू करते हैं।

उदाहरण के लिए, उपरोक्त उदाहरण पर, हमारे पास एक उदाहरण कार्यक्रम है exit.c:

#include <stdio.h>
#include <stdlib.h>

void main(void) {
    exit(0);
}

और एक अलग सी फ़ाइल में common.c, हम एआरएम सेमीहोस्टिंग के exitसाथ लागू करते हैं :

void _exit(int status) {
    __asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
}

अन्य विशिष्ट syscalls जिन्हें आप लागू करेंगे:

  • writeहोस्ट को परिणाम देने के लिए। यह या तो साथ किया जा सकता है:

    • अधिक अर्धचालक
    • एक UART हार्डवेयर
  • brkके लिए malloc

    नंगे पैर पर आसान, क्योंकि हमें पेजिंग की परवाह नहीं है!

TODO मुझे आश्चर्य है कि अगर Zephyr या FreeRTOS जैसे पूर्ण विकसित RTOS में जाए बिना प्रीमेप्टिव शेड्यूलिंग syscalls निष्पादन तक पहुंचना यथार्थवादी है ।

न्यूलिब के बारे में अच्छी बात यह है कि यह आपके लिए सभी गैर-ओएस विशिष्ट चीजों को लागू करता है string.h, और आपको बस ओएस स्टब्स को लागू करने देता है।

इसके अलावा, आपको सभी स्टब्स को लागू करने की आवश्यकता नहीं है, लेकिन केवल उन लोगों की आवश्यकता होगी जो आपको चाहिए। उदाहरण के लिए, यदि आपके प्रोग्राम को केवल जरूरत है exit, तो आपको ए प्रदान करने की आवश्यकता नहीं है print

न्यूलिब स्रोत के पेड़ में पहले से ही कुछ कार्यान्वयन हैं, जिनमें एआरएम सेमीहोस्टिंग कार्यान्वयन शामिल है newlib/libc/sys/arm, लेकिन अधिकांश भाग के लिए आपको स्वयं को लागू करना होगा। हालांकि यह कार्य के लिए एक ठोस आधार प्रदान करता है।

न्यूलिब को सेटअप करने का सबसे आसान तरीका है क्रॉस्स्टूल-एनजी के साथ अपने स्वयं के कंपाइलर का निर्माण करना, आपको बस यह बताना होगा कि आप न्यूलिब को सी लाइब्रेरी के रूप में उपयोग करना चाहते हैं। मेरा सेटअप आपके लिए इस स्क्रिप्ट के साथ स्वचालित रूप से हैंडल करता है, जो कि यहां मौजूद newlib config का उपयोग करता है crosstool_ng_config

मुझे लगता है कि C ++ भी काम करेगी, लेकिन TODO इसका परीक्षण करेगा।


3
@downvoters: कृपया समझाएं ताकि मैं जानकारी सीख सकूं और सुधार सकूं। उम्मीद है कि भविष्य के पाठक वेब पर उपलब्ध एकमात्र परिचयात्मक न्यूलिब सेटअप का मूल्य देख सकते हैं, जो अभी काम करता है :-)
सिरो सेंटिल्ली Sant see see 六四

2

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


स्प्रिंटफ को मॉलोक () की आवश्यकता क्यों होनी चाहिए?
सुपरकैट

मुझे नहीं पता। मुझे लगता है कि आपकी बात यह है कि बफर पहले से ही है, है ना? लेकिन यहां तक ​​कि प्रिंटफ को भी मॉलोक की जरूरत नहीं होनी चाहिए। हो सकता है कि गतिशील रूप से कुछ आंतरिक चर का आवंटन करें, जब अनुरोधित आउटपुट की गणना खड़ी आवंटन (कार्य के गतिशील चर) की दूरदर्शिता से अधिक भारी हो? मुझे यकीन है कि स्प्रिंटफ को मल्लोच (हाथ-कोई-ईबी-न्यूलिब) की आवश्यकता नहीं थी। अब मैंने एक साधारण प्रोग्राम प्रयोग किया जो कंप्यूटर (स्प्रिब) पर स्प्रिंट का उपयोग करता है। इसे कभी भी मलोक नहीं कहा जाता है। फिर प्रिंटफ का इस्तेमाल किया। इसे मलोक कहा जाता है। मल्लोक नकली था, हमेशा वापस लौट रहा था 0. लेकिन यह ठीक काम कर रहा था। वे एक स्ट्रिंग और एक दशमलव चर मुद्रित करने के लिए थे। @supercat
ऐहान

मैंने अपने स्वयं के उपयोग किए गए प्रारूपों का समर्थन करने के लिए अनुकूलित करके स्वयं कुछ प्रिंटफ या इसी तरह की विधियों के संस्करण बनाए हैं। दशमलव उत्पादन में सबसे लंबे समय तक संभावित संख्या को धारण करने के लिए एक बफर की आवश्यकता होती है, लेकिन अन्यथा आधार दिनचर्या एक संरचना को स्वीकार करता है जिसका पहला सदस्य एक आउटपुट फ़ंक्शन है जो डेटा के साथ-साथ उस संरचना के लिए एक सूचक को भी आउटपुट करता है। इस तरह के डिज़ाइन से प्रिंटफ वेरिएंट को जोड़ना संभव हो जाता है जो शाप-शैली के कंसोल, सॉकेट्स इत्यादि को आउटपुट करता है, मुझे ऐसी चीज़ में "मॉलोक" की कभी आवश्यकता नहीं थी।
सुपर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.