2011-01-12 8 views
7

पर आरएस 232 संचार में उच्च देरी मुझे एक पीएक्सए 270 आरआईएससी पीसी/104 पर आरएस 232 संचार में एक लंबी देरी (1.5 एमएमएस - 9.5 एमएमएस) का अनुभव हो रहा है। मैं लंबे विलंब को कम करना चाहता हूं लेकिन मैं एम्बेडेड डिवाइस और सी ++ के साथ शुरुआत कर रहा हूं, इसलिए मुझे लगता है कि मुझे कुछ याद आ रहा है।एक PXA270

उल्लिखित देरी उस समय है जब पीएक्सए बोर्ड को बाहरी डिवाइस से आरएस 232 (115200 बॉड) के माध्यम से एक पैकेट प्राप्त होता है जब तक वह बाहरी डिवाइस पर एसीके कस्टम पैकेट वापस नहीं भेजता। मैंने पीएक्सए बोर्ड पर एक ऑसिलोस्कोप के साथ देरी, आरएक्स पर एक चैनल और दूसरा टीएक्स पर मापा।

पीएक्सए बोर्ड Arcom Embedded Linux (एईएल) चला रहा है। मुझे पता है, यह एक वास्तविक समय ओएस नहीं है, लेकिन मुझे अभी भी लगता है कि प्राप्तकर्ता पैकेट निकालने के लिए 4.5 एमएमएस की औसत देरी बहुत अधिक है, इसे सीआरसी 16 सत्यापित करें, एक एसीके पैकेट (सीआरसी के साथ) बनाएं और इसे भेजें सीरियल लाइन वापस। मैंने जानबूझकर सीपीयू को भारी भार (कुछ समांतर gzip संचालन) के तहत रखा लेकिन देरी का समय बिल्कुल बढ़ता नहीं था। प्राप्त पैकेट का अधिकतम आकार 30 बाइट है।

ए सी ++ एप्लिकेशन (एक अन्य पूर्व सहकर्मी इसे लिखा) पैकेट और उनकी पावती के स्वागत को संभालने में कामयाब रहा है। एक धागा भेज रहा है और दूसरा पैकेट प्राप्त कर रहा है।

मैंने सोचा कि पीएक्सए बोर्ड पर आरटीसी का बहुत बुरा संकल्प है और एईएल आंतरिक आरटीसी संकल्प के समय को संरेखित नहीं कर सकता है। लेकिन आरटीसी की आवृत्ति 32.768 केएचजेड है। संकल्प पर्याप्त है, फिर भी उच्च देरी की व्याख्या नहीं करते हैं। बीटीडब्ल्यू, मुझे लगता है कि ओएस समय के लिए आरटीसी के बजाय आंतरिक पीएक्सए घड़ी (जिसमें एक पर्याप्त संकल्प भी है) का उपयोग कर रहा है।

इसलिए समस्या सी ++ ऐप में या आरएस 232 इंटरफ़ेस के ड्राइवर/ओएस सेटिंग में होना चाहिए।

निम्नलिखित नियंत्रण झंडे Serial Programming Guide for POSIX Operating Systems के अनुसार सी ++ आवेदन में RS232 संचार के लिए इस्तेमाल कर रहे हैं:

// Open RS232 on COM1 
mPhysicalComPort = open(aPort, O_RDWR | O_NOCTTY | O_NDELAY); 
// Force read call to block if no data available 
int f = fcntl(mPhysicalComPort, F_GETFL, 0); 
f &= ~O_NONBLOCK; 
fcntl(mPhysicalComPort, F_SETFL, f); 
// Get the current options for the port... 
tcgetattr(mPhysicalComPort, &options); 
// ... and set them to the desired values 
cfsetispeed(&options, baudRate); 
cfsetospeed(&options, baudRate); 
// no parity (8N1) 
options.c_cflag &= ~PARENB; 
options.c_cflag &= ~CSTOPB; 
options.c_cflag &= ~CSIZE; 
options.c_cflag |= CS8; 
// disable hardware flow control 
options.c_cflag &= ~CRTSCTS; 
// raw input 
options.c_lflag = 0; 
// disable software flow control 
options.c_iflag = 0; 
// raw output 
options.c_oflag = 0; 
// Set byte times 
options.c_cc[VMIN] = 1; 
options.c_cc[VTIME] = 0; 
// Set the new options for the port 
tcsetattr(mPhysicalComPort, TCSAFLUSH, &options); 
// Flush to put settings to work 
tcflush(mPhysicalComPort, TCIOFLUSH); 

मुझे लगता है कि मैं बहुत ही सरल कुछ याद कर रहा हूँ। मुझे लगता है कि अगर ऐप की प्रक्रिया उच्च प्राथमिकता के तहत चल रही है, तो इससे समस्या हल नहीं होगी। कुछ ऐसा होना चाहिए, जो विलंबता को कम करने के लिए उच्च प्राथमिकता वाले अनुरोधों को संभालने के लिए RS232 ड्राइवर को निर्देशित करता है।

क्या किसी के पास कोई विचार है? आपकी मदद के लिए अग्रिम धन्यवाद।

+0

आप हर चार के लिए इन देरियों हैं, या अपने इनपुट आता है जब वहाँ एक \ इनपुट में या बफर भरा हुआ है? धारावाहिक चालक के शीर्ष पर कुछ टर्मिनल से संबंधित सामान हैं, जो आपके समय के साथ अनुमान लगा सकते हैं। – Rudi

+0

देरी हर चार के लिए नहीं होती है। ऐसा होता है, जब पूरा पैकेट (~ 30 बाइट) प्राप्त होता है, जब तक एसीके पैकेट वापस नहीं भेजा जाता है। – saxos

+1

1. कृपया हमें वह कोड दिखाएं जहां आप प्रतीक्षा करते हैं और बंदरगाह से पढ़ते हैं। 2. हमें 'अपटाइम' का आउटपुट दिखाएं (शायद आपका सिस्टम ओवरलोड हो गया है?) 3. क्या आपके लिनक्स में फास्ट कॉन्टेक्स्ट स्विच एक्सटेंशन (lwn.net/images/conf/rtlws11/papers/proc/p01.pdf) है? PXA270 के बिना ~ 0.5ms के संदर्भ स्विच देरी हो सकती है। – atzz

उत्तर

8

आपकी टिप्पणियों के लिए बहुत बहुत धन्यवाद।

मैं देरी को ~ 0.4ms तक कम करने में सक्षम था। आदेश setserial(8) को एईएल मैनुअल में संदर्भित किया गया था। और बिंगो, मैं low_latency झंडा वहाँ निम्नलिखित विवरण के साथ पाया:

कम से कम ग्रेटर CPU उपयोग की कीमत पर धारावाहिक डिवाइस के विलंबता प्राप्त करते हैं। (इससे पहले कि पात्रों भूमि के ऊपर कम करने के लिए लाइन discpline को हस्तांतरित कर दिया जाता है आम तौर पर वहाँ 5-10ms विलंबता के औसत है।) यह डिफ़ॉल्ट रूप से बंद है, लेकिन कुछ वास्तविक समय अनुप्रयोगों इस उपयोगी मिल सकता है।

मैंने फिर setserial /dev/ttyS1 low_latency निष्पादित किया और देरी घटाकर ~ 0 कर दी गई।4ms :-)

लेकिन मैं इस व्यवहार को सी ++ ऐप में कार्यान्वित करना चाहता था, इस ध्वज को सेटरियल के साथ विश्व स्तर पर सेट किए बिना (यह आदेश डिफ़ॉल्ट रूप से सभी distros में शामिल नहीं है)।

मैं निम्नलिखित कोड लाइनों, जो setserial से low_latency ध्वज के रूप में एक ही प्रभाव नहीं पड़ा जोड़ दिया है:

#include <sys/ioctl.h> 
#include <linux/serial.h> 
// Open RS232 on COM1 
mPhysicalComPort = open(aPort, O_RDWR | O_NOCTTY | O_NDELAY); 
struct serial_struct serial; 
ioctl(mPhysicalComPort, TIOCGSERIAL, &serial); 
serial.flags |= ASYNC_LOW_LATENCY; // (0x2000) 
ioctl(mPhysicalComPort, TIOCSSERIAL, &serial); 
+0

उच्च CPU उपयोग के माध्यम से कम विलंबता: क्या इसका मतलब है कि ओएस को सीरियल पोर्ट को किसी तरह से मतदान करना है? – stijn

+0

मुझे सटीक आंतरिक पता नहीं है। मैंने कुछ पढ़ा है, कि low_latency ध्वज के साथ डेटा को हार्ड बाधा संदर्भ पर tty परत में धक्का दिया जाता है, जिसमें नरम बाधा से बहुत अधिक प्राथमिकता होती है। मैं बिल्कुल CPU उपयोग में वृद्धि नहीं कर रहा हूं (मेरे परिदृश्य के लिए)। – saxos