1 /* 2 * COPYRIGHT (C) 2006-2018, RT-Thread Development Team 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 25 * OF SUCH DAMAGE. 26 * 27 * Change Logs: 28 * Date Author Notes 29 * 2012-12-8 Bernard add file header 30 * export bsd socket symbol for RT-Thread Application Module 31 * 2017-11-15 Bernard add lock for init_done callback. 32 * 2018-11-02 MurphyZhao port to lwip2.1.0 33 */ 34 35 #include <rtthread.h> 36 37 #include "lwip/sys.h" 38 #include "lwip/opt.h" 39 #include "lwip/stats.h" 40 #include "lwip/err.h" 41 #include "arch/sys_arch.h" 42 #include "lwip/debug.h" 43 #include "lwip/netif.h" 44 #include "lwip/netifapi.h" 45 #include "lwip/tcpip.h" 46 #include "netif/ethernetif.h" 47 #include "lwip/sio.h" 48 #include "lwip/init.h" 49 #include "lwip/dhcp.h" 50 #include "lwip/inet.h" 51 52 #include <string.h> 53 #include <stdio.h> 54 55 /* 56 * Initialize the network interface device 57 * 58 * @return the operation status, ERR_OK on OK, ERR_IF on error 59 */ 60 static err_t netif_device_init(struct netif *netif) 61 { 62 struct eth_device *ethif; 63 64 ethif = (struct eth_device *)netif->state; 65 if (ethif != RT_NULL) 66 { 67 rt_device_t device; 68 69 /* get device object */ 70 device = (rt_device_t) ethif; 71 if (rt_device_init(device) != RT_EOK) 72 { 73 return ERR_IF; 74 } 75 76 /* copy device flags to netif flags */ 77 netif->flags = ethif->flags; 78 79 return ERR_OK; 80 } 81 82 return ERR_IF; 83 } 84 /* 85 * Initialize the ethernetif layer and set network interface device up 86 */ 87 static void tcpip_init_done_callback(void *arg) 88 { 89 rt_device_t device; 90 struct eth_device *ethif; 91 ip4_addr_t ipaddr, netmask, gw; 92 struct rt_list_node* node; 93 struct rt_object* object; 94 struct rt_object_information *information; 95 96 LWIP_ASSERT("invalid arg.\n",arg); 97 98 IP4_ADDR(&gw, 0,0,0,0); 99 IP4_ADDR(&ipaddr, 0,0,0,0); 100 IP4_ADDR(&netmask, 0,0,0,0); 101 102 /* enter critical */ 103 rt_enter_critical(); 104 105 /* for each network interfaces */ 106 information = rt_object_get_information(RT_Object_Class_Device); 107 RT_ASSERT(information != RT_NULL); 108 for (node = information->object_list.next; 109 node != &(information->object_list); 110 node = node->next) 111 { 112 object = rt_list_entry(node, struct rt_object, list); 113 device = (rt_device_t)object; 114 if (device->type == RT_Device_Class_NetIf) 115 { 116 ethif = (struct eth_device *)device; 117 118 /* leave critical */ 119 rt_exit_critical(); 120 LOCK_TCPIP_CORE(); 121 122 netif_add(ethif->netif, &ipaddr, &netmask, &gw, 123 ethif, netif_device_init, tcpip_input); 124 125 if (netif_default == RT_NULL) 126 netif_set_default(ethif->netif); 127 128 #if LWIP_DHCP 129 /* set interface up */ 130 netif_set_up(ethif->netif); 131 /* if this interface uses DHCP, start the DHCP client */ 132 dhcp_start(ethif->netif); 133 #else 134 /* set interface up */ 135 netif_set_up(ethif->netif); 136 #endif 137 138 if (ethif->flags & ETHIF_LINK_PHYUP) 139 { 140 netif_set_link_up(ethif->netif); 141 } 142 143 UNLOCK_TCPIP_CORE(); 144 /* enter critical */ 145 rt_enter_critical(); 146 } 147 } 148 149 /* leave critical */ 150 rt_exit_critical(); 151 rt_sem_release((rt_sem_t)arg); 152 } 153 154 /** 155 * LwIP system initialization 156 */ 157 extern int eth_system_device_init_private(void); 158 int lwip_system_init(void) 159 { 160 rt_err_t rc; 161 struct rt_semaphore done_sem; 162 static rt_bool_t init_ok = RT_FALSE; 163 164 if (init_ok) 165 { 166 rt_kprintf("lwip system already init.\n"); 167 return 0; 168 } 169 170 eth_system_device_init_private(); 171 172 /* set default netif to NULL */ 173 netif_default = RT_NULL; 174 175 rc = rt_sem_init(&done_sem, "done", 0, RT_IPC_FLAG_FIFO); 176 177 if (rc != RT_EOK) 178 { 179 LWIP_ASSERT("Failed to create semaphore", 0); 180 181 return -1; 182 } 183 184 tcpip_init(tcpip_init_done_callback, (void *)&done_sem); 185 186 /* waiting for initialization done */ 187 if (rt_sem_take(&done_sem, RT_WAITING_FOREVER) != RT_EOK) 188 { 189 rt_sem_detach(&done_sem); 190 191 return -1; 192 } 193 rt_sem_detach(&done_sem); 194 195 /* set default ip address */ 196 #if !LWIP_DHCP 197 if (netif_default != RT_NULL) 198 { 199 struct ip4_addr ipaddr, netmask, gw; 200 201 ipaddr.addr = inet_addr(RT_LWIP_IPADDR); 202 gw.addr = inet_addr(RT_LWIP_GWADDR); 203 netmask.addr = inet_addr(RT_LWIP_MSKADDR); 204 205 netifapi_netif_set_addr(netif_default, &ipaddr, &netmask, &gw); 206 } 207 #endif 208 rt_kprintf("lwIP-%d.%d.%d initialized!\n", LWIP_VERSION_MAJOR, LWIP_VERSION_MINOR, LWIP_VERSION_REVISION); 209 210 init_ok = RT_TRUE; 211 212 return 0; 213 } 214 INIT_PREV_EXPORT(lwip_system_init); 215 216 void sys_init(void) 217 { 218 /* nothing on RT-Thread porting */ 219 } 220 221 void lwip_sys_init(void) 222 { 223 lwip_system_init(); 224 } 225 226 /* 227 * Create a new semaphore 228 * 229 * @return the operation status, ERR_OK on OK; others on error 230 */ 231 err_t sys_sem_new(sys_sem_t *sem, u8_t count) 232 { 233 static unsigned short counter = 0; 234 char tname[RT_NAME_MAX]; 235 sys_sem_t tmpsem; 236 237 RT_DEBUG_NOT_IN_INTERRUPT; 238 239 rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter); 240 counter ++; 241 242 tmpsem = rt_sem_create(tname, count, RT_IPC_FLAG_FIFO); 243 if (tmpsem == RT_NULL) 244 return ERR_MEM; 245 else 246 { 247 *sem = tmpsem; 248 249 return ERR_OK; 250 } 251 } 252 253 /* 254 * Deallocate a semaphore 255 */ 256 void sys_sem_free(sys_sem_t *sem) 257 { 258 RT_DEBUG_NOT_IN_INTERRUPT; 259 rt_sem_delete(*sem); 260 } 261 262 /* 263 * Signal a semaphore 264 */ 265 void sys_sem_signal(sys_sem_t *sem) 266 { 267 rt_sem_release(*sem); 268 } 269 270 /* 271 * Block the thread while waiting for the semaphore to be signaled 272 * 273 * @return If the timeout argument is non-zero, it will return the number of milliseconds 274 * spent waiting for the semaphore to be signaled; If the semaphore isn't signaled 275 * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't 276 * wait for the semaphore, it will return zero 277 */ 278 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) 279 { 280 rt_err_t ret; 281 s32_t t; 282 u32_t tick; 283 284 RT_DEBUG_NOT_IN_INTERRUPT; 285 286 /* get the begin tick */ 287 tick = rt_tick_get(); 288 if (timeout == 0) 289 t = RT_WAITING_FOREVER; 290 else 291 { 292 /* convert msecond to os tick */ 293 if (timeout < (1000/RT_TICK_PER_SECOND)) 294 t = 1; 295 else 296 t = timeout / (1000/RT_TICK_PER_SECOND); 297 } 298 299 ret = rt_sem_take(*sem, t); 300 301 if (ret == -RT_ETIMEOUT) 302 return SYS_ARCH_TIMEOUT; 303 else 304 { 305 if (ret == RT_EOK) 306 ret = 1; 307 } 308 309 /* get elapse msecond */ 310 tick = rt_tick_get() - tick; 311 312 /* convert tick to msecond */ 313 tick = tick * (1000 / RT_TICK_PER_SECOND); 314 if (tick == 0) 315 tick = 1; 316 317 return tick; 318 } 319 320 #ifndef sys_sem_valid 321 /** Check if a semaphore is valid/allocated: 322 * return 1 for valid, 0 for invalid 323 */ 324 int sys_sem_valid(sys_sem_t *sem) 325 { 326 return (int)(*sem); 327 } 328 #endif 329 330 #ifndef sys_sem_set_invalid 331 /** Set a semaphore invalid so that sys_sem_valid returns 0 332 */ 333 void sys_sem_set_invalid(sys_sem_t *sem) 334 { 335 *sem = RT_NULL; 336 } 337 #endif 338 339 /* ====================== Mutex ====================== */ 340 341 /** Create a new mutex 342 * @param mutex pointer to the mutex to create 343 * @return a new mutex 344 */ 345 err_t sys_mutex_new(sys_mutex_t *mutex) 346 { 347 static unsigned short counter = 0; 348 char tname[RT_NAME_MAX]; 349 sys_mutex_t tmpmutex; 350 351 RT_DEBUG_NOT_IN_INTERRUPT; 352 353 rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MUTEX_NAME, counter); 354 counter ++; 355 356 tmpmutex = rt_mutex_create(tname, RT_IPC_FLAG_FIFO); 357 if (tmpmutex == RT_NULL) 358 return ERR_MEM; 359 else 360 { 361 *mutex = tmpmutex; 362 363 return ERR_OK; 364 } 365 } 366 367 /** Lock a mutex 368 * @param mutex the mutex to lock 369 */ 370 void sys_mutex_lock(sys_mutex_t *mutex) 371 { 372 RT_DEBUG_NOT_IN_INTERRUPT; 373 rt_mutex_take(*mutex, RT_WAITING_FOREVER); 374 375 return; 376 } 377 378 /** Unlock a mutex 379 * @param mutex the mutex to unlock 380 */ 381 void sys_mutex_unlock(sys_mutex_t *mutex) 382 { 383 rt_mutex_release(*mutex); 384 } 385 386 /** Delete a semaphore 387 * @param mutex the mutex to delete 388 */ 389 void sys_mutex_free(sys_mutex_t *mutex) 390 { 391 RT_DEBUG_NOT_IN_INTERRUPT; 392 393 rt_mutex_delete(*mutex); 394 } 395 396 #ifndef sys_mutex_valid 397 /** Check if a mutex is valid/allocated: 398 * return 1 for valid, 0 for invalid 399 */ 400 int sys_mutex_valid(sys_mutex_t *mutex) 401 { 402 return (int)(*mutex); 403 } 404 #endif 405 406 #ifndef sys_mutex_set_invalid 407 /** Set a mutex invalid so that sys_mutex_valid returns 0 408 */ 409 void sys_mutex_set_invalid(sys_mutex_t *mutex) 410 { 411 *mutex = RT_NULL; 412 } 413 #endif 414 415 /* ====================== Mailbox ====================== */ 416 417 /* 418 * Create an empty mailbox for maximum "size" elements 419 * 420 * @return the operation status, ERR_OK on OK; others on error 421 */ 422 err_t sys_mbox_new(sys_mbox_t *mbox, int size) 423 { 424 static unsigned short counter = 0; 425 char tname[RT_NAME_MAX]; 426 sys_mbox_t tmpmbox; 427 428 RT_DEBUG_NOT_IN_INTERRUPT; 429 430 rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter); 431 counter ++; 432 433 tmpmbox = rt_mb_create(tname, size, RT_IPC_FLAG_FIFO); 434 if (tmpmbox != RT_NULL) 435 { 436 *mbox = tmpmbox; 437 438 return ERR_OK; 439 } 440 441 return ERR_MEM; 442 } 443 444 /* 445 * Deallocate a mailbox 446 */ 447 void sys_mbox_free(sys_mbox_t *mbox) 448 { 449 RT_DEBUG_NOT_IN_INTERRUPT; 450 451 rt_mb_delete(*mbox); 452 453 return; 454 } 455 456 /** Post a message to an mbox - may not fail 457 * -> blocks if full, only used from tasks not from ISR 458 * @param mbox mbox to posts the message 459 * @param msg message to post (ATTENTION: can be NULL) 460 */ 461 void sys_mbox_post(sys_mbox_t *mbox, void *msg) 462 { 463 RT_DEBUG_NOT_IN_INTERRUPT; 464 465 rt_mb_send_wait(*mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER); 466 467 return; 468 } 469 470 /* 471 * Try to post the "msg" to the mailbox 472 * 473 * @return return ERR_OK if the "msg" is posted, ERR_MEM if the mailbox is full 474 */ 475 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) 476 { 477 if (rt_mb_send(*mbox, (rt_uint32_t)msg) == RT_EOK) 478 return ERR_OK; 479 480 return ERR_MEM; 481 } 482 483 err_t 484 sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg) 485 { 486 return sys_mbox_trypost(q, msg); 487 } 488 489 /** Wait for a new message to arrive in the mbox 490 * @param mbox mbox to get a message from 491 * @param msg pointer where the message is stored 492 * @param timeout maximum time (in milliseconds) to wait for a message 493 * @return time (in milliseconds) waited for a message, may be 0 if not waited 494 or SYS_ARCH_TIMEOUT on timeout 495 * The returned time has to be accurate to prevent timer jitter! 496 */ 497 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) 498 { 499 rt_err_t ret; 500 s32_t t; 501 u32_t tick; 502 503 RT_DEBUG_NOT_IN_INTERRUPT; 504 505 /* get the begin tick */ 506 tick = rt_tick_get(); 507 508 if(timeout == 0) 509 t = RT_WAITING_FOREVER; 510 else 511 { 512 /* convirt msecond to os tick */ 513 if (timeout < (1000/RT_TICK_PER_SECOND)) 514 t = 1; 515 else 516 t = timeout / (1000/RT_TICK_PER_SECOND); 517 } 518 519 ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, t); 520 521 if(ret == -RT_ETIMEOUT) 522 return SYS_ARCH_TIMEOUT; 523 else 524 { 525 LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK); 526 } 527 528 /* get elapse msecond */ 529 tick = rt_tick_get() - tick; 530 531 /* convert tick to msecond */ 532 tick = tick * (1000 / RT_TICK_PER_SECOND); 533 if (tick == 0) 534 tick = 1; 535 536 return tick; 537 } 538 539 /** Wait for a new message to arrive in the mbox 540 * @param mbox mbox to get a message from 541 * @param msg pointer where the message is stored 542 * @param timeout maximum time (in milliseconds) to wait for a message 543 * @return 0 (milliseconds) if a message has been received 544 * or SYS_MBOX_EMPTY if the mailbox is empty 545 */ 546 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) 547 { 548 int ret; 549 550 ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, 0); 551 552 if(ret == -RT_ETIMEOUT) 553 return SYS_ARCH_TIMEOUT; 554 else 555 { 556 if (ret == RT_EOK) 557 ret = 1; 558 } 559 560 return ret; 561 } 562 563 #ifndef sys_mbox_valid 564 /** Check if an mbox is valid/allocated: 565 * return 1 for valid, 0 for invalid 566 */ 567 int sys_mbox_valid(sys_mbox_t *mbox) 568 { 569 return (int)(*mbox); 570 } 571 #endif 572 573 #ifndef sys_mbox_set_invalid 574 /** Set an mbox invalid so that sys_mbox_valid returns 0 575 */ 576 void sys_mbox_set_invalid(sys_mbox_t *mbox) 577 { 578 *mbox = RT_NULL; 579 } 580 #endif 581 582 /* ====================== System ====================== */ 583 584 /* 585 * Start a new thread named "name" with priority "prio" that will begin 586 * its execution in the function "thread()". The "arg" argument will be 587 * passed as an argument to the thread() function 588 */ 589 sys_thread_t sys_thread_new(const char *name, 590 lwip_thread_fn thread, 591 void *arg, 592 int stacksize, 593 int prio) 594 { 595 rt_thread_t t; 596 597 RT_DEBUG_NOT_IN_INTERRUPT; 598 599 /* create thread */ 600 t = rt_thread_create(name, thread, arg, stacksize, prio, 20); 601 RT_ASSERT(t != RT_NULL); 602 603 /* startup thread */ 604 rt_thread_startup(t); 605 606 return t; 607 } 608 609 sys_prot_t sys_arch_protect(void) 610 { 611 rt_base_t level; 612 613 /* disable interrupt */ 614 level = rt_hw_interrupt_disable(); 615 616 return level; 617 } 618 619 void sys_arch_unprotect(sys_prot_t pval) 620 { 621 /* enable interrupt */ 622 rt_hw_interrupt_enable(pval); 623 624 return; 625 } 626 627 void sys_arch_assert(const char *file, int line) 628 { 629 rt_kprintf("\nAssertion: %d in %s, thread %s\n", 630 line, file, rt_thread_self()->name); 631 RT_ASSERT(0); 632 } 633 634 u32_t sys_jiffies(void) 635 { 636 return rt_tick_get(); 637 } 638 639 u32_t sys_now(void) 640 { 641 return rt_tick_get() * (1000 / RT_TICK_PER_SECOND); 642 } 643 644 #if MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK 645 /** 646 * Check if a mep element was victim of an overflow or underflow 647 * (e.g. the restricted area after/before it has been altered) 648 * 649 * @param p the mem element to check 650 * @param size allocated size of the element 651 * @param descr1 description of the element source shown on error 652 * @param descr2 description of the element source shown on error 653 */ 654 void 655 mem_overflow_check_raw(void *p, size_t size, const char *descr1, const char *descr2) 656 { 657 #if MEM_SANITY_REGION_AFTER_ALIGNED || MEM_SANITY_REGION_BEFORE_ALIGNED 658 u16_t k; 659 u8_t *m; 660 661 #if MEM_SANITY_REGION_AFTER_ALIGNED > 0 662 m = (u8_t *)p + size; 663 for (k = 0; k < MEM_SANITY_REGION_AFTER_ALIGNED; k++) { 664 if (m[k] != 0xcd) { 665 char errstr[128]; 666 snprintf(errstr, sizeof(errstr), "detected mem overflow in %s%s", descr1, descr2); 667 LWIP_ASSERT(errstr, 0); 668 } 669 } 670 #endif /* MEM_SANITY_REGION_AFTER_ALIGNED > 0 */ 671 672 #if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 673 m = (u8_t *)p - MEM_SANITY_REGION_BEFORE_ALIGNED; 674 for (k = 0; k < MEM_SANITY_REGION_BEFORE_ALIGNED; k++) { 675 if (m[k] != 0xcd) { 676 char errstr[128]; 677 snprintf(errstr, sizeof(errstr), "detected mem underflow in %s%s", descr1, descr2); 678 LWIP_ASSERT(errstr, 0); 679 } 680 } 681 #endif /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 */ 682 #else 683 LWIP_UNUSED_ARG(p); 684 LWIP_UNUSED_ARG(desc); 685 LWIP_UNUSED_ARG(descr); 686 #endif 687 } 688 689 /** 690 * Initialize the restricted area of a mem element. 691 */ 692 void 693 mem_overflow_init_raw(void *p, size_t size) 694 { 695 #if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 696 u8_t *m; 697 #if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 698 m = (u8_t *)p - MEM_SANITY_REGION_BEFORE_ALIGNED; 699 memset(m, 0xcd, MEM_SANITY_REGION_BEFORE_ALIGNED); 700 #endif 701 #if MEM_SANITY_REGION_AFTER_ALIGNED > 0 702 m = (u8_t *)p + size; 703 memset(m, 0xcd, MEM_SANITY_REGION_AFTER_ALIGNED); 704 #endif 705 #else /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 */ 706 LWIP_UNUSED_ARG(p); 707 LWIP_UNUSED_ARG(desc); 708 #endif /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 */ 709 } 710 #endif /* MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK */ 711 712 RT_WEAK 713 void mem_init(void) 714 { 715 } 716 717 void *mem_calloc(mem_size_t count, mem_size_t size) 718 { 719 return rt_calloc(count, size); 720 } 721 722 void *mem_trim(void *mem, mem_size_t size) 723 { 724 // return rt_realloc(mem, size); 725 /* not support trim yet */ 726 return mem; 727 } 728 729 void *mem_malloc(mem_size_t size) 730 { 731 return rt_malloc(size); 732 } 733 734 void mem_free(void *mem) 735 { 736 rt_free(mem); 737 } 738 739 #ifdef RT_LWIP_PPP 740 u32_t sio_read(sio_fd_t fd, u8_t *buf, u32_t size) 741 { 742 u32_t len; 743 744 RT_ASSERT(fd != RT_NULL); 745 746 len = rt_device_read((rt_device_t)fd, 0, buf, size); 747 if (len <= 0) 748 return 0; 749 750 return len; 751 } 752 753 u32_t sio_write(sio_fd_t fd, u8_t *buf, u32_t size) 754 { 755 RT_ASSERT(fd != RT_NULL); 756 757 return rt_device_write((rt_device_t)fd, 0, buf, size); 758 } 759 760 void sio_read_abort(sio_fd_t fd) 761 { 762 rt_kprintf("read_abort\n"); 763 } 764 765 void ppp_trace(int level, const char *format, ...) 766 { 767 va_list args; 768 rt_size_t length; 769 static char rt_log_buf[RT_CONSOLEBUF_SIZE]; 770 771 va_start(args, format); 772 length = rt_vsprintf(rt_log_buf, format, args); 773 rt_device_write((rt_device_t)rt_console_get_device(), 0, rt_log_buf, length); 774 va_end(args); 775 } 776 #endif 777 778 /* 779 * export bsd socket symbol for RT-Thread Application Module 780 */ 781 #if LWIP_SOCKET 782 #include <lwip/sockets.h> 783 RTM_EXPORT(lwip_accept); 784 RTM_EXPORT(lwip_bind); 785 RTM_EXPORT(lwip_shutdown); 786 RTM_EXPORT(lwip_getpeername); 787 RTM_EXPORT(lwip_getsockname); 788 RTM_EXPORT(lwip_getsockopt); 789 RTM_EXPORT(lwip_setsockopt); 790 RTM_EXPORT(lwip_close); 791 RTM_EXPORT(lwip_connect); 792 RTM_EXPORT(lwip_listen); 793 RTM_EXPORT(lwip_recv); 794 RTM_EXPORT(lwip_read); 795 RTM_EXPORT(lwip_recvfrom); 796 RTM_EXPORT(lwip_send); 797 RTM_EXPORT(lwip_sendto); 798 RTM_EXPORT(lwip_socket); 799 RTM_EXPORT(lwip_write); 800 RTM_EXPORT(lwip_select); 801 RTM_EXPORT(lwip_ioctl); 802 RTM_EXPORT(lwip_fcntl); 803 804 RTM_EXPORT(lwip_htons); 805 RTM_EXPORT(lwip_htonl); 806 807 #if LWIP_DNS 808 #include <lwip/netdb.h> 809 RTM_EXPORT(lwip_gethostbyname); 810 RTM_EXPORT(lwip_gethostbyname_r); 811 RTM_EXPORT(lwip_freeaddrinfo); 812 RTM_EXPORT(lwip_getaddrinfo); 813 #endif 814 815 #endif 816 817 #if LWIP_DHCP 818 #include <lwip/dhcp.h> 819 RTM_EXPORT(dhcp_start); 820 RTM_EXPORT(dhcp_renew); 821 RTM_EXPORT(dhcp_stop); 822 #endif 823 824 #if LWIP_NETIF_API 825 #include <lwip/netifapi.h> 826 RTM_EXPORT(netifapi_netif_set_addr); 827 #endif 828 829 #if LWIP_NETIF_LINK_CALLBACK 830 RTM_EXPORT(netif_set_link_callback); 831 #endif 832 833 #if LWIP_NETIF_STATUS_CALLBACK 834 RTM_EXPORT(netif_set_status_callback); 835 #endif 836 837 RTM_EXPORT(netif_find); 838 RTM_EXPORT(netif_set_addr); 839 RTM_EXPORT(netif_set_ipaddr); 840 RTM_EXPORT(netif_set_gw); 841 RTM_EXPORT(netif_set_netmask); 842