Commit 01046ab6 authored by Martin Horauer's avatar Martin Horauer
Browse files

added HTTP example

parent 1f762269
This diff is collapsed.
TARGET=XMC_4500_RELAX_KIT
TOOLCHAIN=GCC_ARM
ROOT=.
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>APP_BLINKY</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
\ No newline at end of file
################################################################################
# Makefile for XMC4500 RelaxKit using uCOS-III
# v1, 02/2018
# Martin Horauer, UAS Technikum Wien
#
# Supported: Windows, Linux, OSX
# Requirements:
# * GCC ARM https://launchpad.net/gcc-arm-embedded/+download
# * SEGGER JLINK https://www.segger.com/jlink-software.html
# * DOXYGEN http://www.stack.nl/~dimitri/doxygen/
################################################################################
# USAGE
# -----
# make .... build the program image
# make debug .... build the program image and invoke gdb
# make flash .... build an flash the application
# make erase .... erase the target device
# make doc .... run doxygen - output will be in > doc
# make clean .... remove intermediate and generated files
################################################################################
# define the name of the generated output file
#
TARGET = main
################################################################################
# below only edit with care
#
VENDOR = Infineon
################################################################################
# define the following symbol -D JLINK_RTT to enable JLINK_RTT tracing
# -D SEMI_HOSTING to enable semi hosted tracing
# comment the line to disable tracing
TRACE = -D SEMI_HOSTING
################################################################################
# TOOLS & ARGS
#
SRC = $(wildcard *.cpp)
TERMINAL = gnome-terminal
TOOLCHAIN = GCC_ARM
BOARD = XMC_4500_RELAX_KIT
BUILDDIR = BUILD
DOCDIR = DOC
MBED = mbed
GDB = arm-none-eabi-gdb
# DETERMINE OS
ifdef SystemRoot
RM = del /Q
FixPath = $(subst /,\,$1)
else
RM = rm -rf
FixPath = $1
endif
GDB_ARGS = -ex "target remote :2331"
GDB_ARGS += -ex "monitor reset"
GDB_ARGS += -ex "load"
GDB_ARGS += -ex "monitor reset"
################################################################################
# SEMI_HOSTED DEBUGGING
GDB_ARGS += -ex "monitor SWO EnableTarget 16000000 0 1 0"
# RTT OPTION
#GDB_ARGS += -ex "monitor exec SetRTTAddr 0x20000000"
#GDB_ARGS += -ex "monitor exec SetRTTSearchRanges 0x20000000 0x1000"
################################################################################
# BUILD RULES
all: $(SRC) build
################################################################################
# CREATE A DEBUG VESRION
build: $(SRC)
@echo "----------------------------------------------------------------------"
@echo "Building with DEBUG Symbols"
@echo ""
$(MBED) compile -m $(BOARD) -t $(TOOLCHAIN) -N main --profile mbed-os/tools/profiles/debug.json
@echo ""
################################################################################
# CREATE A RELEASE VESRION
release: $(SRC)
@echo "----------------------------------------------------------------------"
@echo "Build a RELEASE version"
@echo ""
$(MBED) compile -m $(BOARD) -t $(TOOLCHAIN) -N main
@echo ""
################################################################################
# DEBUG RULES
debug: build $(BUILDDIR)/$(BOARD)/$(TOOLCHAIN)/$(TARGET).elf
ifdef SystemRoot
@call start JLinkGDBServer -Device XMC4500-1024 -if SWD
else
$(TERMINAL) -e "JLinkGDBServer -Device XMC4500-1024 -if SWD" &
sleep 1 && $(TERMINAL) -e "telnet 127.0.0.1 2333" &
endif
$(GDB) -q $(BUILDDIR)/$(BOARD)/$(TOOLCHAIN)/$(TARGET).elf $(GDB_ARGS)
################################################################################
# FLASH RULES
flash: build $(BUILDDIR)/$(BOARD)/$(TOOLCHAIN)/$(TARGET).hex
echo -e 'speed 4000\nconnect\nh\nloadbin $(BUILDDIR)/$(BOARD)/$(TOOLCHAIN)/$(TARGET).hex,0xC000000\nr\ng\nq' | JLinkExe -Device XMC4500-1024 -if SWD
################################################################################
# ERASE DEVICE
erase:
echo -e 'speed 4000\nconnect\nerase\nr\nq' | JLinkExe -Device XMC4500-1024 -if SWD
################################################################################
# DOCUMENTATION RULES
doc: $(SRC)
doxygen
################################################################################
# CLEAN RULES
clean:
$(RM) $(call FixPath, *.pyc)
$(RM) $(call FixPath, ${BUILDDIR}/*)
$(RM) $(call FixPath, ${DOCDIR}/html/*)
################################################################################
# EOF
################################################################################
= Simple HTTP Server Example
This example shows how you can setup the Ethernet Interface on the XMC4500
RelaxKit to run a simple HTTP server.
The web-ui provides functionality to toggle both Led's and see the actual status
of the push buttons. Furthermore, the network time provided by an NTP server can
be programmed into the internal RTC.
image:xmc_server.png[]
== Project Setup
This project relies on other libraries. In particular, if the folder
`ntp-client` and/or the file `ntp-client.lib` are missing, execute:
[source%nowrap, c]
----
mbed add https://github.com/ARMmbed/ntp-client/#72a3f00ca7c1da7042d53d7f3c59a73cb208571d
----
== Configuration: Static IP Address
Use this option when connecting directly with the ethernet interface on your PC.
To that end, define `STATIC_IP` to configure the IP-Address, Network-Mask and
Default Gateway as shown below:
[source%nowrap, c]
----
#define STATIC_IP
/* IP-Address Network-Mask Gateway */
eth.set_network("192.168.1.40", "255.255.255.0", "192.168.1.2");
----
image:static_ip_config.png[]
== Configuration: Dynamic IP Address
Use this option when connecting the XMC directly to an network switch. To that
end, remove the `STATIC_IP` to get an IP-Address from an DHCP server in your
network.
[source%nowrap, c]
----
// #define STATIC_IP
----
== Testing
TIP: Connect the STDIO UART to see which IP-Address the XMC gets from the DHCP
server.
image:xmc_server_log.png[]
TIP: Wireshark and ICMP (Ping...) are very helpful tools to debug or monitor
your application!
== Known Bugs
* Only works if the ethernet cable is plugged-in during start-up! Workaround:
Create a thread to monitor the ethernet link!
* Clicking the `Toggle Led` button at the same time when the web-page is
refreshing can cause a missing button request because the TCP-Socket is already
in use!
== Makefile Usage
[source%nowrap, bash]
----
make # build the application
make flash # flash the application
make debug # debug the application
make erase # erase the program memory
make doc # invoke doxygen
make clean # clean the project
----
= Manual
== Building
[source%nowrap, bash]
----
mbed compile -c -m XMC_4500_RELAX_KIT -t GCC_ARM -N main
----
This creates several files in the BUILD directory where you can find the
executable (bin, elf, hex ...).
== Flashing
[source%nowrap, bash]
----
$ JLinkExe -Device XMC4500-1024 -if SWD -speed 4000
J-LINK> h
J-Link> loadfile BUILD/XMC_4500_RELAX_KIT/GCC_ARM/main.hex
J-Link> r
J-Link> g
----
== Debugging
(1) Build the application with debug symbols enabled by adding `--profile mbed-os/tools/profiles/debug.json`.
[source%nowrap, bash]
----
mbed compile -c -m XMC_4500_RELAX_KIT -t GCC_ARM -N main --profile mbed-os/tools/profiles/debug.json
----
(2) Start the `JLinkGDEBServer`, e.g.:
[source%nowrap, bash]
----
JLinkGDBServer -Device XMC4500-1024 -if SWD
----
(3) In order to log messages printed to `stdout` we connect to port 2333 via
telnet.
[source%nowrap, bash]
----
telnet 127.0.0.1 2333
----
(4) We launch the debugger and control the debug session:
[source%nowrap, bash]
----
arm-none-eabi-gdb -q BUILD/XMC_4500_RELAX_KIT/GCC_ARM/main.elf
(gdb) target remote :2331
(gdb) monitor reset
(gdb) load
(gdb) monitor reset
(gdb) b main
(gdb) c
[...]
----
This diff is collapsed.
/* mbed Example Program
* Copyright (c) 2006-2014 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************* Includes */
#include "mbed.h"
#include "rtos.h"
#include "EthernetInterface.h"
#include "NTPClient.h"
#include "TCPServer.h"
#include "TCPSocket.h"
/******************************************************************** Defines */
#define NTP_UPDATE_TIME 0x01
#define STATIC_IP 1
/************************************************************** HTTP Response */
static char http_response[2048];
static const char http_status_line[] = "HTTP/1.0 200 OK\r\n";
static const char http_header_fields[] = "Content-Type: text/html; charset=utf-8\r\n\r\n";
static char http_msg_body[] = "" \
"<html>" "\r\n" \
" <body style=\"display:flex;text-align:center\">" "\r\n" \
" <div style=\"margin:auto\">" "\r\n" \
" <h1>HTTP Server Example</h1>" "\r\n" \
" <p>Toggle the Led's on the XMC4500 Relax Kit !</p>" "\r\n" \
" <button id=\"toggle1\">Toggle LED1</button>" "\r\n" \
" <button id=\"toggle2\">Toggle LED2</button>" "\r\n" \
" <p>Button 1: Inactive</p>" "\r\n" \
" <p>Button 2: Inactive</p>" "\r\n" \
" <p>Program Network Time into RTC</p>" "\r\n" \
" <button id=\"set_time\">Set Time</button>" "\r\n" \
" <p>Actual System Time: Sat Mar 3 20:25:32 2018 </p>" "\r\n" \
" </div> <br>" "\r\n" \
" </body>" "\r\n" \
" <br>" "\r\n" \
" <script>document.querySelector('#toggle1').onclick = function() {" \
" var x1 = new XMLHttpRequest(); x1.open('POST', '/toggle1'); x1.send();" \
" }</script>" \
" <script>document.querySelector('#toggle2').onclick = function() {" \
" var x2 = new XMLHttpRequest(); x2.open('POST', '/toggle2'); x2.send();" \
" }</script>" \
" <script>document.querySelector('#set_time').onclick = function() {" \
" var x3 = new XMLHttpRequest(); x3.open('POST', '/set_time'); x3.send();" \
" }</script>" \
" <script>var myVar = setInterval(myTimer, 1000);" \
" function myTimer() {" \
" location.reload(true); " \
" }</script>" \
"</html>";
/******************************************************************** Globals */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalIn sw1(SW1);
DigitalIn sw2(SW2);
Thread ntp_thread;
Thread bt_thread;
EventFlags ntp_update_event;
/****************************************************************** Functions */
/**
* Change timestamp in http source
*/
static void change_button_state_in_http_source(void){
char *ret;
/* Change button 1 state */
ret = strstr(http_msg_body, "Button 1:");
if(!sw1){
strncpy(ret + 10, "Active ", 8);
}else{
strncpy(ret + 10, "Inactive", 8);
}
/* Change button 2 state */
ret = strstr(http_msg_body, "Button 2:");
if(!sw2){
strncpy(ret + 10, "Active ", 8);
}else{
strncpy(ret + 10, "Inactive", 8);
}
/* Build new http response */
sprintf(http_response, "%s%s%s",http_status_line, http_header_fields, http_msg_body);
}
/**
* Change buttons state in http source
*/
static void change_timestamp_in_http_source(void){
char *ret;
/* Get current time from RTC */
time_t seconds = time(NULL);
/* Change time string in http_msg_body[] */
ret = strstr(http_msg_body, "Time:");
strncpy(ret + 6, ctime(&seconds), 25);
/* Build new http response */
sprintf(http_response, "%s%s%s",http_status_line, http_header_fields, http_msg_body);
}
/**
* NTP Client Thread
*/
void ntp_client_thread(EthernetInterface *eth) {
NTPClient ntp(eth);
time_t timestamp;
while (true) {
/* Wait until request from main thread */
ntp_update_event.wait_all(NTP_UPDATE_TIME);
/* Get Time from NTP server */
timestamp = ntp.get_timestamp(5000);
if (timestamp < 0) {
printf("An error occurred when getting the time. Code: %lld\r\n", timestamp);
} else {
/* Set RTC Time */
set_time(timestamp);
/* Print Time */
printf("Current time is %s\r\n", ctime(&timestamp));
}
}
}
/**
* Update Button state thread
*/
void button_thread(void) {
while (true) {
wait(1);
change_button_state_in_http_source();
change_timestamp_in_http_source();
}
}
/**
* Main Function
*/
int main()
{
TCPServer srv;
TCPSocket clt_sock;
SocketAddress clt_addr;
EthernetInterface eth;
char rec_buffer[256];
int rcount;
printf("Basic HTTP server example\n");
#ifdef STATIC_IP
eth.set_network("192.168.1.40", "255.255.255.0", "192.168.1.2");
#endif
/* Initialize low level Ethernet driver and lwip stack */
eth.connect();
/* Print target IP address */
printf("The target IP address is '%s'\n", eth.get_ip_address());
/* Open the server on ethernet stack */
srv.open(&eth);
/* Bind the HTTP port (TCP 80) to the server */
srv.bind(eth.get_ip_address(), 80);
/* Can handle 5 simultaneous connections */
srv.listen(5);
/* Set RTC time to 1 Jan 1970 */
set_time(0);
/* Update timestamp in http source */
change_timestamp_in_http_source();
/* start NTP client thread */
ntp_thread.start(callback(ntp_client_thread, &eth));
/* start button update thread */
bt_thread.start(button_thread);
while (true) {
/* Wait until request from client */
srv.accept(&clt_sock, &clt_addr);
printf("accept %s:%d\n", clt_addr.get_ip_address(), clt_addr.get_port());
/* Get receive message */
rcount = clt_sock.recv(rec_buffer, sizeof rec_buffer);
printf("recv %d [%.*s]\r\n", rcount, strstr(rec_buffer, "\r\n")-rec_buffer, rec_buffer);
/* Check if LED1 toggle button was clicked */
if(strstr(rec_buffer, "toggle1") != NULL){
led1 = !led1;
continue;
}
/* Check if LED2 toggle button was clicked */
if(strstr(rec_buffer, "toggle2") != NULL){
led2 = !led2;
continue;
}
/* Check if Set Time button was clicked */
if(strstr(rec_buffer, "set_time") != NULL){
/* Notify NTP client thread to update time */
ntp_update_event.set(NTP_UPDATE_TIME);
continue;
}
/* Send HTTP response */
clt_sock.send(http_response, strlen(http_response));
}
}
/*EOF*/
../mbed-os/
\ No newline at end of file
https://github.com/mbed-Infineon-XMC/mbed-os/#e12da153ac2ed9ee8693c8aaa5c3eabae5d6c36c
"""
mbed SDK
Copyright (c) 2016 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import subprocess
from os.path import join, abspath, dirname
#ROOT = abspath(join(dirname(__file__), "."))
##############################################################################
# Build System Settings
##############################################################################
#BUILD_DIR = abspath(join(ROOT, "build"))
# ARM
#ARM_PATH = "C:/Program Files/ARM"
# GCC ARM
#GCC_ARM_PATH = ""
GCC_ARM_PATH = dirname(subprocess.check_output(["which", "arm-none-eabi-gcc"]))
# GCC CodeRed
#GCC_CR_PATH = "C:/code_red/RedSuite_4.2.0_349/redsuite/Tools/bin"
# IAR
#IAR_PATH = "C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.0/arm"
# Goanna static analyser. Please overload it in private_settings.py
#GOANNA_PATH = "c:/Program Files (x86)/RedLizards/Goanna Central 3.2.3/bin"
#BUILD_OPTIONS = []
# mbed.org username
#MBED_ORG_USER = ""
ntp-client @ 72a3f00c
Subproject commit 72a3f00ca7c1da7042d53d7f3c59a73cb208571d
https://github.com/ARMmbed/ntp-client/#72a3f00ca7c1da7042d53d7f3c59a73cb208571d
......@@ -36,6 +36,17 @@ This adds a folder `ADJDs311` containing the respective sources and adds a file
`ADJDs311.lib` that simply contains the above link. This löibrary will than be
considered when the project is being built.
== STDIO_UART
The mbed library outputs `printf()` messages via a standard UART interface that
is per default enabled and configured. For the XMC RelaxKit the default UART is
configured in
`targets/TARGET_Infineon/TARGET_XMC4XXX/TARGET_XMC4500/PeripheralNames.h` and