Test of C++ Sockets API with Ethernet
Dependencies: mbed EthernetInterface
Revision 0:81648c034b7a, committed 2012-06-15
- Comitter:
- donatien
- Date:
- Fri Jun 15 16:38:40 2012 +0000
- Child:
- 1:74160c87c7ce
- Commit message:
- Initial commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Fri Jun 15 16:38:40 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/donatien/code/EthernetInterface/#b01299fd0ce3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RTX_Conf_CM.c Fri Jun 15 16:38:40 2012 +0000 @@ -0,0 +1,266 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_Conf_CM.C + * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M + * Rev.: V4.20 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "cmsis_os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part BEGIN + *---------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +// +// <h>Thread Configuration +// ======================= +// <o>Number of concurrent running threads <0-250> +// <i> Defines max. number of threads that will run at the same time. +// counting "main", but not counting "osTimerThread" +// <i> Default: 6 +#ifndef OS_TASKCNT +# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) +# define OS_TASKCNT 7 +# elif defined(TARGET_LPC11U24) +# define OS_TASKCNT 3 +# endif +#endif + +// <o>Number of threads with user-provided stack size <0-250> +// The stack of "main" and "osTimerThread" are calculated separately +// <i> Defines the number of threads with user-provided stack size. +// <i> Default: 0 +#ifndef OS_PRIVCNT + #define OS_PRIVCNT (OS_TASKCNT - 1) +#endif + +// <o>Default Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines default stack size for threads. +// <i> Default: 200 +#ifndef OS_STKSIZE + #define OS_STKSIZE WORDS_STACK_SIZE +#endif + +// <o>Main Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines stack size for main thread. +// <i> Default: 200 +#ifndef OS_MAINSTKSIZE +//Donatien: default allocated stack size is a bit too low + #define OS_MAINSTKSIZE 512 +#endif + +// <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4> +// <i> Defines the combined stack size for threads with user-provided stack size. +// <i> Default: 0 +#ifndef OS_PRIVSTKSIZE +//Donatien: default allocated stack size is a bit too low +# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) +# define OS_PRIVSTKSIZE 3000 +# elif defined(TARGET_LPC11U24) +# define OS_PRIVSTKSIZE 512 +# endif +#endif + +// <q>Check for stack overflow +// =========================== +// <i> Includes the stack checking code for stack overflow. +// <i> Note that additional code reduces the Kernel performance. +#ifndef OS_STKCHECK + #define OS_STKCHECK 1 +#endif + +// <q>Run in privileged mode +// ========================= +// <i> Runs all Threads in privileged mode. +// <i> Default: Unprivileged +#ifndef OS_RUNPRIV + #define OS_RUNPRIV 1 +#endif + +// </h> +// <h>SysTick Timer Configuration +// ============================== +// +// <o>Timer clock value [Hz] <1-1000000000> +// <i> Defines the timer clock value. +// <i> Default: 6000000 (6MHz) +#ifndef OS_CLOCK +# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) +# define OS_CLOCK 96000000 +# elif defined(TARGET_LPC11U24) +# define OS_CLOCK 48000000 +# endif +#endif + +// <o>Timer tick value [us] <1-1000000> +// <i> Defines the timer tick value. +// <i> Default: 1000 (1ms) +#ifndef OS_TICK + #define OS_TICK 1000 +#endif + +// </h> + +// <h>System Configuration +// ======================= +// +// <e>Round-Robin Thread switching +// =============================== +// +// <i> Enables Round-Robin Thread switching. +#ifndef OS_ROBIN + #define OS_ROBIN 1 +#endif + +// <o>Round-Robin Timeout [ticks] <1-1000> +// <i> Defines how long a thread will execute before a thread switch. +// <i> Default: 5 +#ifndef OS_ROBINTOUT + #define OS_ROBINTOUT 5 +#endif + +// </e> + +// <e>User Timers +// ============== +// <i> Enables user Timers +#ifndef OS_TIMERS + #define OS_TIMERS 1 +#endif + +// <o>Timer Thread Priority +// <1=> Low +// <2=> Below Normal <3=> Normal +// <4=> Above Normal +// <5=> High +// <6=> Realtime +// <i> Defines priority for Timer Thread +// <i> Default: High +#ifndef OS_TIMERPRIO + #define OS_TIMERPRIO 5 +#endif + +// <o>Timer Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines stack size for Timer thread. +// <i> Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ WORDS_STACK_SIZE +#endif + +// <o>Timer Callback Queue size <1-32> +// <i> Defines number of concurrent callbacks that will be queued. +// <i> Default: 4 +#ifndef OS_TIMERCBQSZ + #define OS_TIMERCBQS 4 +#endif + +// </e> + +// <o>ISR FIFO Queue size<4=> 4 entries <8=> 8 entries +// <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries +// <48=> 48 entries <64=> 64 entries +// <96=> 96 entries +// <i> ISR functions store requests to this buffer, +// <i> when they are called from the iterrupt handler. +// <i> Default: 16 entries +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +// </h> + +//------------- <<< end of configuration section >>> ----------------------- + +// Standard library system mutexes +// =============================== +// Define max. number system mutexes that are used to protect +// the arm standard runtime library. For microlib they are not used. +#ifndef OS_MUTEXCNT + #define OS_MUTEXCNT 8 +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part END + *---------------------------------------------------------------------------*/ +#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) + + +/*---------------------------------------------------------------------------- + * OS Idle daemon + *---------------------------------------------------------------------------*/ +void os_idle_demon (void) { + /* The idle demon is a system thread, running when no other thread is */ + /* ready to run. */ + + /* Sleep: ideally, we should put the chip to sleep. + Unfortunately, this usually requires disconnecting the interface chip (debugger). + This can be done, but it would break the local file system. + */ + for (;;) { + // sleep(); + } +} + +/*---------------------------------------------------------------------------- + * RTX Errors + *---------------------------------------------------------------------------*/ +extern void mbed_die(void); + +void os_error (uint32_t err_code) { + /* This function is called when a runtime error is detected. Parameter */ + /* 'err_code' holds the runtime error code (defined in RTX_Config.h). */ + mbed_die(); +} + +void sysThreadError(osStatus status) { + if (status != osOK) { + mbed_die(); + } +} + +/*---------------------------------------------------------------------------- + * RTX Configuration Functions + *---------------------------------------------------------------------------*/ + +#include "RTX_CM_lib.h" + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Jun 15 16:38:40 2012 +0000 @@ -0,0 +1,223 @@ +/* cpp_sockets_test.cpp */ +/* +Copyright (C) 2012 ARM Limited. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#define __DEBUG__ 4 //Maximum verbosity +#ifndef __MODULE__ +#define __MODULE__ "cpp_sockets_test.cpp" +#endif + +#include "core/fwk.h" +#include "mbed.h" + +#include "rtos.h" + +#include "EthernetInterface.h" +#include "TCPSocket.h" +#include "UDPSocket.h" + +#define CHECK_ERR(ret) if(ret < 0) break; + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +void notify(bool a, bool b, bool c) +{ + led1 = a; + led2 = b; + led3 = c; +} + +extern "C" void HardFault_Handler() +{ + error("Hard Fault!\n"); +} + +void test(void const*) +{ + EthernetInterface eth; + DBG("Hello!"); + + int count = 0; + eth.init(); //Use DHCP + + count++; + DBG("iteration #%d", count); + + char in_buf[256]; + + notify(0, 1, 1); + int ret = eth.connect(); + notify(0, 1, 0); + if (ret == OK) + { + //TCP Socket test + do + { + DBG("TCP Client test"); + TCPSocket sock; + //http://mbed.org/media/uploads/donatien/hello.txt + ret = sock.connect("mbed.org", 80); + CHECK_ERR(ret); + const char http_cmd[] = "GET /media/uploads/donatien/hello.txt HTTP/1.1\r\nHost: %s\r\n\r\n"; + ret = sock.send((std::uint8_t*)http_cmd, sizeof(http_cmd) - 1, 3000); + CHECK_ERR(ret); + + bool firstIt = true; + do + { + ret = sock.receive((std::uint8_t*)in_buf, 255, firstIt?3000:0); + CHECK_ERR(ret); + in_buf[ret] = '\0'; + DBG("Received %d chars from server: %s", ret, in_buf); + firstIt = false; + } while( ret > 0 ); + CHECK_ERR(ret); + ret = sock.close(); + CHECK_ERR(ret); + } while(0); + if(ret < 0) + { + WARN("TCP Client test failed"); + } + else + { + DBG("TCP Client test succeeded"); + } + + do + { + DBG("TCP Server test"); + TCPSocket sock; + ret = sock.bind(80); //Listen on all interfaces + CHECK_ERR(ret); + + TCPSocket hdlrSock; + ret = sock.listen(1); + CHECK_ERR(ret); + DBG("Now listening on port 80, open a browser and try to fetch the page"); + + char* inHost; + int inPort; + ret = sock.accept(hdlrSock, &inHost, &inPort, 150000); + CHECK_ERR(ret); + DBG("Connection from %s on port %d", inHost, inPort); + bool firstIt = true; + do + { + ret = hdlrSock.receive((std::uint8_t*)in_buf, 255, firstIt?3000:0); + CHECK_ERR(ret); + in_buf[ret] = '\0'; + DBG("Received %d chars from client: %s", ret, in_buf); + firstIt = false; + } while( ret > 0 ); + CHECK_ERR(ret); + + const char http_resp[] = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello world!"; + ret = hdlrSock.send((std::uint8_t*)http_resp, sizeof(http_resp) - 1, 3000); + CHECK_ERR(ret); + + ret = hdlrSock.close(); + CHECK_ERR(ret); + + ret = sock.close(); + CHECK_ERR(ret); + } while(0); + if(ret < 0) + { + WARN("TCP Server test failed"); + } + else + { + DBG("TCP Server test succeeded"); + } + + //UDP Socket test + do + { + DBG("UDP Client test"); + UDPSocket sock; + sock.bind(0); //Use a random port + const char daytime_cmd[] = "plop"; //Does not matter + ret = sock.sendTo((std::uint8_t*)daytime_cmd, sizeof(daytime_cmd) - 1, "utcnist.colorado.edu", 37, 3000); + CHECK_ERR(ret); + + char* inHost; + int inPort; + ret = sock.receiveFrom((std::uint8_t*)in_buf, 4, &inHost, &inPort, 3000); + CHECK_ERR(ret); + + std::uint32_t timeRes = ntohl( *((std::uint32_t*)in_buf)); + + DBG("Received %d bytes from server %s on port %d: %u seconds since 1/01/1900 00:00 GMT", ret, inHost, inPort, timeRes); + + ret = sock.close(); + CHECK_ERR(ret); + } while(0); + if(ret < 0) + { + WARN("UDP Client test failed"); + } + else + { + DBG("UDP Client test succeeded"); + } + + } + eth.disconnect(); + DBG("Disconnected"); + + notify(1, 1, 1); + + while (1) + { + Thread::wait(100); + } +} + +void keepAlive(void const*) +{ + while (1) + { + led1 = !led1; + Thread::wait(500); + } +} + +void tick() +{ + led4 = !led4; +} + +int main() +{ + Ticker t; + t.attach(tick, 1); + DBG_INIT(); + notify(1, 0, 0); + + Thread testTask(test, NULL, osPriorityNormal, 1024 * 4); + keepAlive(NULL); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Jun 15 16:38:40 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/976df7c37ad5 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtos.lib Fri Jun 15 16:38:40 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/emilmont/code/rtos/#d042ad0c4507
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx.lib Fri Jun 15 16:38:40 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/emilmont/code/rtx/#985806751475