mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
b36ddd7fd7
4
Makefile
4
Makefile
@ -2,10 +2,10 @@ DIRS = $(RIOTCPU) core drivers sys
|
||||
|
||||
all:
|
||||
mkdir -p $(BINDIR)
|
||||
@for i in $(DIRS) ; do $(MAKE) -C $$i ; done ;
|
||||
@for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ;
|
||||
|
||||
clean:
|
||||
@for i in $(DIRS) ; do $(MAKE) -C $$i clean ; done ;
|
||||
@for i in $(DIRS) ; do "$(MAKE)" -C $$i clean ; done ;
|
||||
-@if [ -d $(BINDIR) ] ; \
|
||||
then rmdir $(BINDIR) ; \
|
||||
fi
|
||||
|
||||
@ -17,7 +17,7 @@ include $(RIOTBASE)/Makefile.modules
|
||||
|
||||
# your binaries to link
|
||||
BASELIBS += $(RIOTBOARD)/$(BOARD)/bin/$(BOARD)_base.a
|
||||
BASELIBS += $(PROJBINDIR)/project.a
|
||||
BASELIBS += $(PROJBINDIR)/${PROJECT}.a
|
||||
|
||||
PROJBINDIR =$(CURDIR)/bin
|
||||
|
||||
@ -32,11 +32,24 @@ all: $(PROJBINDIR)/$(PROJECT).a
|
||||
|
||||
## your make rules
|
||||
## Only basic example - modify it for larger projects!!
|
||||
$(PROJBINDIR)/$(PROJECT).a: $(PROJBINDIR)/$(PROJECT).o
|
||||
$(AR) -rc $(PROJBINDIR)/project.a $(PROJBINDIR)/$(PROJECT).o
|
||||
|
||||
$(PROJBINDIR)/$(PROJECT).o: main.c
|
||||
$(CC) $(CFLAGS) $(BOARDINCLUDE) $(INCLUDES) -c main.c -o $(PROJBINDIR)/$(PROJECT).o
|
||||
#$(PROJBINDIR)/$(PROJECT).a: $(PROJBINDIR)/$(PROJECT).o
|
||||
# $(AR) -rc $(PROJBINDIR)/project.a $(PROJBINDIR)/$(PROJECT).o
|
||||
|
||||
# string array of all names of c files in dir
|
||||
SRC = $(wildcard *.c)
|
||||
|
||||
# string array of all names replaced .c with .o
|
||||
OBJ = $(SRC:%.c=${PROJBINDIR}/%.o)
|
||||
|
||||
${PROJBINDIR}/$(PROJECT).a: $(OBJ)
|
||||
$(AR) -rc bin/$(PROJECT).a $(OBJ)
|
||||
|
||||
# pull in dependency info for *existing* .o files
|
||||
-include $(OBJ:.o=.d)
|
||||
|
||||
${PROJBINDIR}/%.o: %.c
|
||||
@echo; echo "Compiling.... $*.c"; echo
|
||||
$(CC) $(CFLAGS) $(BOARDINCLUDE) $(INCLUDES) -c $*.c -o bin/$*.o
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(RIOTBOARD) clean
|
||||
@ -44,7 +57,7 @@ clean:
|
||||
rm -f $(PROJBINDIR)/*
|
||||
|
||||
flash: all
|
||||
$(FLASHER) $(PORT) $(PROJBINDIR)/$(PROJECT).hex
|
||||
$(FLASHER) $(FFLAGS)
|
||||
|
||||
term:
|
||||
$(TERM) $(PORT)
|
||||
|
||||
@ -77,7 +77,8 @@ unsigned number_of_highest_bit(unsigned v);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of the lowest '1' bit in a value
|
||||
* @param[in] v Input value
|
||||
* @param[in] v Input value - must be unequal to '0', otherwise the
|
||||
* function will produce an infinite loop
|
||||
* @return Bit Number
|
||||
*
|
||||
* Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
* interrupt context and must use the shortest possible execution time (e.g.
|
||||
* set a flag and trigger a worker thread).
|
||||
*
|
||||
* <b>hwtimer must not be used within applications</b>, use \ref swtimer
|
||||
* <b>hwtimer must not be used within applications</b>, use \ref vtimer
|
||||
* instead.
|
||||
*
|
||||
* @defgroup hwtimer Hardware timer
|
||||
|
||||
@ -24,6 +24,7 @@ this program. If not, see http://www.gnu.org/licenses/ .
|
||||
* @ingroup lpc2387
|
||||
* @brief LPC2387 NewLib system calls implementation
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics
|
||||
* @author Michael Baar <michael.baar@fu-berlin.de>
|
||||
*
|
||||
*/
|
||||
|
||||
@ -107,6 +107,15 @@ SECTIONS
|
||||
|
||||
} >flash /* put all the above into FLASH */
|
||||
. = ALIGN(4);
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >flash
|
||||
__exidx_end = .;
|
||||
|
||||
_etext = . ; /* define a global symbol _etext just after the last code byte */
|
||||
|
||||
.config :
|
||||
@ -175,7 +184,26 @@ SECTIONS
|
||||
_data = .; /* create a global symbol marking the start of the .data section */
|
||||
*(.data) /* all .data sections */
|
||||
*(.gnu.linkonce.d*)
|
||||
} >ram /* put all the above into RAM (but load the LMA copy into FLASH) */
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >ram /* put all the above into RAM (but load the LMA copy into FLASH) */
|
||||
. = ALIGN(4); /* ensure data is aligned so relocation can use 4-byte operations */
|
||||
_edata = .; /* define a global symbol marking the end of the .data section */
|
||||
|
||||
|
||||
4
dist/Makefile
vendored
4
dist/Makefile
vendored
@ -11,7 +11,9 @@
|
||||
export PROJECT =foobar
|
||||
|
||||
# for easy switching of boards
|
||||
export BOARD = msb-430
|
||||
ifeq ($(strip $(BOARD)),)
|
||||
export BOARD = msba2
|
||||
endif
|
||||
|
||||
# this has to be the absolute path of the RIOT-base dir
|
||||
export RIOTBASE =$(CURDIR)/../../RIOT
|
||||
|
||||
141
doc/getting_started.html
Normal file
141
doc/getting_started.html
Normal file
@ -0,0 +1,141 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Start the RIOT</title>
|
||||
<link href="riot.css" media="all" rel="stylesheet" type="text/css" >
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
|
||||
</head>
|
||||
<body>
|
||||
<h1>Start the RIOT - Getting started with RIOT</h1>
|
||||
|
||||
<div id="toc">
|
||||
<ol start="0">
|
||||
<li><a href="#requirements" title="Required tools and libraries">Requirements</a></li>
|
||||
<li><a href="#getcode" title="How to obtain RIOT">Get the source code</a></li>
|
||||
<li><a href="#toolchains" title="How to install and configure the toolchains">Setup the toolchain</a></li>
|
||||
<li><a href="#flasher" title="How to install a flasher">Setup a flashing tool</a></li>
|
||||
<li><a href="#hello" title="Build and run the famous hello world program">Hello World!</a></li>
|
||||
<li><a href="#firstapp" title="First Application">Write your first applicatoin</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<h2 id="requirements">Requirements</h2>
|
||||
<ul>
|
||||
<li>Git (<a href="http://git-scm.com/" title="A distributed version control
|
||||
system" target="_blank">http://git-scm.com/</a>)</li>
|
||||
<li>Python (for the terminal script) (<a href="http://www.python.org/" title="Python Programming Language" target="_blank">http://www.python.org/</a>)</li>
|
||||
<li>A toolchain (see <a href="#toolchains" title="How to install and configure
|
||||
the toolchains">Setup the toolchain</a>)</li>
|
||||
</ul>
|
||||
<p>You may not to install additional packages for particular toolchains or flashing tools. For the MSB-A2 check the requirements in the <a href="https://github.com/RIOT-OS/boards/wiki/For-MSB-A2" title="MSB-A2 Toolchain Installation" target="_blank">Github Wiki</a>.</p>
|
||||
<h2 id="getcode">Get the source code</h2>
|
||||
<p>You can obtain RIOT either by cloning the git repositories or download the latest tarballs.</p>
|
||||
|
||||
<h3>Using the git repository</h3>
|
||||
<p>In order to obtain RIOT from the official <a href="https://github.com/RIOT-OS/" title="RIOT at GitHub" target="_blank">GitHub</a> repositories, please perform the following commands:</p>
|
||||
<h4>The kernel</h4>
|
||||
<pre>
|
||||
git clone git://github.com/RIOT-OS/RIOT.git
|
||||
</pre>
|
||||
<h4>The platform configurations</h4>
|
||||
<pre>
|
||||
git clone git://github.com/RIOT-OS/boards.git
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
git clone git://github.com/RIOT-OS/thirdparty_boards.git
|
||||
git clone git://github.com/RIOT-OS/thirdparty_cpu.git
|
||||
</pre>
|
||||
|
||||
<h4><em>Optional (recommended):</em> Examplary projects</h4>
|
||||
<pre>
|
||||
git clone git://github.com/RIOT-OS/projects.git
|
||||
</pre>
|
||||
|
||||
<h3>Download the tarballs</h3>
|
||||
<p class="todo">TODO: Build tarballs!</p>
|
||||
|
||||
<h2 id="toolchains">Setup the toolchain</h2>
|
||||
<p>You can either build RIOT for one of the supported hardware platforms (check
|
||||
our <a href="http://riot-os.org/new/#usage" title="RIOT usage"
|
||||
target="_blank">website</a>) or try the native port. As a special platform,
|
||||
you will find a CPU and board called <i>native</i> in the repository. This
|
||||
target allows you to run RIOT as a process on Linux on most supported hardware
|
||||
platforms. Just set <tt>CPU</tt> and <tt>BOARD</tt> to native in your
|
||||
project's Makefile, call <tt>make</tt>, and execute the resulting elf-file.</p>
|
||||
<h3>For ARM</h3>
|
||||
<p>The recommended toolchain for RIOT on ARM is an older version (2008q3) of CodeBench (formerly CodeSourcery) from <a href="http://www.mentor.com/" title="Company Web Page">Mentor Graphics</a>. It can be obtained <a class="download" href="http://www.codesourcery.com/sgpp/lite/arm/portal/release642" title="CodeSourcery 2008q3">here</a>.</p>
|
||||
<h4>Linux</h4>
|
||||
<p>Direct links for Linux are </p>
|
||||
<p class="download"><a href="http://www.codesourcery.com/sgpp/lite/arm/portal/package3688/public/arm-none-eabi/arm-2008q3-66-arm-none-eabi.bin" title="Installer for Linux version">http://www.codesourcery.com/.../arm-2008q3-66-arm-none-eabi.bin</a> (with installer)</p>
|
||||
<p> or</p>
|
||||
<p class="download"><a href="http://www.codesourcery.com/sgpp/lite/arm/portal/package3686/public/arm-none-eabi/arm-2008q3-66-arm-none-eabi-i686-pc-linux-gnu.tar.bz2" title="Binary archive for Linux">http://www.codesourcery.com/.../arm-2008q3-66-arm-none-eabi-i686-pc-linux-gnu.tar.bz2</a>.</p>
|
||||
<p><em>Please note</em> that you will have to add the directory with executables (<tt>arm-none-eabi-gcc</tt>, <tt>arm-none-eabi-as</tt> etc.) to your <a href="http://en.wikipedia.org/wiki/PATH_(variable)" title="Wikipedia article about the PATH variable" target="_blank">PATH variable</a> in both cases.
|
||||
On a typical shell like bash or zsh this can be done using export, e.g.</p>
|
||||
<pre>
|
||||
export PATH=${PATH}:/path/to/arm-none-eabi-gcc
|
||||
</pre>
|
||||
<h4>Windows</h4>
|
||||
<p>The direct link for the Windows version is</p>
|
||||
<p class="download"><a href="http://www.codesourcery.com/sgpp/lite/arm/portal/package3689/public/arm-none-eabi/arm-2008q3-66-arm-none-eabi.exe" title="Installer for Windows version">http://www.codesourcery.com/.../arm-2008q3-66-arm-none-eabi.exe</a>.</p>
|
||||
<h4>Mac OS X</h4>
|
||||
<p>There is a tutorial to install the CodeSourcery toolchain on Mac OS X: <a href="https://gist.github.com/errordeveloper/1854389" title="CodeSourcery ARM (2008q3) bare-metal toolchain on OS X">https://gist.github.com/errordeveloper/1854389</a>.</p>
|
||||
<h4>Build the toolchain from sources</h4>
|
||||
<p>There is also the possibility to build the toolchain from the sources, allowing for newer versions of GCC, binutils, and Newlib. A script to build a toolchain for the MSB-A2 is available in the RIOT git repository at <br>
|
||||
<code>dist/tools/toolchains/build_gnuarm.sh</code>.</p>
|
||||
<h3>For MSP430</h3>
|
||||
<p>Download and install <a class="download" href="http://sourceforge.net/projects/mspgcc/"title="MSPGCC" target="_blank">GCC toolchain for MSP430</a> according to the information provided on the website.</p>
|
||||
<h3>For the native port</h3>
|
||||
<p>In order to build RIOT for the native port, you just need the <a class="download" href="http://gcc.gnu.org/" title="GCC, the GNU Compiler Collection" target="_blank">GNU
|
||||
Compiler Collection</a>.</p>
|
||||
|
||||
<h2 id="flasher">Setup a flashing tool</h2>
|
||||
<h3>For MSB-A2</h3>
|
||||
<ul>
|
||||
<li>Enter the <i>boards</i> directory and change to <i>msba2-common/tools</i>.</li>
|
||||
<li>Call <tt>make</tt>.</li>
|
||||
<li>Either run <tt>make install</tt> (you will need probably superuser
|
||||
rights to do this, i.e. you could run <tt>sudo make install</tt>) or add
|
||||
<i>boards/msba2-common/tools/bin/</i> to your <a
|
||||
href="http://en.wikipedia.org/wiki/PATH_(variable)" title="Wikipedia article
|
||||
about the PATH variable" target="_blank">PATH variable</a>.</li>
|
||||
<li>Install the driver for the FTDI chip from
|
||||
<a href="http://www.ftdichip.com/Drivers/VCP.htm" title="Virtual COM Port
|
||||
Drivers" target="_blank">FTDI homepage</a>.</li>
|
||||
</ul>
|
||||
<h3>For MSB-430H</h3>
|
||||
<p>Download and install <a class="download" href="http://mspdebug.sourceforge.net/download.html" title="Debugging and programming tool for MSP430 MCUs" target="_blank">MSPDebug</a> according to the information provided on the website. You can also use MSPDebug for debugging.</p>
|
||||
<h3>For redbee-econotag</h3>
|
||||
<p>Folow the instructions for <a href="http://mc1322x.devl.org/libmc1322x.html" title="LIBMC1322X"target="_blank">Getting Started with MC1322x</a>.
|
||||
<h3>For STM32F4DISCOVERY</h3>
|
||||
<p class="todo">TODO</p>
|
||||
|
||||
<h2 id="hello"><em>Optional:</em> Hello World!</h2>
|
||||
If you have obtained a copy of the projects repository, you can build the
|
||||
famous <em>Hello World</em> application for RIOT.
|
||||
<ul>
|
||||
<li>Enter the <i>projects</i> directory and change to <tt>hello-world</tt>.</li>
|
||||
<li>Edit the <tt>Makefile</tt> to set the variables <tt>RIOTBASE</tt> and
|
||||
<tt>RIOTBOARD</tt> according to where your copies of the RIOT repositories are located.</li>
|
||||
<li>Dependent on your target platform set the <tt>BOARD</tt> environment
|
||||
variable and call <tt>make</tt>, e.g. <tt>BOARD=msb-430h make</tt>.</li>
|
||||
<li>Now you program the resulting hex file on your target platform by calling
|
||||
<tt>make flash</tt>.</li>
|
||||
<li>Finally see the output of the application by running <tt>make term</tt>.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="firstapp">Write your first application</h2>
|
||||
<p>To write your own RIOT application, you just need a <tt>Makefile</tt> and C file(s)
|
||||
containing your source code. A template Makefile is available in the dist
|
||||
folder of the RIOT repository.</p>
|
||||
<p>One of the C files has to provide a main function according to this
|
||||
prototype:</p>
|
||||
<pre>
|
||||
int main(void);
|
||||
</pre>
|
||||
<p>Within your project's Makefile, you can define the modules you want to use.</p>
|
||||
<p>Unless specified otherwise, make will create an
|
||||
elf-file as well as an Intel hex file in the bin folder of your project
|
||||
directory.
|
||||
</body>
|
||||
</html>
|
||||
89
doc/riot.css
Normal file
89
doc/riot.css
Normal file
@ -0,0 +1,89 @@
|
||||
@font-face { font-family: 'MisoRegular'; src: url('../new/fonts/miso-regular.eot'); src: url('../new/fonts/miso-regular.eot?#iefix') format('embedded-opentype'), url('../new/fonts/miso-regular.woff') format('woff'), url('../new/fonts/miso-regular.ttf') format('truetype'), url('../new/fonts/miso-regular.svg#MisoRegular') format('svg');font-weight: normal; font-style: normal; }
|
||||
|
||||
H1,H2 {,
|
||||
font-family:"MisoRegular", Verdana, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
BODY {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
background: white;
|
||||
color: black;
|
||||
font-size: .9em;
|
||||
margin: 1em 10%;
|
||||
max-width: 800px;
|
||||
}
|
||||
h1 {
|
||||
text-align: left;
|
||||
font-size: 180%;
|
||||
margin: 0 -20px;
|
||||
padding: 0 1em 0 1em;
|
||||
color: #EEE;
|
||||
background-color: #BC1A29;
|
||||
}
|
||||
h2 {
|
||||
font-size: 140%;
|
||||
color: #EEE;
|
||||
background-color: #3fa687;
|
||||
padding: .2em 1em .2em 1em;
|
||||
margin: .4em -10px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 140%;
|
||||
margin: .5em .2em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 100%;
|
||||
margin: .5em .2em;
|
||||
}
|
||||
p, ul {
|
||||
}
|
||||
pre, code{
|
||||
font-family:monospace;
|
||||
font-size:1em;
|
||||
padding: .2em .4em;
|
||||
margin-left: 1.5em;
|
||||
background-color: #CCC;
|
||||
width: 50em;
|
||||
}
|
||||
a:link {
|
||||
color: #BC1A29;
|
||||
}
|
||||
a:visited {
|
||||
color: #BC1A29;
|
||||
}
|
||||
a:hover {
|
||||
color: #F00;
|
||||
text-decoration: none;
|
||||
}
|
||||
hr {
|
||||
height: 1px;
|
||||
border: none;
|
||||
border-top: 1px solid #d1d1d1;
|
||||
}
|
||||
#toc {
|
||||
margin-top: 1em;
|
||||
margin-left: 2em;
|
||||
width: 20em;
|
||||
background-color: #EEE;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
#toc ol {
|
||||
padding: .2em 3em;
|
||||
margin: 0;
|
||||
}
|
||||
#toc ol li {
|
||||
padding: .2em 0;
|
||||
}
|
||||
.todo {
|
||||
font-size: 140%;
|
||||
background-color: #F00;
|
||||
color: #FFF;
|
||||
}
|
||||
.download {
|
||||
background-color: #EEE;
|
||||
margin-top: -.5em;
|
||||
margin-bottom: .5em;
|
||||
max-width: 100%;
|
||||
}
|
||||
p.download {
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
@ -49,9 +49,6 @@ endif
|
||||
ifneq (,$(findstring shell_commands,$(USEMODULE)))
|
||||
DIRS += shell/commands
|
||||
endif
|
||||
ifneq (,$(findstring swtimer,$(USEMODULE)))
|
||||
DIRS += swtimer
|
||||
endif
|
||||
ifneq (,$(findstring timex,$(USEMODULE)))
|
||||
DIRS += timex
|
||||
endif
|
||||
|
||||
@ -30,10 +30,6 @@ void auto_init(void) {
|
||||
DEBUG("Auto init vtimer module.\n");
|
||||
vtimer_init();
|
||||
#endif
|
||||
#ifdef MODULE_SWTIMER
|
||||
DEBUG("Auto init swtimer module.\n");
|
||||
swtimer_init();
|
||||
#endif
|
||||
#ifdef MODULE_UART0
|
||||
DEBUG("Auto init uart0 module.\n");
|
||||
board_uart0_init();
|
||||
|
||||
@ -5,10 +5,6 @@
|
||||
#include <hwtimer.h>
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_SWTIMER
|
||||
#include <swtimer.h>
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_SHT11
|
||||
#include <sht11.h>
|
||||
#endif
|
||||
|
||||
@ -1,147 +0,0 @@
|
||||
/** \addtogroup system
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* \defgroup swtimer Software Timer library
|
||||
*
|
||||
* The swtimer library provides functions for setting, resetting and restarting
|
||||
* software timers, and for checking if a swtimer has expired.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Timer library header file.
|
||||
*/
|
||||
|
||||
#ifndef __SWTIMER_H__
|
||||
#define __SWTIMER_H__
|
||||
#warning Swtimers are deprecated. use virtual timers (vtimer) instead.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MSG_TIMER 12345
|
||||
|
||||
#define SWTIMER_WAKEUP 0
|
||||
#define SWTIMER_CALLBACK 1
|
||||
#define SWTIMER_MSG 2
|
||||
|
||||
#undef wakeup
|
||||
|
||||
typedef uint32_t swtime_t;
|
||||
|
||||
/**
|
||||
* A swtimer.
|
||||
*
|
||||
* This structure is used for declaring a swtimer. The swtimer must be set
|
||||
* with swtimer_set() before it can be used.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
typedef struct swtimer_t {
|
||||
swtime_t start;
|
||||
swtime_t interval;
|
||||
|
||||
struct swtimer_t *next;
|
||||
|
||||
int action_type;
|
||||
union {
|
||||
struct {
|
||||
int pid;
|
||||
} wakeup;
|
||||
struct {
|
||||
void (*f)(void*);
|
||||
void *ptr;
|
||||
} callback;
|
||||
struct {
|
||||
unsigned int value;
|
||||
int target_pid;
|
||||
} msg;
|
||||
} action;
|
||||
} swtimer_t;
|
||||
|
||||
/**
|
||||
* @brief Current system time
|
||||
* @return Time in ticks since system boot
|
||||
*/
|
||||
swtime_t swtimer_now(void);
|
||||
|
||||
/**
|
||||
* @brief Initializes swtimer
|
||||
* @return always 0
|
||||
*/
|
||||
int swtimer_init(void);
|
||||
|
||||
/**
|
||||
* @brief set swtimer interval and activate
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
* @param[in] interval swtimer interval
|
||||
* @return always 0
|
||||
*/
|
||||
int swtimer_set(swtimer_t *t, swtime_t interval);
|
||||
|
||||
/**
|
||||
* @brief reset swtimer
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
*/
|
||||
void swtimer_reset(swtimer_t *t);
|
||||
|
||||
/**
|
||||
* @brief restart swtimer
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
*/
|
||||
void swtimer_restart(swtimer_t *t);
|
||||
|
||||
/**
|
||||
* @brief check if swtimer is expired
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
* @return
|
||||
*/
|
||||
int swtimer_expired(swtimer_t *t);
|
||||
|
||||
/**
|
||||
* @brief will cause the calling thread to be suspended from excecution until the number of microseconds has elapsed
|
||||
* @param[in] us number of microseconds
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int swtimer_usleep(swtime_t us);
|
||||
|
||||
/**
|
||||
* @brief set a swtimer with msg event handler
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
* @param[in] interval swtimer interval
|
||||
* @param[in] pid process id
|
||||
* @param[in] ptr message value
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int swtimer_set_msg(swtimer_t *t, swtime_t interval, int pid, void *ptr);
|
||||
|
||||
/**
|
||||
* @brief set a swtimer with wakeup event
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
* @param[in] pid process id
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int swtimer_set_wakeup(swtimer_t *t, swtime_t interval, int pid);
|
||||
|
||||
/**
|
||||
* @brief set a swtimer with callback function event handler
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
* @param[in] interval swtimer interval
|
||||
* @param[in] f_ptr pointer to callback function
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int swtimer_set_cb(swtimer_t *t, swtime_t interval, void (*f_ptr)(void *), void *ptr);
|
||||
|
||||
/**
|
||||
* @brief remove a swtimer
|
||||
* @param[in] t pointer to preinitialised swtimer_t
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int swtimer_remove(swtimer_t *t);
|
||||
|
||||
#endif /* __SWTIMER_H__ */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
@ -6,14 +6,15 @@
|
||||
#include "cc110x/cc1100.h"
|
||||
#include "lpc2387.h"
|
||||
|
||||
#include "swtimer.h"
|
||||
#include "vtimer.h"
|
||||
#include "timex.h"
|
||||
#include "gpioint.h"
|
||||
#include <ping.h>
|
||||
|
||||
ping_payload *pipa;
|
||||
protocol_t protocol_id = 0;
|
||||
radio_address_t r_address = 0;
|
||||
uint64_t start = 0;
|
||||
timex_t start = 0;
|
||||
float rtt = 0;
|
||||
|
||||
void ping_handler(void *payload, int payload_size,
|
||||
@ -48,7 +49,7 @@ void ping(radio_address_t addr, uint8_t channr){
|
||||
cc1100_set_channel(channr);
|
||||
cc1100_set_address(r_address);
|
||||
while(1){
|
||||
start = swtimer_now();
|
||||
start = vtimer_now();
|
||||
int trans_ok = cc1100_send_csmaca(addr,
|
||||
protocol_id,2,pipa->payload,sizeof(pipa->payload));
|
||||
if(trans_ok < 0)
|
||||
@ -58,9 +59,10 @@ void ping(radio_address_t addr, uint8_t channr){
|
||||
}
|
||||
|
||||
void calc_rtt(void){
|
||||
uint64_t end = swtimer_now();
|
||||
timex_t end = vtimer_now();
|
||||
timex_t result = vtimer_sub(end, start);
|
||||
|
||||
rtt = ((float)end - (float)start)/1000;
|
||||
rtt = result.seconds+(float)result.microseconds/100000;
|
||||
}
|
||||
|
||||
void print_success(void){
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
INCLUDES = -I../include -I$(RIOTBASE)/core/include/ -I$(RIOTBASE)/drivers/include
|
||||
MODULE =swtimer
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -1,301 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* \ingroup system
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <msg.h>
|
||||
#include <thread.h>
|
||||
#include <hwtimer.h>
|
||||
#include <swtimer.h>
|
||||
#include <sched.h>
|
||||
#include <cpu.h>
|
||||
#include <irq.h>
|
||||
|
||||
#define SWTIMER_OVERHEAD 80
|
||||
#define SWTIMER_SPIN_THRESHOLD 100
|
||||
|
||||
//#define ENABLE_DEBUG
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
#undef SWTIMER_OVERHEAD
|
||||
#define SWTIMER_OVERHEAD 7500
|
||||
#endif
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
/* workaround for buggy mspgcc signal.h */
|
||||
#undef wakeup
|
||||
|
||||
static void swtimer_update_alarm(void);
|
||||
static void swtimer_action(swtimer_t *swtimer);
|
||||
static void swtimer_trigger(void* ptr);
|
||||
static void swtimer_tick(void *ptr);
|
||||
static int swtimer_activate(swtimer_t *t);
|
||||
static void swtimer_priolist_insert(swtimer_t *t);
|
||||
static void swtimer_update_values(void);
|
||||
|
||||
static swtimer_t *swtimer_list = NULL;
|
||||
static volatile swtime_t system_time = 0;
|
||||
volatile swtime_t swtimer_next_alarm_absolute = 0;
|
||||
static volatile unsigned long hwtimer_ticks_left = 0;
|
||||
static volatile int hwtimer_id = -1;
|
||||
|
||||
extern unsigned long hwtimer_now(void);
|
||||
|
||||
int swtimer_init(void) {
|
||||
hwtimer_set_absolute(HWTIMER_MAXTICKS, swtimer_tick, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int swtimer_set(swtimer_t *t, swtime_t interval) {
|
||||
t->interval = interval;
|
||||
t->next = NULL;
|
||||
swtimer_activate(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swtimer_activate(swtimer_t *t) {
|
||||
DEBUG("swtimer_activate. now=%lu t->interval = %lu hwtimer_ticks=%lu\n", swtimer_now(), t->interval, HWTIMER_TICKS(t->interval));
|
||||
|
||||
if (!inISR()) dINT();
|
||||
|
||||
if (t->interval <= SWTIMER_OVERHEAD) {
|
||||
DEBUG("swtimer_activate: interval too short, triggering right away.\n");
|
||||
swtimer_action(t);
|
||||
if (!inISR()) eINT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
t->start = swtimer_now();
|
||||
|
||||
swtimer_priolist_insert(t);
|
||||
|
||||
if (swtimer_list == t) {
|
||||
swtimer_update_values();
|
||||
swtimer_update_alarm();
|
||||
}
|
||||
|
||||
if (!inISR())eINT();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void swtimer_update_values(void) {
|
||||
swtimer_next_alarm_absolute = swtimer_list->start + swtimer_list->interval;
|
||||
swtime_t now = swtimer_now();
|
||||
swtime_t offset = swtimer_next_alarm_absolute - now;
|
||||
hwtimer_ticks_left = HWTIMER_TICKS(offset);
|
||||
|
||||
DEBUG("swtimer_update_values abs: %lu offset: %lu hwtimer_ticks_left: %lu, now=%lu, hwtimer_now=%lu\n", swtimer_next_alarm_absolute, offset, hwtimer_ticks_left, swtimer_now(), hwtimer_now());
|
||||
}
|
||||
|
||||
|
||||
int swtimer_remove(swtimer_t *t) {
|
||||
if ( (! swtimer_list) || (! t)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ! inISR() ) dINT();
|
||||
if (t == swtimer_list) {
|
||||
swtimer_list = t->next;
|
||||
if (swtimer_list) {
|
||||
swtimer_update_values();
|
||||
swtimer_update_alarm();
|
||||
} else {
|
||||
swtimer_next_alarm_absolute = 0;
|
||||
hwtimer_ticks_left = 0;
|
||||
hwtimer_remove(hwtimer_id);
|
||||
hwtimer_id = -1;
|
||||
}
|
||||
} else {
|
||||
swtimer_t *cur = t;
|
||||
while (cur) {
|
||||
if (cur->next == t) {
|
||||
cur->next = cur->next->next;
|
||||
break;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
if (! inISR() ) eINT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
swtime_t swtimer_now(void) {
|
||||
swtime_t now = system_time;
|
||||
now += HWTIMER_TICKS_TO_US(hwtimer_now());
|
||||
return now;
|
||||
}
|
||||
|
||||
int swtimer_set_msg(swtimer_t *t, swtime_t interval, int pid, void *ptr) {
|
||||
t->action_type = SWTIMER_MSG;
|
||||
t->action.msg.value = (unsigned int) ptr;
|
||||
t->action.msg.target_pid = pid;
|
||||
swtimer_set(t, interval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int swtimer_set_wakeup(swtimer_t *t, swtime_t interval, int pid) {
|
||||
t->action_type = SWTIMER_WAKEUP;
|
||||
t->action.wakeup.pid = pid;
|
||||
swtimer_set(t, interval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int swtimer_set_cb(swtimer_t *t, swtime_t interval, void (*f_ptr)(void *), void *ptr) {
|
||||
t->action_type = SWTIMER_CALLBACK;
|
||||
t->action.callback.f = f_ptr;
|
||||
t->action.callback.ptr = ptr;
|
||||
swtimer_set(t, interval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void swtimer_spin(swtime_t us) {
|
||||
swtime_t target = swtimer_now() + us;
|
||||
while (target > swtimer_now());
|
||||
}
|
||||
|
||||
int swtimer_usleep(swtime_t us) {
|
||||
if (inISR()) {
|
||||
swtimer_spin(us);
|
||||
return 0;
|
||||
}
|
||||
swtimer_t t;
|
||||
t.interval = us;
|
||||
t.action_type = SWTIMER_WAKEUP;
|
||||
t.action.wakeup.pid = thread_getpid();
|
||||
swtimer_activate(&t);
|
||||
thread_sleep();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void swtimer_priolist_insert(swtimer_t *t) {
|
||||
t->next = NULL;
|
||||
if (swtimer_list == NULL) {
|
||||
// DEBUG("swtimer: inserting first timer %x\n", (unsigned int)t);
|
||||
swtimer_list = t;
|
||||
} else {
|
||||
// DEBUG("swtimer: inserting timer %x\n", (unsigned int)t);
|
||||
swtime_t t_absolute = t->start + t->interval;
|
||||
swtimer_t *last = NULL;
|
||||
swtimer_t *cur = swtimer_list;
|
||||
while (cur != NULL) {
|
||||
if ( t_absolute < (cur->start + cur->interval) ) {
|
||||
// DEBUG("swtimer: timer %x elapses before timer %x\n", (unsigned int) t, (unsigned int) cur);
|
||||
t->next = cur;
|
||||
if (last) {
|
||||
// DEBUG("swtimer: setting ->next of %x to %x\n", (unsigned int) last->next, (unsigned int) t);
|
||||
last->next = t;
|
||||
} else {
|
||||
// DEBUG("swtimer: %x is first timer now.\n", (unsigned int)t);
|
||||
swtimer_list = t;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// DEBUG("insertF\n");
|
||||
if ( cur->next ) {
|
||||
// DEBUG("insertF1\n");
|
||||
last = cur;
|
||||
cur = cur->next;
|
||||
} else {
|
||||
// DEBUG("insertF2\n");
|
||||
cur->next = t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void swtimer_set_hwtimer(unsigned int offset) {
|
||||
DEBUG("swtimer_set_hwtimer: hwtimer_now: %lu offset:%u\n", hwtimer_now(), offset);
|
||||
if (hwtimer_id != -1) {
|
||||
hwtimer_remove(hwtimer_id);
|
||||
}
|
||||
|
||||
hwtimer_id = hwtimer_set (offset, swtimer_trigger, NULL);
|
||||
}
|
||||
|
||||
static void swtimer_action(swtimer_t *swtimer) {
|
||||
switch(swtimer->action_type) {
|
||||
case SWTIMER_WAKEUP:
|
||||
{
|
||||
thread_wakeup(swtimer->action.wakeup.pid);
|
||||
break;
|
||||
}
|
||||
case SWTIMER_CALLBACK:
|
||||
{
|
||||
swtimer->action.callback.f(swtimer->action.callback.ptr);
|
||||
break;
|
||||
}
|
||||
case SWTIMER_MSG:
|
||||
{
|
||||
msg_t m;
|
||||
m.content.value = swtimer->action.msg.value;
|
||||
int result = msg_send_int(&m, swtimer->action.msg.target_pid);
|
||||
if (result < 0) {
|
||||
// error
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void swtimer_trigger(void* ptr) {
|
||||
swtimer_t *next = swtimer_list;
|
||||
swtimer_list = swtimer_list->next;
|
||||
swtimer_action(next);
|
||||
if (! ptr) swtimer_update_alarm();
|
||||
}
|
||||
|
||||
|
||||
static void swtimer_update_alarm(void) {
|
||||
DEBUG("swtimer_check_elapsed: Checking for elapsed timer...\n");
|
||||
|
||||
while (swtimer_list) {
|
||||
swtimer_update_values();
|
||||
DEBUG("swtimer_check_elapsed: there are timers left to consider. hwtimer_ticks_left=%lu\n", hwtimer_ticks_left);
|
||||
|
||||
if (hwtimer_ticks_left > HWTIMER_MAXTICKS) {
|
||||
if ((long int) hwtimer_ticks_left < 0) {
|
||||
printf("swtimer_update_alarm: We're late!\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (hwtimer_ticks_left < SWTIMER_SPIN_THRESHOLD) {
|
||||
DEBUG("swtimer_check_elapsed: spinning..\n");
|
||||
if (hwtimer_ticks_left != 0) hwtimer_spin(hwtimer_ticks_left);
|
||||
DEBUG("swtimer_check_elapsed: spinning done. shooting timer.\n");
|
||||
swtimer_trigger((void*)1); /* flag to prevent recursion */
|
||||
} else {
|
||||
DEBUG("swtimer_check_elapsed: Setting hwtimer.\n");
|
||||
swtimer_set_hwtimer(hwtimer_ticks_left);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void swtimer_tick(void* offset_ptr) {
|
||||
hwtimer_set_absolute(HWTIMER_MAXTICKS, swtimer_tick, NULL);
|
||||
system_time += HWTIMER_TICKS_TO_US(HWTIMER_MAXTICKS);
|
||||
|
||||
// DEBUG("swtimer_tick: system_time: %lu next timer: %lu ticks_left: %lu pid=%i\n", system_time, swtimer_next_alarm_absolute, hwtimer_ticks_left, thread_getpid());
|
||||
DEBUG(".");
|
||||
|
||||
if (swtimer_next_alarm_absolute > 0) {
|
||||
if (hwtimer_ticks_left > HWTIMER_MAXTICKS) {
|
||||
hwtimer_ticks_left -= HWTIMER_MAXTICKS;
|
||||
swtimer_update_alarm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
Loading…
x
Reference in New Issue
Block a user