unix_devs.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  1. /*
  2. * Copyright (C) 2000-2004 by ETH Zurich
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY ETH ZURICH AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ETH ZURICH
  21. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /* unix_devs.c - a nut/os device driver for native unix devices
  34. *
  35. * 2004.04.01 Matthias Ringwald <matthias.ringwald@inf.ethz.ch>
  36. *
  37. * \todo check block read implementation
  38. * \todo allow native filee accesss using names like "FAT_C:/.." \see fs/fat.c
  39. * \todo implement cooked mode and use it as default mode
  40. *
  41. */
  42. /* avoid stdio nut wrapper */
  43. #define NO_STDIO_NUT_WRAPPER
  44. #include <fcntl_orig.h>
  45. #include <arch/unix.h>
  46. #include <sys/atom.h>
  47. #include <sys/device.h>
  48. #include <sys/file.h>
  49. #include <sys/timer.h>
  50. #include <sys/thread.h>
  51. #include <sys/event.h>
  52. #include <dev/usart.h>
  53. #include <dev/irqreg.h>
  54. #include <errno.h>
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <unistd.h>
  59. #include <termios.h>
  60. #include <dev/unix_devs.h>
  61. // for sockets
  62. #include <sys/types.h>
  63. #include <sys/socket.h> //
  64. #include <netinet/in.h> //
  65. #include <arpa/inet.h> //
  66. #include <netdb.h>
  67. #include <sys/uio.h>
  68. #include <unistd.h>
  69. #include <string.h>
  70. #ifdef __CYGWIN__
  71. #include <sys/select.h>
  72. #endif
  73. /* on mac os x, not all baud rates are defined in termios.h but
  74. they are mapped to the numeric value anyway, so we define them here */
  75. #ifdef __APPLE__
  76. #ifndef B460800
  77. #define B460800 460800
  78. #endif
  79. #ifndef B500000
  80. #define B500000 500000
  81. #endif
  82. #ifndef B576000
  83. #define B576000 576000
  84. #endif
  85. #ifndef B921600
  86. #define B921600 921600
  87. #endif
  88. #endif
  89. /* thread attributes */
  90. pthread_attr_t unix_devs_attr;
  91. /* protect thread signaling */
  92. pthread_mutex_t unix_devs_mutex;
  93. /* to get a new thread start acked'd */
  94. pthread_cond_t unix_devs_cv;
  95. /*
  96. * functions available on avr somehow -- not implemented properly here :(
  97. */
  98. char *dtostre(double f, char *str, uint8_t prec, uint8_t flags);
  99. char *dtostre(double f, char *str, uint8_t prec, uint8_t flags)
  100. {
  101. sprintf(str, "%e", f);
  102. return str;
  103. }
  104. char *dtostrf(double f, char width, char prec, char *str);
  105. char *dtostrf(double f, char width, char prec, char *str)
  106. {
  107. sprintf(str, "%f", f);
  108. return str;
  109. }
  110. /*
  111. * Quite unnecessary functions, because linux doesn't define B19200 as 19200
  112. * we have to map those value to their symbolic counterparts:
  113. * 0
  114. * 50
  115. * 75
  116. * 110
  117. * 134
  118. * 150
  119. * 200
  120. * 300
  121. * 600
  122. * 1200
  123. * 1800
  124. * 2400
  125. * 4800
  126. * 9600
  127. * 19200
  128. * 38400
  129. * 57600
  130. * 115200
  131. * 230400
  132. * 460800
  133. * 500000
  134. * 576000
  135. * 921600
  136. */
  137. static int convertToRealSpeed(int baudSpeed)
  138. {
  139. switch (baudSpeed) {
  140. case B0:
  141. return 0;
  142. case B50:
  143. return 50;
  144. case B75:
  145. return 75;
  146. case B110:
  147. return 110;
  148. case B134:
  149. return 134;
  150. case B150:
  151. return 150;
  152. case B200:
  153. return 200;
  154. case B300:
  155. return 300;
  156. case B600:
  157. return 600;
  158. case B1200:
  159. return 1200;
  160. case B1800:
  161. return 1800;
  162. case B2400:
  163. return 2400;
  164. case B4800:
  165. return 4800;
  166. case B9600:
  167. return 9600;
  168. case B19200:
  169. return 19200;
  170. case B38400:
  171. return 38400;
  172. case B57600:
  173. return 57600;
  174. case B115200:
  175. return 115200;
  176. case B230400:
  177. return 230400;
  178. #ifndef __CYGWIN__
  179. case B460800:
  180. return 460800;
  181. case B500000:
  182. return 500000;
  183. case B576000:
  184. return 576000;
  185. case B921600:
  186. return 921600;
  187. #endif
  188. }
  189. return -1;
  190. }
  191. static int convertToBaudSpeed(int realSpeed)
  192. {
  193. switch (realSpeed) {
  194. case 0:
  195. return B0;
  196. case 50:
  197. return B50;
  198. case 75:
  199. return B75;
  200. case 110:
  201. return B110;
  202. case 134:
  203. return B134;
  204. case 150:
  205. return B150;
  206. case 200:
  207. return B200;
  208. case 300:
  209. return B300;
  210. case 600:
  211. return B600;
  212. case 1200:
  213. return B1200;
  214. case 1800:
  215. return B1800;
  216. case 2400:
  217. return B2400;
  218. case 4800:
  219. return B4800;
  220. case 9600:
  221. return B9600;
  222. case 19200:
  223. return B19200;
  224. case 38400:
  225. return B38400;
  226. case 57600:
  227. return B57600;
  228. case 115200:
  229. return B115200;
  230. case 230400:
  231. return B230400;
  232. #ifndef __CYGWIN__
  233. case 460800:
  234. return B460800;
  235. case 500000:
  236. return B500000;
  237. case 576000:
  238. return B576000;
  239. case 921600:
  240. return B921600;
  241. #endif
  242. }
  243. return -1;
  244. }
  245. /* ======================= sockets ======================== */
  246. unsigned int resolve(char *);
  247. unsigned int resolve(char *ip_addr)
  248. {
  249. struct hostent *hp;
  250. unsigned int ip;
  251. hp = gethostbyname(ip_addr);
  252. if (!hp)
  253. {
  254. ip = inet_addr(ip_addr);
  255. if ((int)ip == -1) {
  256. return -1;
  257. } else {
  258. return ip;
  259. }
  260. }
  261. // hp->h_length should equal to 4
  262. memcpy(&ip, hp->h_addr, 4);
  263. return ip;
  264. }
  265. /*
  266. * IRQ Handler for correct signaling
  267. * not currently used (see UnixDevReadThread for more info on variants
  268. static void UnixDevRxIntr(void *arg){
  269. NUTDEVICE* dev = (NUTDEVICE*) arg;
  270. UNIXDCB * dcb = (UNIXDCB*) dev->dev_dcb;
  271. // printf("UnixDevRxIntr(%s)\n",dev->dev_name);
  272. NutEventPostFromIrq( &dcb->dcb_rx_rdy);
  273. }
  274. */
  275. /*
  276. * Read Thread
  277. *
  278. */
  279. static void *UnixDevReadThread( void * arg )
  280. {
  281. int ret;
  282. int fd;
  283. fd_set rfd_set;
  284. NUTDEVICE* dev = (NUTDEVICE*) arg;
  285. UNIXDCB * dcb = (UNIXDCB*) dev->dev_dcb;
  286. // fd
  287. fd = dcb->dcb_fd;
  288. if (fd == STDOUT_FILENO)
  289. fd = STDIN_FILENO;
  290. // non-nut thread => block IRQ signals
  291. pthread_sigmask(SIG_BLOCK, &irq_signal, 0);
  292. // printf("UnixDevReadThread() started\n");
  293. // be ready to receive requests
  294. pthread_mutex_lock(&dcb->dcb_rx_mutex);
  295. // confirm start
  296. pthread_mutex_lock(&unix_devs_mutex);
  297. pthread_cond_signal(&unix_devs_cv);
  298. pthread_mutex_unlock(&unix_devs_mutex);
  299. // printf("UnixDevReadThread(%s) start confirmed\n", dev->dev_name);
  300. //
  301. for (;;) {
  302. pthread_cond_wait(&dcb->dcb_rx_trigger, &dcb->dcb_rx_mutex);
  303. // printf("UnixDevReadThread(%s) triggered\n", dev->dev_name);
  304. // wait for data to become ready //
  305. do {
  306. FD_ZERO(&rfd_set);
  307. FD_SET(fd, &rfd_set);
  308. ret = select(fd + 1, &rfd_set, NULL, NULL, NULL);
  309. } while (FD_ISSET(fd, &rfd_set) == 0);
  310. // printf("UnixDevReadThread(%s) task processed\n", dev->dev_name);
  311. // signale waiting thread
  312. /* version 1 (working but could cause a race condition)
  313. NutEventPostAsync( &dcb->dcb_rx_rdy);
  314. */
  315. /* version 2 (correct, but currently very slow)
  316. if (dev->dev_name[4] == '0') {
  317. NutIRQTrigger(IRQ_UART0_RX);
  318. } else {
  319. NutIRQTrigger(IRQ_UART1_RX);
  320. }*/
  321. /* version 3 (another hack, but fast and correct */
  322. switch (dev->dev_name[4]) {
  323. case '0':
  324. NutUnixIrqEventPostAsync( IRQ_UART0_RX, &dcb->dcb_rx_rdy);
  325. break;
  326. case '1':
  327. NutUnixIrqEventPostAsync( IRQ_UART1_RX, &dcb->dcb_rx_rdy);
  328. break;
  329. case '2':
  330. NutUnixIrqEventPostAsync( IRQ_UART2_RX, &dcb->dcb_rx_rdy);
  331. break;
  332. }
  333. }
  334. return 0;
  335. }
  336. /*!
  337. * \brief Open UnixDev
  338. *
  339. * \return Pointer to a static NUTFILE structure.
  340. */
  341. static NUTFILE *UnixDevOpen(NUTDEVICE * dev, const char *name, int mode, int acc)
  342. {
  343. NUTFILE *nf;
  344. int nativeFile;
  345. char *nativeName;
  346. struct termios t;
  347. long baud;
  348. pthread_t *thread;
  349. // sockets
  350. struct sockaddr_in sinaddr;
  351. struct sockaddr_in remote;
  352. unsigned int remote_ip;
  353. unsigned int remote_port;
  354. char *ip;
  355. char *port;
  356. // char *idx;
  357. // map from dev->name to unix name
  358. if (strncmp("uart", dev->dev_name, 4) == 0) {
  359. // uart
  360. switch (dev->dev_name[4]) {
  361. case '0':
  362. nativeName = emulation_options.uart_options[0].device;
  363. break;
  364. case '1':
  365. nativeName = emulation_options.uart_options[1].device;
  366. break;
  367. case '2':
  368. nativeName = emulation_options.uart_options[2].device;
  369. break;
  370. default:
  371. return NULL;
  372. }
  373. } else
  374. return NULL;
  375. // check for sockets
  376. // try to split "device name" into ip:port
  377. if (strncmp("stdio", nativeName, 5)==0) {
  378. ip = nativeName;
  379. port = NULL;
  380. } else {
  381. ip = strtok( nativeName, ":");
  382. port = strtok ( NULL, ":");
  383. }
  384. // printf("UnixDevOpen: Nut name = %s, unix name = %s\n", dev->dev_name, nativeName);
  385. // determine mode -- not implemented yet
  386. // set default mode
  387. mode = O_RDWR | O_NOCTTY;
  388. // fopen unix device
  389. if (strcmp("stdio", nativeName) == 0) {
  390. nativeFile = STDOUT_FILENO;
  391. // make raw
  392. if (tcgetattr(nativeFile, &t) == 0) {
  393. /* set input mode (non-canonical, no echo,...) but allow INTR signal */
  394. // bzero(&t, sizeof(t));
  395. t.c_lflag = ISIG;
  396. t.c_cc[VTIME] = 0; /* inter-character timer unused */
  397. t.c_cc[VMIN] = 0; /* non-blocking read */
  398. // apply file descriptor options
  399. if (tcsetattr(nativeFile, TCSANOW, &t) < 0) {
  400. printf("UnixDevOpen: tcsetattr failed\n\r");
  401. }
  402. ((UNIXDCB*)dev->dev_dcb)->dcb_socket = 0;
  403. }
  404. } else if (port) {
  405. // tcp/ip socket
  406. remote_ip = resolve ( ip );
  407. remote_port = atoi( port );
  408. if ( ip ) {
  409. NutEnterCritical();
  410. // create socket
  411. nativeFile = socket(AF_INET, SOCK_STREAM, 0);
  412. // set inbound address
  413. sinaddr.sin_family = AF_INET;
  414. sinaddr.sin_addr.s_addr = INADDR_ANY;
  415. sinaddr.sin_port = htons(0);
  416. // bind to socket
  417. bind(nativeFile, (struct sockaddr *)&sinaddr, sizeof(sinaddr));
  418. // set remote address
  419. remote.sin_family = AF_INET;
  420. remote.sin_port = htons(remote_port);
  421. remote.sin_addr.s_addr = remote_ip;
  422. // try to connect
  423. if ( connect ( nativeFile, (struct sockaddr *)&remote, sizeof(remote) ) == 0) {
  424. // connected
  425. ((UNIXDCB*)dev->dev_dcb)->dcb_socket = 1;
  426. } else {
  427. NutExitCritical();
  428. printf( "UnixDevOpen: Connect to %s port %d failed (errno = %d)\n\r", ip, remote_port, errno);
  429. return NULL;
  430. }
  431. } else {
  432. NutExitCritical();
  433. printf("UnixDevOpen: Could not resolve IP address of '%s'!\n", ip);
  434. return NULL;
  435. }
  436. } else {
  437. nativeFile = open(nativeName, mode);
  438. if (nativeFile < 0) {
  439. printf("UnixDevOpen: open('%s',%d) failed!\n", nativeName, mode);
  440. return NULL;
  441. }
  442. /* flush pending data*/
  443. if (tcflush( nativeFile, TCIOFLUSH)) {
  444. printf("UnixDevOpen: tcflush('%s',%d) failed!\n", nativeName, TCIOFLUSH);
  445. return NULL;
  446. }
  447. if (tcgetattr(nativeFile, &t) == 0) {
  448. baud = convertToBaudSpeed(USART_INITSPEED);
  449. bzero(&t, sizeof(t));
  450. t.c_cflag = CS8 | CLOCAL | CREAD;
  451. t.c_iflag = IGNPAR;
  452. t.c_oflag = 0;
  453. cfsetospeed(&t, baud);
  454. cfsetispeed(&t, baud);
  455. /* set input mode (non-canonical, no echo,...) */
  456. t.c_lflag = 0;
  457. t.c_cc[VTIME] = 0; /* inter-character timer unused */
  458. t.c_cc[VMIN] = 0; /* non-blocking read */
  459. tcflush(nativeFile, TCIFLUSH);
  460. // apply file descriptor options
  461. if (tcsetattr(nativeFile, TCSANOW, &t) < 0) {
  462. printf("UnixDevOpen: tcsetattr failed\n\r");
  463. }
  464. }
  465. ((UNIXDCB*)dev->dev_dcb)->dcb_socket = 0;
  466. }
  467. if (nativeFile == 0)
  468. return NULL;
  469. // set non-blocking
  470. if (fcntl(nativeFile, F_SETFL, O_NONBLOCK) < 0) {
  471. printf("UnixDevOpen: fcntl O_NONBLOCK failed\n\r");
  472. }
  473. // store unix fd in dev
  474. ((UNIXDCB*)dev->dev_dcb)->dcb_fd = nativeFile;
  475. // printf("UnixDevOpen: %s, fd * %d\n\r", nativeName, nativeFile);
  476. // printf("UnixDevOpen: stdout %d, stdin %d, stderr %d \n\r", fileno(stdin), fileno(stdout), fileno(stderr));
  477. /* initialized rx IRQ handler -- not currently used (see UnixDevReadThread for more info on variants
  478. if (dev->dev_name[4] == '0') {
  479. NutRegisterIrqHandler(IRQ_UART0_RX, UnixDevRxIntr, dev);
  480. } else
  481. {
  482. NutRegisterIrqHandler(IRQ_UART1_RX, UnixDevRxIntr, dev);
  483. }
  484. */
  485. /* Initialize mutex and condition variable objects */
  486. pthread_mutex_init(&unix_devs_mutex, NULL);
  487. pthread_mutex_init(&((UNIXDCB*)dev->dev_dcb)->dcb_rx_mutex, NULL);
  488. pthread_attr_init(&unix_devs_attr);
  489. pthread_attr_setdetachstate(&unix_devs_attr, PTHREAD_CREATE_JOINABLE);
  490. // unix_devs_cv init
  491. pthread_cond_init(&unix_devs_cv, NULL);
  492. pthread_cond_init( &((UNIXDCB*)dev->dev_dcb)->dcb_rx_trigger, NULL);
  493. // get thread struct
  494. thread = malloc(sizeof(pthread_t));
  495. // lock mutex and start thread
  496. pthread_mutex_lock(&unix_devs_mutex);
  497. pthread_create(thread, &unix_devs_attr, UnixDevReadThread, dev);
  498. // printf("UnixDevOpen: %s, waiting for UnixDevRead ack\n\r", nativeName);
  499. // wait for ack
  500. pthread_cond_wait(&unix_devs_cv, &unix_devs_mutex);
  501. pthread_mutex_unlock(&unix_devs_mutex);
  502. // printf("UnixDevOpen: %s, ack from UnixDevRead received\n\r", nativeName);
  503. // create new NUTFILE using malloc
  504. nf = malloc(sizeof(NUTFILE));
  505. // enter data
  506. nf->nf_dev = dev;
  507. nf->nf_fcb = NULL;
  508. return nf;
  509. }
  510. /*!
  511. * \brief Blocking write bytes to file
  512. *
  513. * \return Number of characters sent.
  514. */
  515. static int UnixDevWrite(NUTFILE * nf, const void *buffer, int len)
  516. {
  517. int rc;
  518. int remaining = len;
  519. UNIXDCB * dcb = (UNIXDCB*) nf->nf_dev->dev_dcb;
  520. /* flush ? */
  521. if (len == 0)
  522. return 0;
  523. do {
  524. rc = write(dcb->dcb_fd, buffer, remaining);
  525. if (rc > 0) {
  526. buffer += rc;
  527. remaining -= rc;
  528. }
  529. } while (remaining > 0);
  530. return len;
  531. }
  532. /*!
  533. * \brief Read bytes from file
  534. *
  535. * \return Number of characters read.
  536. */
  537. static int UnixDevRead(NUTFILE * nf, void *buffer, int len)
  538. {
  539. int newBytes;
  540. int fd;
  541. fd_set rfd_set;
  542. int ret;
  543. struct timeval timeout;
  544. int rc = 0;
  545. UNIXDCB * dcb = (UNIXDCB*) nf->nf_dev->dev_dcb;
  546. // fd
  547. fd = dcb->dcb_fd;
  548. if (fd == STDOUT_FILENO)
  549. fd = STDIN_FILENO;
  550. // test for read len. len == 0 => flush fd
  551. if (len == 0){
  552. tcflush(fd, TCIFLUSH);
  553. return 0;
  554. }
  555. // printf("UnixDevRead: called: len = %d\n\r",len);
  556. timeout.tv_usec = 0;
  557. timeout.tv_sec = 0;
  558. do {
  559. // data available ?
  560. FD_ZERO(&rfd_set);
  561. FD_SET(fd, &rfd_set);
  562. ret = select(fd + 1, &rfd_set, NULL, NULL, &timeout);
  563. if (FD_ISSET(fd, &rfd_set) == 0) {
  564. // no data available. let's block the nut way...
  565. // printf("UnixDevRead(%s): no data ready, signaling read thread\n\r", nf->nf_dev->dev_name);
  566. // prepared signaling
  567. dcb->dcb_rx_rdy = 0;
  568. // lock mutex and signal read thread
  569. pthread_mutex_lock(&dcb->dcb_rx_mutex);
  570. pthread_cond_signal(&dcb->dcb_rx_trigger);
  571. pthread_mutex_unlock(&dcb->dcb_rx_mutex);
  572. // printf("UnixDevRead(%s): no data ready, waiting for answer\n\r", nf->nf_dev->dev_name);
  573. // wait for data to be ready
  574. NutEventWait( &dcb->dcb_rx_rdy, dcb->dcb_rtimeout);
  575. // printf("UnixDevRead(%s): got answer\n\r", nf->nf_dev->dev_name);
  576. }
  577. // printf("UnixDevRead(%s): before read\n\r", nf->nf_dev->dev_name);
  578. newBytes = read( fd, buffer, len);
  579. // printf("UnixDevRead(%s): read some bytes. res = %d\n\r", nf->nf_dev->dev_name, newBytes);
  580. /* error or timeout ? */
  581. if (newBytes < 0) {
  582. if (errno == EAGAIN) {
  583. // timeout. No data available right now
  584. // printf("UnixDevRead: no bytes available, trying again\n\r");
  585. errno = 0;
  586. continue;
  587. } else {
  588. printf("UnixDevRead: error %d occured, giving up\n\r", errno);
  589. return newBytes;
  590. }
  591. } else
  592. rc += newBytes;
  593. #ifdef UART_SETBLOCKREAD
  594. // printf("UnixDevRead: UART_SETBLOCKREAD defined\n\r");
  595. // check for blocking read: all bytes received
  596. if ( (dcb->dcb_modeflags & USART_MF_BLOCKREAD) && (rc < len)) {
  597. // printf("UnixDevRead: block read enabled, but not enough bytes read \n\r");
  598. continue;
  599. }
  600. #endif
  601. // did we get one?
  602. if (rc > 0)
  603. break;
  604. } while (1);
  605. return rc;
  606. }
  607. /*!
  608. * \brief Close ...
  609. *
  610. * \return Always 0.
  611. */
  612. static int UnixDevClose(NUTFILE * nf)
  613. {
  614. UNIXDCB * dcb = (UNIXDCB*) nf->nf_dev->dev_dcb;
  615. if ( dcb->dcb_fd > STDERR_FILENO)
  616. close( dcb->dcb_fd );
  617. return 0;
  618. }
  619. /*!
  620. * \brief Perform USART control functions.
  621. *
  622. * This function is called by the ioctl() function of the C runtime
  623. * library.
  624. *
  625. * \param dev Identifies the device that receives the device-control
  626. * function.
  627. * \param req Requested control function. May be set to one of the
  628. * following constants:
  629. * - \ref UART_SETSPEED
  630. * - \ref UART_GETSPEED
  631. * - \ref UART_SETDATABITS
  632. * - \ref UART_GETDATABITS
  633. * - \ref UART_SETSTOPBITS
  634. * - \ref UART_GETSTOPBITS
  635. * - \ref UART_SETPARITY
  636. * - \ref UART_GETPARITY
  637. * - \ref UART_SETFLOWCONTROL
  638. * - \ref UART_GETFLOWCONTROL
  639. * - \ref UART_SETBLOCKREAD
  640. * - \ref UART_GETBLOCKREAD
  641. * - \ref UART_SETSTATUS
  642. * - \ref UART_GETSTATUS
  643. * \param conf Points to a buffer that contains any data required for
  644. * the given control function or receives data from that
  645. * function.
  646. * \return 0 on success, -1 otherwise.
  647. *
  648. * \warning Timeout values are given in milliseconds and are limited to
  649. * the granularity of the system timer. To disable timeout,
  650. * set the parameter to NUT_WAIT_INFINITE.
  651. */
  652. int UnixDevIOCTL(NUTDEVICE * dev, int req, void *conf)
  653. {
  654. struct termios t;
  655. uint32_t *lvp = (uint32_t *) conf;
  656. uint32_t lv = *lvp;
  657. UNIXDCB * dcb = (UNIXDCB*) dev->dev_dcb;
  658. // printf("UnixDevIOCTL, native %x, req: %d, lv: %ld\n\r", dcb->dcb_fd , req, lv);
  659. switch (req) {
  660. case UART_SETSPEED:
  661. case UART_SETFLOWCONTROL:
  662. case UART_SETPARITY:
  663. case UART_SETDATABITS:
  664. case UART_SETSTOPBITS:
  665. // ok on stdio
  666. if ( dcb->dcb_fd <= STDERR_FILENO)
  667. return 0;
  668. // ok on sockets
  669. if ( dcb->dcb_socket)
  670. return 0;
  671. if (tcgetattr( dcb->dcb_fd , &t)) {
  672. printf("UnixDevIOCTL, tcgetattr failed\n\r");
  673. return -1;
  674. }
  675. switch (req) {
  676. case UART_SETSPEED:
  677. lv = convertToBaudSpeed(lv);
  678. cfsetospeed(&t, lv);
  679. cfsetispeed(&t, lv);
  680. break;
  681. case UART_SETFLOWCONTROL:
  682. switch (lv) {
  683. case 0:
  684. t.c_cflag &= ~CRTSCTS;
  685. t.c_iflag &= ~(IXON | IXOFF | IXANY);
  686. break;
  687. case UART_HS_SOFT:
  688. t.c_cflag &= ~CRTSCTS;
  689. t.c_iflag |= (IXON | IXOFF | IXANY);
  690. return -1;
  691. case UART_HS_MODEM:
  692. return -1;
  693. case UART_HS_RTSCTS:
  694. t.c_cflag |= CRTSCTS;
  695. t.c_iflag &= ~(IXON | IXOFF | IXANY);
  696. break;
  697. default:
  698. return -1;
  699. }
  700. break;
  701. case UART_SETPARITY:
  702. // 0 (none), 1 (odd) or 2 (even).
  703. t.c_cflag &= ~(PARODD | PARENB);
  704. switch (lv) {
  705. case 0:
  706. break;
  707. case 1:
  708. t.c_cflag |= PARENB | PARODD;
  709. break;
  710. case 2:
  711. t.c_cflag |= PARENB;
  712. default:
  713. return -1;
  714. }
  715. break;
  716. case UART_SETDATABITS:
  717. t.c_cflag &= ~CSIZE;
  718. switch (lv) {
  719. case 5:
  720. t.c_cflag |= CS5;
  721. break;
  722. case 6:
  723. t.c_cflag |= CS6;
  724. break;
  725. case 7:
  726. t.c_cflag |= CS7;
  727. break;
  728. case 8:
  729. t.c_cflag |= CS8;
  730. break;
  731. default:
  732. return -1;
  733. }
  734. break;
  735. case UART_SETSTOPBITS:
  736. switch (lv) {
  737. case 1:
  738. t.c_cflag &= ~CSTOPB;
  739. break;
  740. case 2:
  741. t.c_cflag |= CSTOPB;
  742. break;
  743. default:
  744. return -1;
  745. }
  746. break;
  747. }
  748. /* tcdrain fails on mac os x for some unknown reason -- work around */
  749. while (tcdrain( dcb->dcb_fd ) < 0) {
  750. // printf("UnixDevIOCTL: tcdrain failed: errno: %d\n\r", errno);
  751. errno = 0;
  752. usleep(1000);
  753. }
  754. if (tcsetattr( dcb->dcb_fd , TCSANOW, &t) < 0) {
  755. printf("UnixDevIOCTL: tcsetattr failed: errno: %d\n\r", errno);
  756. errno = 0;
  757. return -1;
  758. }
  759. return 0;
  760. case UART_GETSPEED:
  761. case UART_GETFLOWCONTROL:
  762. case UART_GETPARITY:
  763. case UART_GETDATABITS:
  764. case UART_GETSTOPBITS:
  765. if ((dcb->dcb_fd <= STDERR_FILENO) || ( dcb->dcb_socket))
  766. {
  767. // default answers for sockets / stdio
  768. switch (req){
  769. case UART_GETSPEED:
  770. *lvp = 9600; return 0;
  771. case UART_GETFLOWCONTROL:
  772. *lvp = 0; return 0;
  773. case UART_GETPARITY:
  774. *lvp = 0; return 0;
  775. case UART_GETDATABITS:
  776. *lvp = 8; return 0;
  777. case UART_GETSTOPBITS:
  778. *lvp = 1; return 0;
  779. }
  780. return 0;
  781. }
  782. if (tcgetattr(dcb->dcb_fd, &t) != 0)
  783. return -1;
  784. switch (req) {
  785. case UART_GETSPEED:
  786. *lvp = convertToRealSpeed(cfgetospeed(&t));
  787. break;
  788. case UART_GETFLOWCONTROL:
  789. if (t.c_cflag & CRTSCTS)
  790. *lvp = UART_HS_RTSCTS;
  791. else if (t.c_iflag & IXANY)
  792. *lvp = UART_HS_SOFT;
  793. else
  794. *lvp = 0;
  795. break;
  796. case UART_GETPARITY:
  797. if (t.c_cflag & PARENB) {
  798. if (t.c_cflag & PARODD)
  799. *lvp = 1;
  800. else
  801. *lvp = 2;
  802. } else
  803. *lvp = 0;
  804. break;
  805. case UART_GETDATABITS:
  806. switch (t.c_cflag & CSIZE) {
  807. case CS5:
  808. *lvp = 5;
  809. break;
  810. case CS6:
  811. *lvp = 6;
  812. break;
  813. case CS7:
  814. *lvp = 7;
  815. break;
  816. case CS8:
  817. *lvp = 8;
  818. break;
  819. default:
  820. return -1;
  821. }
  822. break;
  823. case UART_GETSTOPBITS:
  824. if (t.c_cflag & CSTOPB)
  825. *lvp = 2;
  826. else
  827. *lvp = 1;
  828. break;
  829. }
  830. return 0;
  831. #ifdef UART_SETBLOCKREAD
  832. case UART_SETBLOCKREAD:
  833. if (lv)
  834. dcb->dcb_modeflags |= USART_MF_BLOCKREAD;
  835. else
  836. dcb->dcb_modeflags &= ~USART_MF_BLOCKREAD;
  837. return 0;
  838. case UART_GETBLOCKREAD:
  839. if ( dcb->dcb_modeflags & USART_MF_BLOCKREAD)
  840. *lvp = 1;
  841. else
  842. *lvp = 0;
  843. return 0;
  844. #endif
  845. case UART_SETCOOKEDMODE:
  846. if (*lvp == 0)
  847. return 0;
  848. else
  849. return -1;
  850. case UART_GETSTATUS:
  851. *lvp = 0;
  852. return 0;
  853. case UART_SETTXBUFSIZ:
  854. case UART_SETRXBUFSIZ:
  855. case UART_SETTXBUFHWMARK:
  856. case UART_SETRXBUFHWMARK:
  857. case UART_SETTXBUFLWMARK:
  858. case UART_SETRXBUFLWMARK:
  859. case UART_SETSTATUS:
  860. return 0;
  861. default:
  862. return -1;
  863. }
  864. return -1;
  865. }
  866. /* ======================= Devices ======================== */
  867. /*!
  868. * \brief USART0 device control block structure.
  869. */
  870. static UNIXDCB dcb_usart0 = {
  871. 0, /* dcb_modeflags */
  872. 0, /* dcb_statusflags */
  873. 0, /* dcb_rtimeout */
  874. 0, /* dcb_wtimeout */
  875. 0, /* dbc_last_eol */
  876. 0, /* dcb_fd */
  877. 0, /* dcb_rx_rdy */
  878. /* xx, dcb_rx_mutex */
  879. /* xx, dcb_rx_trigger */
  880. };
  881. /*!
  882. * \brief USART1 device control block structure.
  883. */
  884. static UNIXDCB dcb_usart1 = {
  885. 0, /* dcb_modeflags */
  886. 0, /* dcb_statusflags */
  887. 0, /* dcb_rtimeout */
  888. 0, /* dcb_wtimeout */
  889. 0, /* dbc_last_eol */
  890. 0, /* dcb_fd */
  891. 0, /* dcb_rx_rdy */
  892. /* xx, dcb_rx_mutex */
  893. /* xx, dcb_rx_trigger */
  894. };
  895. /*!
  896. * \brief USART1 device control block structure.
  897. */
  898. static UNIXDCB dcb_usart2 = {
  899. 0, /* dcb_modeflags */
  900. 0, /* dcb_statusflags */
  901. 0, /* dcb_rtimeout */
  902. 0, /* dcb_wtimeout */
  903. 0, /* dbc_last_eol */
  904. 0, /* dcb_fd */
  905. 0, /* dcb_rx_rdy */
  906. /* xx, dcb_rx_mutex */
  907. /* xx, dcb_rx_trigger */
  908. };
  909. /*!
  910. * \brief Debug device 0 information structure.
  911. */
  912. NUTDEVICE devDebug0 = {
  913. 0, /*!< Pointer to next device. */
  914. {'u', 'a', 'r', 't', '0', 0, 0, 0, 0}
  915. , /*!< Unique device name. */
  916. 0, /*!< Type of device. */
  917. 0, /*!< Base address. */
  918. 0, /*!< First interrupt number. */
  919. 0, /*!< Interface control block. */
  920. &dcb_usart0, /*!< Driver control block. */
  921. 0, /*!< Driver initialization routine. */
  922. UnixDevIOCTL, /*!< Driver specific control function. */
  923. UnixDevRead,
  924. UnixDevWrite,
  925. UnixDevOpen,
  926. UnixDevClose,
  927. 0,
  928. 0, /*!< Select function, optional, not yet implemented */
  929. };
  930. /*!
  931. * \brief Debug device 1 information structure.
  932. */
  933. NUTDEVICE devDebug1 = {
  934. 0, /*!< Pointer to next device. */
  935. {'u', 'a', 'r', 't', '1', 0, 0, 0, 0}
  936. , /*!< Unique device name. */
  937. 0, /*!< Type of device. */
  938. 0, /*!< Base address. */
  939. 0, /*!< First interrupt number. */
  940. 0, /*!< Interface control block. */
  941. &dcb_usart1, /*!< Driver control block. */
  942. 0, /*!< Driver initialization routine. */
  943. UnixDevIOCTL, /*!< Driver specific control function. */
  944. UnixDevRead,
  945. UnixDevWrite,
  946. UnixDevOpen,
  947. UnixDevClose,
  948. 0,
  949. 0, /*!< Select function, optional, not yet implemented */
  950. };
  951. /*!
  952. * \brief uart device 0 information structure.
  953. */
  954. NUTDEVICE devUart0 = {
  955. 0, /*!< Pointer to next device. */
  956. {'u', 'a', 'r', 't', '0', 0, 0, 0, 0}
  957. , /*!< Unique device name. */
  958. 0, /*!< Type of device. */
  959. 0, /*!< Base address. */
  960. 0, /*!< First interrupt number. */
  961. 0, /*!< Interface control block. */
  962. &dcb_usart0, /*!< Driver control block. */
  963. 0, /*!< Driver initialization routine. */
  964. UnixDevIOCTL, /*!< Driver specific control function. */
  965. UnixDevRead,
  966. UnixDevWrite,
  967. UnixDevOpen,
  968. UnixDevClose,
  969. 0,
  970. 0, /*!< Select function, optional, not yet implemented */
  971. };
  972. /*!
  973. * \brief uart device 1 information structure.
  974. */
  975. NUTDEVICE devUart1 = {
  976. 0, /*!< Pointer to next device. */
  977. {'u', 'a', 'r', 't', '1', 0, 0, 0, 0}
  978. , /*!< Unique device name. */
  979. 0, /*!< Type of device. */
  980. 0, /*!< Base address. */
  981. 0, /*!< First interrupt number. */
  982. 0, /*!< Interface control block. */
  983. &dcb_usart1, /*!< Driver control block. */
  984. 0, /*!< Driver initialization routine. */
  985. UnixDevIOCTL, /*!< Driver specific control function. */
  986. UnixDevRead,
  987. UnixDevWrite,
  988. UnixDevOpen,
  989. UnixDevClose,
  990. 0,
  991. 0, /*!< Select function, optional, not yet implemented */
  992. };
  993. /*!
  994. * \brief uart device 2 information structure.
  995. */
  996. NUTDEVICE devUart2 = {
  997. 0, /*!< Pointer to next device. */
  998. {'u', 'a', 'r', 't', '2', 0, 0, 0, 0}
  999. , /*!< Unique device name. */
  1000. 0, /*!< Type of device. */
  1001. 0, /*!< Base address. */
  1002. 0, /*!< First interrupt number. */
  1003. 0, /*!< Interface control block. */
  1004. &dcb_usart2, /*!< Driver control block. */
  1005. 0, /*!< Driver initialization routine. */
  1006. UnixDevIOCTL, /*!< Driver specific control function. */
  1007. UnixDevRead,
  1008. UnixDevWrite,
  1009. UnixDevOpen,
  1010. UnixDevClose,
  1011. 0,
  1012. 0, /*!< Select function, optional, not yet implemented */
  1013. };
  1014. /*!
  1015. * \brief usartavr device 0 information structure.
  1016. */
  1017. NUTDEVICE devUsartAvr0 = {
  1018. 0, /*!< Pointer to next device. */
  1019. {'u', 'a', 'r', 't', '0', 0, 0, 0, 0}
  1020. , /*!< Unique device name. */
  1021. 0, /*!< Type of device. */
  1022. 0, /*!< Base address. */
  1023. 0, /*!< First interrupt number. */
  1024. 0, /*!< Interface control block. */
  1025. &dcb_usart0, /*!< Driver control block. */
  1026. 0, /*!< Driver initialization routine. */
  1027. UnixDevIOCTL, /*!< Driver specific control function. */
  1028. UnixDevRead,
  1029. UnixDevWrite,
  1030. UnixDevOpen,
  1031. UnixDevClose,
  1032. 0,
  1033. 0, /*!< Select function, optional, not yet implemented */
  1034. };
  1035. /*!
  1036. * \brief usartavr device 1 information structure.
  1037. */
  1038. NUTDEVICE devUsartAvr1 = {
  1039. 0, /*!< Pointer to next device. */
  1040. {'u', 'a', 'r', 't', '1', 0, 0, 0, 0}
  1041. , /*!< Unique device name. */
  1042. 0, /*!< Type of device. */
  1043. 0, /*!< Base address. */
  1044. 0, /*!< First interrupt number. */
  1045. 0, /*!< Interface control block. */
  1046. &dcb_usart1, /*!< Driver control block. */
  1047. 0, /*!< Driver initialization routine. */
  1048. UnixDevIOCTL, /*!< Driver specific control function. */
  1049. UnixDevRead,
  1050. UnixDevWrite,
  1051. UnixDevOpen,
  1052. UnixDevClose,
  1053. 0,
  1054. 0, /*!< Select function, optional, not yet implemented */
  1055. };
  1056. /*!
  1057. * \brief usartavr device 2 information structure.
  1058. */
  1059. NUTDEVICE devUsartAvr2 = {
  1060. 0, /*!< Pointer to next device. */
  1061. {'u', 'a', 'r', 't', '2', 0, 0, 0, 0}
  1062. , /*!< Unique device name. */
  1063. 0, /*!< Type of device. */
  1064. 0, /*!< Base address. */
  1065. 0, /*!< First interrupt number. */
  1066. 0, /*!< Interface control block. */
  1067. &dcb_usart2, /*!< Driver control block. */
  1068. 0, /*!< Driver initialization routine. */
  1069. UnixDevIOCTL, /*!< Driver specific control function. */
  1070. UnixDevRead,
  1071. UnixDevWrite,
  1072. UnixDevOpen,
  1073. UnixDevClose,
  1074. 0,
  1075. 0, /*!< Select function, optional, not yet implemented */
  1076. };
  1077. /*@}*/