تحديد معدل باود غير قياسي للمنفذ التسلسلي الافتراضي FTDI تحت Linux

StackOverflow https://stackoverflow.com/questions/3192478

سؤال

لديّ جهاز USB أحاول التواصل معه أكثر من منفذ تسلسلي افتراضي توفره وحدة Kernel FTDI_SIO. ومع ذلك ، أواجه بعض المتاعب في ضبط معدل باود للمنفذ إلى 14400:

  • termios.h لا تحدد ثابتًا لـ 14400 ، لذلك لا يمكنني استخدامه cfsetispeed و cfsetospeed.
  • في مصدر وحدة Kernel FTDI_SIO ، تم ضبط قاعدة Baud على 24000000 ولا يبدو أن هناك طريقة لتغييرها. هذا يعني أنه لا يمكنني استخدام مقسوم مخصص مع TIOCSSERIAL IOCTL والحصول على معدل باود 14400 بهذه الطريقة.
  • يحتوي مصدر الوحدة على تعليق مما يجعله يبدو وكأنه ضبط alt_speed عضو في tty_struct بنية المنفذ إلى 14400 سيفعل ما أريد ، ولكن لا يبدو أن هناك أي طريقة لتعيينه على 14400 بالنظر إلى الواجهات الموجودة.

هل اي منكم لديه اي فكره عن هذا؟ سيكون من السهل جدًا إصلاح هذا عن طريق اختراق وحدة Kernel ، لكنني أبحث حقًا عن حل لا يتطلب تغييرات kernel.

هل كانت مفيدة؟

المحلول

لا يمكنك تغيير قاعدة Baud ، أفترض أنها تتعلق بالأجهزة. لذا فإن العبث بالوحدة لن يكون جيدًا. في النقطة الثالثة ، تتحدث فقط عن الطريقة الأولى المقترحة لإعداد باودات مخصصة ، حيث تحتاج إلى الوصول إلى tty->alt_speed. يبدو أنه لا توجد واجهة لتعيين Tty Struct مباشرة من WervePace ، على الأقل ليس مع برنامج تشغيل FTDI_SIO.
ومع ذلك ، هناك طريقة أخرى موضحة في التعليقات:

     * 3. You can also set baud rate by setting custom divisor as follows
     *    - set tty->termios->c_cflag speed to B38400
     *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as
     *      follows:
     *      o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST
     *      o custom_divisor set to baud_base / your_new_baudrate

هل جربته ؟

نصائح أخرى

يعمل حل Shodanex مع أطياف NDI Polaris (Baud 1.2Mbps) تحت Linux. كما هو محدد ، افتح الجهاز التسلسلي (/dev/ttyusb0) مع B38400 ،

int port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
tcgetattr(port,&g_initialAtt);// save this to restore later
newAtt=g_initialAtt;
newAtt.c_cflag = B38400 | CS8 | CLOCAL | CREAD; 
cfmakeraw(&newAtt);
tcsetattr(port,TCSANOW,&newAtt);

ثم تنفذ:

if(ioctl(port, TIOCGSERIAL, &sstruct) < 0){
    printf("Error: could not get comm ioctl\n"); 
    exit(0); 
}
sstruct.custom_divisor = custDiv;
//sstruct.flags &= 0xffff ^ ASYNC_SPD_MASK; NO! makes read fail.
sstruct.flags |= ASYNC_SPD_CUST; 
if(ioctl(port, TIOCSSERIAL, &sstruct) < 0){
    printf("Error: could not set custom comm baud divisor\n"); 
    exit(0); 
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top