core/
This commit is contained in:
commit
e89dc07a05
23
core/mutex.c
23
core/mutex.c
@ -79,6 +79,7 @@ void mutex_wait(struct mutex_t *mutex) {
|
|||||||
/* we were woken up by scheduler. waker removed us from queue. we have the mutex now. */
|
/* we were woken up by scheduler. waker removed us from queue. we have the mutex now. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
void mutex_unlock(struct mutex_t* mutex, int yield) {
|
void mutex_unlock(struct mutex_t* mutex, int yield) {
|
||||||
DEBUG("%s: unlocking mutex. val: %u pid: %u\n", active_thread->name, mutex->val, thread_pid);
|
DEBUG("%s: unlocking mutex. val: %u pid: %u\n", active_thread->name, mutex->val, thread_pid);
|
||||||
int irqstate = disableIRQ();
|
int irqstate = disableIRQ();
|
||||||
@ -94,6 +95,28 @@ void mutex_unlock(struct mutex_t* mutex, int yield) {
|
|||||||
} else {
|
} else {
|
||||||
mutex->val = 0;
|
mutex->val = 0;
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
void mutex_wake_waiters(struct mutex_t *mutex, int flags) {
|
||||||
|
if ( ! (flags & MUTEX_INISR)) dINT();
|
||||||
|
DEBUG("%s: waking up waiters.\n", fk_thread->name);
|
||||||
|
|
||||||
|
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
||||||
|
|
||||||
|
/* queue is empty */
|
||||||
|
if (!next) {
|
||||||
|
mutex->val = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcb* process = (tcb*)next->data;
|
||||||
|
|
||||||
|
sched_set_status(process, STATUS_PENDING);
|
||||||
|
|
||||||
|
if ( mutex->queue.next != NULL) {
|
||||||
|
mutex->val = -1;
|
||||||
|
} else {
|
||||||
|
mutex->val = process->pid;
|
||||||
|
>>>>>>> 2919cc18c84c53e1aedb6c7e3f39162635b5ab70
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreIRQ(irqstate);
|
restoreIRQ(irqstate);
|
||||||
|
|||||||
15
core/sched.c
15
core/sched.c
@ -35,7 +35,11 @@ volatile int thread_pid;
|
|||||||
clist_node_t *runqueues[SCHED_PRIO_LEVELS];
|
clist_node_t *runqueues[SCHED_PRIO_LEVELS];
|
||||||
static uint32_t runqueue_bitcache = 0;
|
static uint32_t runqueue_bitcache = 0;
|
||||||
|
|
||||||
|
void sched_register_cb(void (*callback)(uint32_t, uint32_t));
|
||||||
|
|
||||||
|
|
||||||
#if SCHEDSTATISTICS
|
#if SCHEDSTATISTICS
|
||||||
|
static void (*sched_cb)(uint32_t timestamp, uint32_t value) = NULL;
|
||||||
schedstat pidlist[MAXTHREADS];
|
schedstat pidlist[MAXTHREADS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -112,6 +116,12 @@ void sched_run() {
|
|||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
#if SCHEDSTATISTICS
|
||||||
|
if ((sched_cb) && (my_fk_thread->pid != last_pid)) {
|
||||||
|
sched_cb(hwtimer_now(), my_fk_thread->pid);
|
||||||
|
last_pid = my_fk_thread->pid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("scheduler: next task: %s\n", my_active_thread->name);
|
DEBUG("scheduler: next task: %s\n", my_active_thread->name);
|
||||||
@ -130,6 +140,11 @@ void sched_run() {
|
|||||||
DEBUG("scheduler: done.\n");
|
DEBUG("scheduler: done.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SCHEDSTATISTICS
|
||||||
|
void sched_register_cb(void (*callback)(uint32_t, uint32_t)) {
|
||||||
|
sched_cb = callback;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void sched_set_status(tcb_t *process, unsigned int status) {
|
void sched_set_status(tcb_t *process, unsigned int status) {
|
||||||
if (status & STATUS_ON_RUNQUEUE) {
|
if (status & STATUS_ON_RUNQUEUE) {
|
||||||
|
|||||||
7
projects/OHM/Jamfile
Normal file
7
projects/OHM/Jamfile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
SubDir TOP projects OHM ;
|
||||||
|
|
||||||
|
CCFLAGS += -DSCHEDSTATISTICS ;
|
||||||
|
|
||||||
|
Module OHM : profiling.c main.c ohm_routing.c protocol_msg_gateway.c ohm_cc1100.c ohm_rtc.c ohm_ltc4150.c : cc110x sht11 gpioint shell shell_commands posix_io uart0 auto_init rtc ps board_ltc4150 ;
|
||||||
|
|
||||||
|
UseModule OHM ;
|
||||||
43
projects/OHM/cib.c
Normal file
43
projects/OHM/cib.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <cib.h>
|
||||||
|
|
||||||
|
void cib_init(cib_t *cib, unsigned int size) {
|
||||||
|
cib->read_count = 0;
|
||||||
|
cib->write_count = 0;
|
||||||
|
cib->complement = 0-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cib_avail (cib_t *cib) {
|
||||||
|
return cib->write_count - cib->read_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cib_get(cib_t *cib) {
|
||||||
|
int avail = cib_avail (cib);
|
||||||
|
|
||||||
|
if (avail > 0) {
|
||||||
|
return cib->read_count++ & ~cib->complement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cib_put(cib_t *cib) {
|
||||||
|
int avail = cib_avail (cib);
|
||||||
|
|
||||||
|
if ((int)(avail + cib->complement) < 0 ) {
|
||||||
|
return cib->write_count++ & ~(cib->complement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int main() {
|
||||||
|
cib_t cib;
|
||||||
|
|
||||||
|
cib_init(&cib, 0);
|
||||||
|
|
||||||
|
int res = cib_get(&cib);
|
||||||
|
|
||||||
|
printf("%i\n", res);
|
||||||
|
}
|
||||||
|
*/
|
||||||
15
projects/OHM/cib.h
Normal file
15
projects/OHM/cib.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef __CIB_H
|
||||||
|
#define __CIB_H
|
||||||
|
|
||||||
|
typedef struct cib_t {
|
||||||
|
unsigned int read_count;
|
||||||
|
unsigned int write_count;
|
||||||
|
unsigned int complement;
|
||||||
|
} cib_t;
|
||||||
|
|
||||||
|
void cib_init(cib_t *cib, unsigned int size);
|
||||||
|
int cib_get(cib_t *cib);
|
||||||
|
int cib_put(cib_t *cib);
|
||||||
|
int cib_avail(cib_t *cib);
|
||||||
|
|
||||||
|
#endif /* __CIB_H */
|
||||||
476
projects/OHM/main.c
Normal file
476
projects/OHM/main.c
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
/* stdlib includes */
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
|
#include <msg.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <hwtimer.h>
|
||||||
|
#include <cib.h>
|
||||||
|
#include <scheduler.h>
|
||||||
|
|
||||||
|
//#define ENABLE_DEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* sensors and actors */
|
||||||
|
#include <board.h>
|
||||||
|
#include <sht11.h>
|
||||||
|
#include <ltc4150.h>
|
||||||
|
|
||||||
|
/* shell */
|
||||||
|
#include <shell.h>
|
||||||
|
#include <board_uart0.h>
|
||||||
|
#include <posix_io.h>
|
||||||
|
|
||||||
|
/* transceiver */
|
||||||
|
#include <cc1100.h>
|
||||||
|
#include <cc1100-defaultSettings.h>
|
||||||
|
|
||||||
|
/* real time clock */
|
||||||
|
#include <lpc2387-rtc.h>
|
||||||
|
|
||||||
|
/* application header */
|
||||||
|
#include "ohm.h"
|
||||||
|
#include "ohm_routing.h"
|
||||||
|
#include "ohm_protocol.h"
|
||||||
|
#include "protocol_msg_gateway.h"
|
||||||
|
|
||||||
|
#define CC1100_RADIO_MODE CC1100_MODE_WOR
|
||||||
|
|
||||||
|
/* some local defines */
|
||||||
|
#define SECOND (1000 * 1000)
|
||||||
|
#define MINUTE (1 * SECOND)
|
||||||
|
|
||||||
|
/* size of ohm data packet without hop list */
|
||||||
|
#define EMPTY_WDP_SIZE (sizeof(ohm_data_pkt_t) - MAX_HOP_LIST)
|
||||||
|
|
||||||
|
/* default values */
|
||||||
|
#define DEFAULT_INTERVAL (5 * SECOND)
|
||||||
|
|
||||||
|
/* stack space for threads */
|
||||||
|
#define SHELL_STACK_SIZE (2048)
|
||||||
|
#define PH_STACK_SIZE (2048)
|
||||||
|
|
||||||
|
/* debugging pins */
|
||||||
|
#define P10_TOGGLE (FIO1PIN ^= BIT0)
|
||||||
|
#define P11_TOGGLE (FIO1PIN ^= BIT1)
|
||||||
|
#define P14_TOGGLE (FIO1PIN ^= BIT4)
|
||||||
|
|
||||||
|
char shell_stack_buffer[SHELL_STACK_SIZE];
|
||||||
|
char ph_stack_buffer[PH_STACK_SIZE];
|
||||||
|
|
||||||
|
/* Coulomb, thread and function measurement buffers */
|
||||||
|
volatile uint32_t cb_buf[MAX_TICK_BUF_SIZE];
|
||||||
|
volatile uint32_t *cb_buf_ptr;
|
||||||
|
volatile ohm_measurement_t thread_buf[MAX_THREAD_BUF_SIZE];
|
||||||
|
volatile ohm_measurement_t *thread_buf_ptr;
|
||||||
|
volatile ohm_measurement_t func_buf[MAX_FUNC_BUF_SIZE];
|
||||||
|
volatile ohm_measurement_t *func_buf_ptr;
|
||||||
|
|
||||||
|
uint32_t otto_says = 0;
|
||||||
|
uint8_t measure_pause = 1;
|
||||||
|
|
||||||
|
/* per default acting only as relay */
|
||||||
|
static uint8_t data_sink = 0;
|
||||||
|
static uint8_t data_src = 0;
|
||||||
|
|
||||||
|
cib_t cib;
|
||||||
|
uint16_t pkts_processed = 0;
|
||||||
|
|
||||||
|
static uint32_t sending_interval = DEFAULT_INTERVAL;
|
||||||
|
|
||||||
|
extern uint8_t gossip_probability;
|
||||||
|
extern void _cc110x_get_set_address_handler(char *addr);
|
||||||
|
extern void _cc110x_get_set_channel_handler(char *chan);
|
||||||
|
extern void _date_handler(char* c);
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
static void ohm_send(char* unused);
|
||||||
|
static void ohm_sink(char* unused);
|
||||||
|
static void set_interval(char* interval);
|
||||||
|
static void set_probability(char* prob);
|
||||||
|
static void print_cc1100_info(char* unused);
|
||||||
|
static void stat_handler(char* unused);
|
||||||
|
|
||||||
|
int shell_readc() {
|
||||||
|
char c = 0;
|
||||||
|
posix_read(uart0_handler_pid, &c, 1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shell_putchar(int c) {
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shell commands */
|
||||||
|
shell_t shell;
|
||||||
|
const shell_command_t sc[] = {
|
||||||
|
{"sender", ohm_send},
|
||||||
|
{"sink", ohm_sink},
|
||||||
|
{"int", set_interval},
|
||||||
|
{"prob", set_probability},
|
||||||
|
{"cc1100", print_cc1100_info},
|
||||||
|
{"addr", _cc110x_get_set_address_handler},
|
||||||
|
{"date", _date_handler},
|
||||||
|
{"stats", stat_handler},
|
||||||
|
{NULL, NULL}};
|
||||||
|
|
||||||
|
static void shell_runner(void) {
|
||||||
|
posix_open(uart0_handler_pid, 0);
|
||||||
|
shell_init(&shell, shell_readc, shell_putchar);
|
||||||
|
shell.command_list = sc;
|
||||||
|
shell_run(&shell);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ohm_send(char* unused) {
|
||||||
|
if (data_src) {
|
||||||
|
data_src = 0;
|
||||||
|
puts("Disabling data source mode.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_src = 1;
|
||||||
|
puts("Enabling data source mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ohm_sink(char* unused) {
|
||||||
|
if (data_sink) {
|
||||||
|
data_sink = 0;
|
||||||
|
puts("Disabling data sink mode.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_sink = 1;
|
||||||
|
puts("Enabling data sink mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_interval(char* interval) {
|
||||||
|
uint16_t a;
|
||||||
|
|
||||||
|
a = atoi(interval+4);
|
||||||
|
if (strlen(interval) > 4) {
|
||||||
|
printf("[WEAtHeR] Set interval to %u\n ", a);
|
||||||
|
sending_interval = a * SECOND;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[WEAtHeR] Current interval is %lu\n ", (sending_interval / SECOND));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_probability(char* prob) {
|
||||||
|
uint16_t a;
|
||||||
|
|
||||||
|
a = atoi(prob+4);
|
||||||
|
if (strlen(prob) > 4) {
|
||||||
|
printf("[WEAtHeR] Set probability to %hu\n ", a);
|
||||||
|
gossip_probability = a;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[WEAtHeR] Current probability is %hu\n ", gossip_probability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_cc1100_info(char* unused) {
|
||||||
|
puts("==================================================");
|
||||||
|
cc1100_print_statistic();
|
||||||
|
puts("--------------------------------------------------");
|
||||||
|
cc1100_print_config();
|
||||||
|
puts("==================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stat_handler(char* unused) {
|
||||||
|
extern uint16_t pkts_received;
|
||||||
|
extern uint16_t pkts_success;
|
||||||
|
extern uint16_t pkts_dup;
|
||||||
|
extern uint16_t pkts_dropped;
|
||||||
|
printf(" ::::::::::::::::::::::::::: \n");
|
||||||
|
printf(" :: Packets received: %u ::\n", pkts_received);
|
||||||
|
printf(" :: Packets processed: %u ::\n", pkts_processed);
|
||||||
|
printf(" :: Packets success: %u ::\n", pkts_success);
|
||||||
|
printf(" :: Packets dup: %u ::\n", pkts_dup);
|
||||||
|
printf(" :: Packets dropped: %u ::\n", pkts_dropped);
|
||||||
|
printf(" ::::::::::::::::::::::::::: \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void otto(uint32_t timestamp, uint32_t value) {
|
||||||
|
uint16_t i, j;
|
||||||
|
|
||||||
|
if (measure_pause) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// printf("tbp: %p\n", thread_buf_ptr);
|
||||||
|
thread_buf_ptr->timestamp = timestamp;
|
||||||
|
thread_buf_ptr->value = value;
|
||||||
|
if (((thread_buf_ptr++) - thread_buf) > CRIT_THREAD_BUF_SIZE) {
|
||||||
|
/* output */
|
||||||
|
otto_says = 1;
|
||||||
|
}
|
||||||
|
if (otto_says) {
|
||||||
|
measure_pause = 1;
|
||||||
|
/*
|
||||||
|
printf("Otto says: %lX\n", otto_says);
|
||||||
|
|
||||||
|
printf("Coulomb buffer is filled with %lu entries\n", (cb_buf_ptr - cb_buf));
|
||||||
|
printf("Thread buffer is filled with %lu entries\n", (thread_buf_ptr - thread_buf));
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < (cb_buf_ptr - cb_buf); i++) {
|
||||||
|
for (; j < (thread_buf_ptr - thread_buf); j++) {
|
||||||
|
if (thread_buf[j].timestamp > cb_buf[i]) break;
|
||||||
|
printf("T;%04lX;%04lX\n", thread_buf[j].timestamp, thread_buf[j].value);
|
||||||
|
}
|
||||||
|
printf("C;%04lX\n", cb_buf[i]);
|
||||||
|
}
|
||||||
|
for (; j < (thread_buf_ptr - thread_buf); j++) {
|
||||||
|
printf("T;%04lX;%04lX\n", thread_buf[j].timestamp, thread_buf[j].value);
|
||||||
|
}
|
||||||
|
cb_buf_ptr = cb_buf;
|
||||||
|
thread_buf_ptr = thread_buf;
|
||||||
|
|
||||||
|
printf("Function buffer is filled with %lu entries\n", (func_buf_ptr - func_buf));
|
||||||
|
*/
|
||||||
|
/* for (i = 0; i < (func_buf_ptr - func_buf); i++) {
|
||||||
|
printf("F;%04lX;%04lX\n", func_buf[i].timestamp, func_buf[i].value);
|
||||||
|
}*/
|
||||||
|
func_buf_ptr = func_buf;
|
||||||
|
|
||||||
|
otto_says = 0;
|
||||||
|
measure_pause = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("tbp: %p\n", thread_buf_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* packet handling */
|
||||||
|
static void handle_packet(void* msg, int msg_size, packet_info_t* packet_info) {
|
||||||
|
pkts_processed++;
|
||||||
|
ohm_packet_header_t *header = (ohm_packet_header_t*) msg;
|
||||||
|
|
||||||
|
printf("\n\t Pkt received from phy: %u (%u bytes)\n"
|
||||||
|
"\t -> SEQ: %u | TYPE: %u | SRC: %hu \n\n",
|
||||||
|
packet_info->phy_src,
|
||||||
|
msg_size,
|
||||||
|
header->seq_nr,
|
||||||
|
header->type,
|
||||||
|
header->src
|
||||||
|
);
|
||||||
|
/* packet origins at current node, just ignore it */
|
||||||
|
if (header->src == cc1100_get_address()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* while not acting as sink and packet contains data, route the packet */
|
||||||
|
if (!data_sink) {
|
||||||
|
if (header->type == OHM_DATA) {
|
||||||
|
ohm_data_pkt_t* odp = (ohm_data_pkt_t*) msg;
|
||||||
|
DEBUG("$0;%hu;%hu;%lu;%u;%.2f;%.2f;%.2f\n",
|
||||||
|
header->src,
|
||||||
|
0,
|
||||||
|
odp->timestamp,
|
||||||
|
0,
|
||||||
|
odp->temperature,
|
||||||
|
odp->relhum,
|
||||||
|
odp->relhum_temp,
|
||||||
|
odp->energy
|
||||||
|
)
|
||||||
|
DEBUG("Not for me, routing, baby!\n");
|
||||||
|
route_packet(msg, msg_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if current node acts as sink, handle packet */
|
||||||
|
switch (header->type) {
|
||||||
|
case OHM_HELLO: {
|
||||||
|
if (msg_size < sizeof(ohm_hello_pkt_t)) {
|
||||||
|
puts("Bad hello packet received.");
|
||||||
|
} else {
|
||||||
|
puts("Hello packet received - no handler implemented");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OHM_CHAT: {
|
||||||
|
puts("\n*================================================================================*");
|
||||||
|
printf("\tCHAT MESSAGE from %hu: %s\n\n", packet_info->phy_src, ((ohm_chat_pkt_t*) msg)->mesg);
|
||||||
|
puts("*================================================================================*\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OHM_DATA: {
|
||||||
|
ohm_data_pkt_t* odp = (ohm_data_pkt_t*) msg;
|
||||||
|
uint8_t i;
|
||||||
|
time_t local_time = rtc_time(NULL);
|
||||||
|
if (update_sources(header->src, odp->timestamp)) {
|
||||||
|
printf("$1;%hu;%u;%lu;%lu;%.2f;%.2f;%.2f;%.2f;",
|
||||||
|
header->src,
|
||||||
|
cc1100_get_address(),
|
||||||
|
odp->timestamp,
|
||||||
|
local_time,
|
||||||
|
odp->temperature,
|
||||||
|
odp->relhum,
|
||||||
|
odp->relhum_temp,
|
||||||
|
odp->energy);
|
||||||
|
for (i = 0; i < odp->hop_counter; i++) {
|
||||||
|
printf("%03u-", odp->hops[i]);
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
printf("Unknown packet type \"%i\" received.\n", header->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void protocol_handler_thread(void) {
|
||||||
|
puts("Start protocol handler thread");
|
||||||
|
packet_t packet;
|
||||||
|
int n = -1;
|
||||||
|
while (1) {
|
||||||
|
n = cib_get(&cib);
|
||||||
|
if (n >= 0) {
|
||||||
|
packet = packet_buffer[n];
|
||||||
|
handle_packet(packet.payload, packet.msg_size, &(packet.packet_info));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thread_sleep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
FIO1DIR |= BIT0;
|
||||||
|
FIO1DIR |= BIT1;
|
||||||
|
FIO1DIR |= BIT4;
|
||||||
|
|
||||||
|
ohm_data_pkt_t odp;
|
||||||
|
sht11_val_t sht11_val;
|
||||||
|
|
||||||
|
/* initialize variables */
|
||||||
|
uint8_t success = 0;
|
||||||
|
int sending_state = 0;
|
||||||
|
gossip_probability = FLOODING_PROB;
|
||||||
|
cib_init(&cib, PACKET_BUFFER_SIZE);
|
||||||
|
|
||||||
|
cb_buf_ptr = cb_buf;
|
||||||
|
thread_buf_ptr = thread_buf;
|
||||||
|
func_buf_ptr = func_buf;
|
||||||
|
|
||||||
|
/* register thread switch callback */
|
||||||
|
void sched_register_cb(void (*callback)(uint32_t, uint32_t));
|
||||||
|
sched_register_cb(otto);
|
||||||
|
|
||||||
|
/* fill some fields of the packet */
|
||||||
|
odp.header.seq_nr = 0;
|
||||||
|
odp.header.type = OHM_DATA;
|
||||||
|
odp.hop_counter = 1;
|
||||||
|
|
||||||
|
/* set initial channel */
|
||||||
|
cc1100_set_channel(15);
|
||||||
|
|
||||||
|
/* boot screen */
|
||||||
|
puts("");
|
||||||
|
puts("WEAtHeR: Wireless Energy-Aware mulTi-Hop sEnsor Reading. V.4.4");
|
||||||
|
puts("");
|
||||||
|
printf("Sending interval: %lu\n", sending_interval / SECOND);
|
||||||
|
extern int cc1100_phy_calc_wor_settings(uint16_t m);
|
||||||
|
printf("Burst count: %i\n", cc1100_phy_calc_wor_settings(T_RX_INTERVAL));
|
||||||
|
|
||||||
|
printf(" Coulomb buffer size: %u\n", CRIT_TICK_BUF_SIZE);
|
||||||
|
printf(" Thread buffer size: %u\n", CRIT_THREAD_BUF_SIZE);
|
||||||
|
printf(" Function buffer size: %u\n", CRIT_FUNC_BUF_SIZE);
|
||||||
|
|
||||||
|
/* start shell */
|
||||||
|
thread_create(SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell");
|
||||||
|
|
||||||
|
measure_pause = 0;
|
||||||
|
|
||||||
|
/* initialize message gateway */
|
||||||
|
init_protocol_msg_gateway();
|
||||||
|
/* create thread for radio packet handling */
|
||||||
|
int pid = thread_create(PH_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, protocol_handler_thread, "protocol_handler");
|
||||||
|
set_protocol_handler_thread(pid);
|
||||||
|
|
||||||
|
/* start coulomb counter and RTC */
|
||||||
|
ltc4150_start();
|
||||||
|
rtc_enable();
|
||||||
|
|
||||||
|
/* loop forever */
|
||||||
|
while (1) {
|
||||||
|
DEBUG("Measurement in progress...\n");
|
||||||
|
#ifndef ENABLE_DEBUG
|
||||||
|
P14_TOGGLE;
|
||||||
|
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
|
||||||
|
P14_TOGGLE;
|
||||||
|
#else
|
||||||
|
success = 1;
|
||||||
|
sht11_val.temperature = 1;
|
||||||
|
sht11_val.relhum = 2;
|
||||||
|
sht11_val.relhum_temp = 3;
|
||||||
|
#endif
|
||||||
|
DEBUG("...done.\n");
|
||||||
|
|
||||||
|
odp.timestamp = rtc_time(NULL);
|
||||||
|
DEBUG("Timestamp filled\n");
|
||||||
|
|
||||||
|
if (data_src) {
|
||||||
|
odp.header.src = cc1100_get_address();
|
||||||
|
DEBUG("Src filled\n");
|
||||||
|
odp.energy = ltc4150_get_total_mAh();
|
||||||
|
DEBUG("Energy filled\n");
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
printf("error;error;error\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
odp.temperature = sht11_val.temperature;
|
||||||
|
odp.relhum = sht11_val.relhum;
|
||||||
|
odp.relhum_temp = sht11_val.relhum_temp;
|
||||||
|
odp.hops[0] = cc1100_get_address();
|
||||||
|
DEBUG("Ready for sending\n");
|
||||||
|
/* send packet with one entry in hop list */
|
||||||
|
P11_TOGGLE;
|
||||||
|
sending_state = cc1100_send_csmaca(0, OHM_PROTOCOL_NR, 0, (char*)&odp, (EMPTY_WDP_SIZE + 1));
|
||||||
|
P11_TOGGLE;
|
||||||
|
if (sending_state > 0) {
|
||||||
|
DEBUG("Sending %lu bytes.\n", (EMPTY_WDP_SIZE + 1));
|
||||||
|
odp.header.seq_nr++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Error on sending packet with code %i!\n", sending_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//LED_RED_TOGGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
printf("error;error;error\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef ENABLE_DEBUG_CC1100
|
||||||
|
puts("==================================================");
|
||||||
|
cc1100_print_statistic();
|
||||||
|
puts("--------------------------------------------------");
|
||||||
|
cc1100_print_config();
|
||||||
|
puts("==================================================");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
thread_print_all();
|
||||||
|
printf("$0;%hu;%hu;%lu;%u;%.2f;%.2f;%.2f;%.2f\n",
|
||||||
|
cc1100_get_address(),
|
||||||
|
0,
|
||||||
|
odp.timestamp,
|
||||||
|
0,
|
||||||
|
sht11_val.temperature,
|
||||||
|
sht11_val.relhum,
|
||||||
|
sht11_val.relhum_temp,
|
||||||
|
ltc4150_get_total_mAh()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
hwtimer_wait(sending_interval);
|
||||||
|
}
|
||||||
|
puts("Something went wrong.");
|
||||||
|
}
|
||||||
30
projects/OHM/ohm.h
Normal file
30
projects/OHM/ohm.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef OHM_H
|
||||||
|
#define OHM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX_TICK_BUF_SIZE (256)
|
||||||
|
#define CRIT_TICK_BUF_SIZE (MAX_TICK_BUF_SIZE * 80/100)
|
||||||
|
|
||||||
|
#define MAX_THREAD_BUF_SIZE (1024)
|
||||||
|
#define CRIT_THREAD_BUF_SIZE (MAX_THREAD_BUF_SIZE * 50/100)
|
||||||
|
|
||||||
|
#define MAX_FUNC_BUF_SIZE (4048)
|
||||||
|
#define CRIT_FUNC_BUF_SIZE (MAX_FUNC_BUF_SIZE * 50/100)
|
||||||
|
|
||||||
|
#define OHM_LTC_TICK (0xFFFF)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OHM_DT_LTC,
|
||||||
|
OHM_DT_THREAD,
|
||||||
|
OHM_DT_FUNCTION
|
||||||
|
} ohm_datatype_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t timestamp;
|
||||||
|
uint32_t value;
|
||||||
|
} ohm_measurement_t;
|
||||||
|
|
||||||
|
void otto(uint32_t timestamp, uint32_t value);
|
||||||
|
|
||||||
|
#endif /* OHM_H */
|
||||||
43
projects/OHM/ohm_cc1100.c
Normal file
43
projects/OHM/ohm_cc1100.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cc1100-interface.h>
|
||||||
|
|
||||||
|
#ifdef MODULE_CC110X
|
||||||
|
|
||||||
|
void _cc110x_get_set_address_handler(char *addr) {
|
||||||
|
int16_t a;
|
||||||
|
|
||||||
|
a = atoi(addr+5);
|
||||||
|
if (strlen(addr) > 5) {
|
||||||
|
printf("[cc110x] Setting address %i ... ", a);
|
||||||
|
cc1100_set_address((radio_address_t)a);
|
||||||
|
if (cc1100_get_address() == (radio_address_t)a) {
|
||||||
|
puts("[OK]");
|
||||||
|
} else {
|
||||||
|
puts("Error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[cc1100] Got address: %i\n", cc1100_get_address());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cc110x_get_set_channel_handler(char *addr) {
|
||||||
|
int16_t a;
|
||||||
|
|
||||||
|
a = atoi(addr+5);
|
||||||
|
if (strlen(addr) > 5) {
|
||||||
|
printf("[cc110x] Setting channel %i...", a);
|
||||||
|
cc1100_set_channel(a);
|
||||||
|
if (cc1100_get_channel() == a) {
|
||||||
|
puts("OK");
|
||||||
|
} else {
|
||||||
|
puts("Error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[cc1100] Got address: %i\n", cc1100_get_channel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
117
projects/OHM/ohm_ltc4150.c
Normal file
117
projects/OHM/ohm_ltc4150.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||||
|
|
||||||
|
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||||
|
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
This file is part of FeuerWare.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program. If not, see http://www.gnu.org/licenses/ .
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
For further information and questions please use the web site
|
||||||
|
http://scatterweb.mi.fu-berlin.de
|
||||||
|
and the mailinglist (subscription via web site)
|
||||||
|
scatterweb@lists.spline.inf.fu-berlin.de
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup ltc4150
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief LTC4150 Coulomb Counter
|
||||||
|
*
|
||||||
|
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||||
|
* @author Heiko Will
|
||||||
|
* @author Kaspar Schleiser <kaspar.schleiser@fu-berlin.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hwtimer.h>
|
||||||
|
#include <mutex.h>
|
||||||
|
#include "ltc4150_arch.h"
|
||||||
|
#include "board.h"
|
||||||
|
#include "ohm.h"
|
||||||
|
|
||||||
|
static volatile unsigned long int_count;
|
||||||
|
static unsigned int last_int_time;
|
||||||
|
static unsigned int last_int_duration;
|
||||||
|
static unsigned int start_time;
|
||||||
|
|
||||||
|
static double int_to_coulomb(int ints) {
|
||||||
|
return ((double)ints) / (_GFH * _R_SENSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double coulomb_to_mA(double coulomb){
|
||||||
|
return (coulomb * 1000) / 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ltc4150_get_last_int_duration_us() {
|
||||||
|
return HWTIMER_TICKS_TO_US(last_int_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
double ltc4150_get_current_mA() {
|
||||||
|
return 1000000000/(ltc4150_get_last_int_duration_us()*(_GFH * _R_SENSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
double ltc4150_get_total_mAh() {
|
||||||
|
return coulomb_to_mA(int_to_coulomb(int_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
double ltc4150_get_avg_mA() {
|
||||||
|
return (int_to_coulomb(int_count)*1000000000)/HWTIMER_TICKS_TO_US(last_int_time - start_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ltc4150_get_intcount() {
|
||||||
|
return int_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc4150_init() {
|
||||||
|
ltc4150_arch_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc4150_start() {
|
||||||
|
ltc4150_disable_int();
|
||||||
|
int_count = 0;
|
||||||
|
uint32_t now = hwtimer_now();
|
||||||
|
ltc4150_sync_blocking();
|
||||||
|
start_time = now;
|
||||||
|
last_int_time = now;
|
||||||
|
ltc4150_enable_int();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc4150_stop() {
|
||||||
|
ltc4150_disable_int();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltc4150_interrupt()
|
||||||
|
{
|
||||||
|
extern uint32_t *cb_buf_ptr;
|
||||||
|
uint32_t now = hwtimer_now();
|
||||||
|
|
||||||
|
if (now >= last_int_time) {
|
||||||
|
last_int_duration = now - last_int_time;
|
||||||
|
} else {
|
||||||
|
last_int_duration = (0-1) - last_int_time + now + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_int_time = now;
|
||||||
|
int_count++;
|
||||||
|
|
||||||
|
*cb_buf_ptr = hwtimer_now();
|
||||||
|
cb_buf_ptr++;
|
||||||
|
// LED_GREEN_TOGGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
||||||
44
projects/OHM/ohm_protocol.h
Normal file
44
projects/OHM/ohm_protocol.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef OHM_PROTOCOL_H_
|
||||||
|
#define OHM_PROTOCOL_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <radio/radio.h>
|
||||||
|
|
||||||
|
#define OHM_PROTOCOL_NR 6
|
||||||
|
#define MAX_HOP_LIST (11)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OHM_HELLO,
|
||||||
|
OHM_CHAT,
|
||||||
|
OHM_DATA
|
||||||
|
} packet_types;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t seq_nr;
|
||||||
|
uint8_t src;
|
||||||
|
uint8_t type;
|
||||||
|
} ohm_packet_header_t;
|
||||||
|
|
||||||
|
typedef struct __attribute__ ((packed)) {
|
||||||
|
ohm_packet_header_t header;
|
||||||
|
} ohm_hello_pkt_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ohm_packet_header_t header;
|
||||||
|
uint8_t len;
|
||||||
|
char mesg[40];
|
||||||
|
} ohm_chat_pkt_t;
|
||||||
|
|
||||||
|
typedef struct __attribute__ ((packed)) {
|
||||||
|
ohm_packet_header_t header;
|
||||||
|
time_t timestamp;
|
||||||
|
double temperature;
|
||||||
|
double relhum;
|
||||||
|
double relhum_temp;
|
||||||
|
double energy;
|
||||||
|
uint8_t hop_counter;
|
||||||
|
uint8_t hops[MAX_HOP_LIST];
|
||||||
|
} ohm_data_pkt_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
86
projects/OHM/ohm_routing.c
Normal file
86
projects/OHM/ohm_routing.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <cc1100.h>
|
||||||
|
#include <hwtimer.h>
|
||||||
|
|
||||||
|
#include "ohm_protocol.h"
|
||||||
|
#include "ohm_routing.h"
|
||||||
|
|
||||||
|
//#define ENABLE_DEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
uint8_t gossip_probability;
|
||||||
|
|
||||||
|
uint16_t pkts_dup = 0;
|
||||||
|
uint16_t pkts_success = 0;
|
||||||
|
uint16_t pkts_dropped = 0;
|
||||||
|
|
||||||
|
static source_timestamp_t sources[MAX_SOURCES];
|
||||||
|
|
||||||
|
uint8_t update_sources(uint8_t id, time_t timestamp) {
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
DEBUG("updating sources list\n");
|
||||||
|
for (i = 0; i < MAX_SOURCES; i++) {
|
||||||
|
/* source id found */
|
||||||
|
if (sources[i].id == id) {
|
||||||
|
DEBUG("source already known, comparing timestamps: %04lX : %04lX\n", sources[i].timestamp, timestamp);
|
||||||
|
/* more current timestamp received, updating */
|
||||||
|
if (sources[i].timestamp < timestamp) {
|
||||||
|
sources[i].timestamp = timestamp;
|
||||||
|
pkts_success++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* timestamp too old, discard this packet */
|
||||||
|
else {
|
||||||
|
pkts_dup++;
|
||||||
|
DEBUG("Timestamp too old, discarding");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* source id not yet stored creating new entry */
|
||||||
|
else if (!sources[i].id) {
|
||||||
|
puts("got to know a new source");
|
||||||
|
sources[i].id = id;
|
||||||
|
sources[i].timestamp = timestamp;
|
||||||
|
pkts_success++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pkts_dropped++;
|
||||||
|
puts("No more sources could be stored!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void route_packet(void* msg, int msg_size) {
|
||||||
|
ohm_packet_header_t *header = (ohm_packet_header_t*) msg;
|
||||||
|
ohm_data_pkt_t* wdp = NULL;
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
if (header->type == OHM_DATA) {
|
||||||
|
wdp = (ohm_data_pkt_t*) msg;
|
||||||
|
if (!update_sources(wdp->header.src, wdp->timestamp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((100.0 * rand()/(double) RAND_MAX) <= gossip_probability) {
|
||||||
|
DEBUG("Broadcasting packet...");
|
||||||
|
/* if broadcasting ohm data, append current hop */
|
||||||
|
if (wdp != NULL) {
|
||||||
|
if (wdp->hop_counter < MAX_HOP_LIST) {
|
||||||
|
wdp->hops[wdp->hop_counter] = cc1100_get_address();
|
||||||
|
wdp->hop_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = cc1100_send_csmaca(0, OHM_PROTOCOL_NR, 0, (char*)msg, msg_size);
|
||||||
|
if (state > 0) {
|
||||||
|
DEBUG("successful!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("failed with code %i!\n", state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
18
projects/OHM/ohm_routing.h
Normal file
18
projects/OHM/ohm_routing.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef WEATHER_ROUTING_H
|
||||||
|
#define WEATHER_ROUTING_H
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define FLOODING_PROB (100)
|
||||||
|
#define MAX_SOURCES (20)
|
||||||
|
#define MAX_INTERVAL (5 * 60)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t id;
|
||||||
|
time_t timestamp;
|
||||||
|
} source_timestamp_t;
|
||||||
|
|
||||||
|
void route_packet(void* msg, int msg_size);
|
||||||
|
uint8_t update_sources(uint8_t id, time_t timestamp);
|
||||||
|
|
||||||
|
#endif /* WEATHER_ROUTING_H */
|
||||||
42
projects/OHM/ohm_rtc.c
Normal file
42
projects/OHM/ohm_rtc.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef MODULE_RTC
|
||||||
|
#include <lpc2387-rtc.h>
|
||||||
|
|
||||||
|
|
||||||
|
void _gettime_handler(void) {
|
||||||
|
struct tm now;
|
||||||
|
rtc_get_localtime(&now);
|
||||||
|
|
||||||
|
printf("%s", asctime(&now));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _settime_handler(char* c) {
|
||||||
|
time_t now;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sscanf(c, "date %lu", &now);
|
||||||
|
|
||||||
|
if (res < 1) {
|
||||||
|
printf("Usage: date <UNIX timestamp>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_set(now);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _date_handler(char* c) {
|
||||||
|
if (strlen(c) == 4) {
|
||||||
|
_gettime_handler();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_settime_handler(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
29
projects/OHM/profiling.c
Normal file
29
projects/OHM/profiling.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "cpu.h"
|
||||||
|
#include "ohm.h"
|
||||||
|
|
||||||
|
#define TIMER_REG (T0TC)
|
||||||
|
#define P10_TOGGLE (FIO1PIN ^= BIT0)
|
||||||
|
|
||||||
|
void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter (void *func, void *caller) {
|
||||||
|
extern ohm_measurement_t *func_buf_ptr;
|
||||||
|
extern ohm_measurement_t func_buf[];
|
||||||
|
|
||||||
|
extern uint32_t otto_says;
|
||||||
|
extern uint8_t measure_pause;
|
||||||
|
|
||||||
|
P10_TOGGLE;
|
||||||
|
if (measure_pause) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
func_buf_ptr->timestamp = TIMER_REG;
|
||||||
|
func_buf_ptr->value = (uint32_t) func;
|
||||||
|
|
||||||
|
if ((++func_buf_ptr - func_buf) > ((uint32_t) CRIT_FUNC_BUF_SIZE)) {
|
||||||
|
/* output */
|
||||||
|
//otto_says = (func_buf_ptr - func_buf);
|
||||||
|
otto_says = (uint32_t) func_buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit (void *func, void *caller) {
|
||||||
|
}
|
||||||
78
projects/OHM/protocol_msg_gateway.c
Normal file
78
projects/OHM/protocol_msg_gateway.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <radio/radio.h>
|
||||||
|
#include <radio/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <msg.h>
|
||||||
|
#include <cc1100.h>
|
||||||
|
#include <cib.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "protocol_msg_gateway.h"
|
||||||
|
#include "ohm_protocol.h"
|
||||||
|
|
||||||
|
#define NUM_PROTOCOL_HANDLER_PIDS 8
|
||||||
|
|
||||||
|
static uint16_t protocol_handler_pid;
|
||||||
|
|
||||||
|
uint16_t pkts_received = 0;
|
||||||
|
|
||||||
|
packet_t packet_buffer[PACKET_BUFFER_SIZE];
|
||||||
|
|
||||||
|
static void protocol_msg_gateway(void* payload, int msg_size, packet_info_t* packet_info) {
|
||||||
|
int n = -1;
|
||||||
|
extern cib_t cib;
|
||||||
|
|
||||||
|
pkts_received++;
|
||||||
|
if (!cc1100_get_address()) {
|
||||||
|
puts("No address configured, not processing incoming packet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protocol_handler_pid <= 0) {
|
||||||
|
puts("protocol_handler(): received packet without protocol handler. msg dropped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int mypos = packet_buffer_next++;
|
||||||
|
if (packet_buffer_next == PACKET_BUFFER_SIZE) packet_buffer_next = 0;
|
||||||
|
*/
|
||||||
|
n = cib_put(&cib);
|
||||||
|
|
||||||
|
if (n != -1) {
|
||||||
|
packet_t *p = &(packet_buffer[n]);
|
||||||
|
p->packet_info = *packet_info;
|
||||||
|
p->msg_size = msg_size;
|
||||||
|
memcpy(p->payload, payload, msg_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("Buffer full!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
m.type = 0;
|
||||||
|
m.content.value = mypos;
|
||||||
|
int success = msg_send_int(&m, protocol_handler_pid);
|
||||||
|
if (! success) {
|
||||||
|
// should set timer to retry. Dropping pkt for now.
|
||||||
|
DEBUG("protocol_handler(): msg dropped.");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
thread_wakeup(protocol_handler_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_protocol_msg_gateway() {
|
||||||
|
puts("Init protocol msg gateway");
|
||||||
|
cc1100_set_packet_handler(OHM_PROTOCOL_NR, protocol_msg_gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
int set_protocol_handler_thread(int pid) {
|
||||||
|
protocol_handler_pid = pid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
projects/OHM/protocol_msg_gateway.h
Normal file
18
projects/OHM/protocol_msg_gateway.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef __PROTOCOL_MSG_GATEWAY_H
|
||||||
|
#define __PROTOCOL_MSG_GATEWAY_H
|
||||||
|
|
||||||
|
#define PACKET_BUFFER_SIZE 32
|
||||||
|
#define MAXIMUM_PAYLOAD_SIZE 64
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
packet_info_t packet_info;
|
||||||
|
unsigned int msg_size;
|
||||||
|
char payload[MAXIMUM_PAYLOAD_SIZE];
|
||||||
|
} packet_t;
|
||||||
|
|
||||||
|
void init_protocol_msg_gateway();
|
||||||
|
int set_protocol_handler_thread(int pid);
|
||||||
|
|
||||||
|
extern packet_t packet_buffer[PACKET_BUFFER_SIZE];
|
||||||
|
|
||||||
|
#endif /* __PROTOCOL_MSG_GATEWAY_H */
|
||||||
13
projects/OHM/tests/hello-world
Executable file
13
projects/OHM/tests/hello-world
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/expect
|
||||||
|
|
||||||
|
set timeout 5
|
||||||
|
|
||||||
|
spawn pseudoterm $env(PORT)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
"Hello World!" {}
|
||||||
|
timeout { exit 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
puts "\nTest successful!\n"
|
||||||
|
|
||||||
6
projects/WEAtHeR_stable/Jamfile
Normal file
6
projects/WEAtHeR_stable/Jamfile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
SubDir TOP projects WEAtHeR_stable ;
|
||||||
|
|
||||||
|
Module WEAtHeR_stable : main.c weather_routing.c protocol_msg_gateway.c
|
||||||
|
weather_cc1100.c weather_rtc.c : ltc4150 cc110x sht11 gpioint shell shell_commands posix_io uart0 auto_init rtc ps ;
|
||||||
|
|
||||||
|
UseModule WEAtHeR_stable ;
|
||||||
409
projects/WEAtHeR_stable/main.c
Normal file
409
projects/WEAtHeR_stable/main.c
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
/* stdlib includes */
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
|
#include <msg.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <hwtimer.h>
|
||||||
|
#include <cib.h>
|
||||||
|
#include <scheduler.h>
|
||||||
|
|
||||||
|
//#define ENABLE_DEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* sensors and actors */
|
||||||
|
#include <board.h>
|
||||||
|
#include <sht11.h>
|
||||||
|
#include <ltc4150.h>
|
||||||
|
|
||||||
|
/* shell */
|
||||||
|
#include <shell.h>
|
||||||
|
#include <board_uart0.h>
|
||||||
|
#include <posix_io.h>
|
||||||
|
|
||||||
|
/* transceiver */
|
||||||
|
#include <cc1100.h>
|
||||||
|
#include <cc1100-defaultSettings.h>
|
||||||
|
|
||||||
|
/* real time clock */
|
||||||
|
#include <lpc2387-rtc.h>
|
||||||
|
|
||||||
|
/* application header */
|
||||||
|
#include "weather_routing.h"
|
||||||
|
#include "weather_protocol.h"
|
||||||
|
#include "protocol_msg_gateway.h"
|
||||||
|
|
||||||
|
#define CC1100_RADIO_MODE CC1100_MODE_WOR
|
||||||
|
|
||||||
|
/* some local defines */
|
||||||
|
#define SECOND (1000 * 1000)
|
||||||
|
#define MINUTE (1 * SECOND)
|
||||||
|
|
||||||
|
/* size of weather data packet without hop list */
|
||||||
|
#define EMPTY_WDP_SIZE (sizeof(weather_data_pkt_t) - MAX_HOP_LIST)
|
||||||
|
|
||||||
|
/* default values */
|
||||||
|
#define DEFAULT_INTERVAL (30 * SECOND)
|
||||||
|
|
||||||
|
/* stack space for threads */
|
||||||
|
#define SHELL_STACK_SIZE (4048)
|
||||||
|
#define PH_STACK_SIZE (4048)
|
||||||
|
|
||||||
|
|
||||||
|
char shell_stack_buffer[SHELL_STACK_SIZE];
|
||||||
|
char ph_stack_buffer[PH_STACK_SIZE];
|
||||||
|
|
||||||
|
/* per default acting only as relay */
|
||||||
|
static uint8_t data_sink = 0;
|
||||||
|
static uint8_t data_src = 0;
|
||||||
|
|
||||||
|
cib_t cib;
|
||||||
|
uint16_t pkts_processed = 0;
|
||||||
|
|
||||||
|
static uint32_t sending_interval = DEFAULT_INTERVAL;
|
||||||
|
|
||||||
|
extern uint8_t gossip_probability;
|
||||||
|
extern void _cc110x_get_set_address_handler(char *addr);
|
||||||
|
extern void _cc110x_get_set_channel_handler(char *chan);
|
||||||
|
extern void _date_handler(char* c);
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
static void weather_send(char* unused);
|
||||||
|
static void weather_sink(char* unused);
|
||||||
|
static void set_interval(char* interval);
|
||||||
|
static void set_probability(char* prob);
|
||||||
|
static void print_cc1100_info(char* unused);
|
||||||
|
static void stat_handler(char* unused);
|
||||||
|
|
||||||
|
int shell_readc() {
|
||||||
|
char c = 0;
|
||||||
|
posix_read(uart0_handler_pid, &c, 1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shell_putchar(int c) {
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shell commands */
|
||||||
|
shell_t shell;
|
||||||
|
const shell_command_t sc[] = {
|
||||||
|
{"sender", weather_send},
|
||||||
|
{"sink", weather_sink},
|
||||||
|
{"int", set_interval},
|
||||||
|
{"prob", set_probability},
|
||||||
|
{"cc1100", print_cc1100_info},
|
||||||
|
{"addr", _cc110x_get_set_address_handler},
|
||||||
|
{"date", _date_handler},
|
||||||
|
{"stats", stat_handler},
|
||||||
|
{NULL, NULL}};
|
||||||
|
|
||||||
|
static void shell_runner(void) {
|
||||||
|
posix_open(uart0_handler_pid, 0);
|
||||||
|
shell_init(&shell, shell_readc, shell_putchar);
|
||||||
|
shell.command_list = sc;
|
||||||
|
shell_run(&shell);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void weather_send(char* unused) {
|
||||||
|
if (data_src) {
|
||||||
|
data_src = 0;
|
||||||
|
puts("Disabling data source mode.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_src = 1;
|
||||||
|
puts("Enabling data source mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void weather_sink(char* unused) {
|
||||||
|
if (data_sink) {
|
||||||
|
data_sink = 0;
|
||||||
|
puts("Disabling data sink mode.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_sink = 1;
|
||||||
|
puts("Enabling data sink mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_interval(char* interval) {
|
||||||
|
uint16_t a;
|
||||||
|
|
||||||
|
a = atoi(interval+4);
|
||||||
|
if (strlen(interval) > 4) {
|
||||||
|
printf("[WEAtHeR] Set interval to %u\n ", a);
|
||||||
|
sending_interval = a * SECOND;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[WEAtHeR] Current interval is %lu\n ", (sending_interval / SECOND));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_probability(char* prob) {
|
||||||
|
uint16_t a;
|
||||||
|
|
||||||
|
a = atoi(prob+4);
|
||||||
|
if (strlen(prob) > 4) {
|
||||||
|
printf("[WEAtHeR] Set probability to %hu\n ", a);
|
||||||
|
gossip_probability = a;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[WEAtHeR] Current probability is %hu\n ", gossip_probability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_cc1100_info(char* unused) {
|
||||||
|
puts("==================================================");
|
||||||
|
cc1100_print_statistic();
|
||||||
|
puts("--------------------------------------------------");
|
||||||
|
cc1100_print_config();
|
||||||
|
puts("==================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stat_handler(char* unused) {
|
||||||
|
extern uint16_t pkts_received;
|
||||||
|
extern uint16_t pkts_success;
|
||||||
|
extern uint16_t pkts_dup;
|
||||||
|
extern uint16_t pkts_dropped;
|
||||||
|
printf(" ::::::::::::::::::::::::::: \n");
|
||||||
|
printf(" :: Packets received: %u ::\n", pkts_received);
|
||||||
|
printf(" :: Packets processed: %u ::\n", pkts_processed);
|
||||||
|
printf(" :: Packets success: %u ::\n", pkts_success);
|
||||||
|
printf(" :: Packets dup: %u ::\n", pkts_dup);
|
||||||
|
printf(" :: Packets dropped: %u ::\n", pkts_dropped);
|
||||||
|
printf(" ::::::::::::::::::::::::::: \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* packet handling */
|
||||||
|
static void handle_packet(void* msg, int msg_size, packet_info_t* packet_info) {
|
||||||
|
pkts_processed++;
|
||||||
|
weather_packet_header_t *header = (weather_packet_header_t*) msg;
|
||||||
|
|
||||||
|
printf("\n\t Pkt received from phy: %u (%u bytes)\n"
|
||||||
|
"\t -> SEQ: %u | TYPE: %u | SRC: %hu \n\n",
|
||||||
|
packet_info->phy_src,
|
||||||
|
msg_size,
|
||||||
|
header->seq_nr,
|
||||||
|
header->type,
|
||||||
|
header->src
|
||||||
|
);
|
||||||
|
/* packet origins at current node, just ignore it */
|
||||||
|
if (header->src == cc1100_get_address()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* while not acting as sink and packet contains data, route the packet */
|
||||||
|
if (!data_sink) {
|
||||||
|
if (header->type == WEATHER_DATA) {
|
||||||
|
weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg;
|
||||||
|
DEBUG("$0;%hu;%hu;%lu;%u;%.2f;%.2f;%.2f;%.2f;%.2f\n",
|
||||||
|
header->src,
|
||||||
|
0,
|
||||||
|
wdp->timestamp,
|
||||||
|
0,
|
||||||
|
wdp->temperature,
|
||||||
|
wdp->relhum,
|
||||||
|
wdp->relhum_temp,
|
||||||
|
wdp->energy,
|
||||||
|
pidlist[0].energy,
|
||||||
|
pidlist[1].energy);
|
||||||
|
DEBUG("Not for me, routing, baby!\n");
|
||||||
|
route_packet(msg, msg_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if current node acts as sink, handle packet */
|
||||||
|
switch (header->type) {
|
||||||
|
case WEATHER_HELLO: {
|
||||||
|
if (msg_size < sizeof(weather_hello_pkt_t)) {
|
||||||
|
puts("Bad hello packet received.");
|
||||||
|
} else {
|
||||||
|
puts("Hello packet received - no handler implemented");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WEATHER_CHAT: {
|
||||||
|
puts("\n*================================================================================*");
|
||||||
|
printf("\tCHAT MESSAGE from %hu: %s\n\n", packet_info->phy_src, ((weather_chat_pkt_t*) msg)->mesg);
|
||||||
|
puts("*================================================================================*\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WEATHER_DATA: {
|
||||||
|
weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg;
|
||||||
|
uint8_t i;
|
||||||
|
time_t local_time = rtc_time(NULL);
|
||||||
|
if (update_sources(header->src, wdp->timestamp)) {
|
||||||
|
printf("$1;%hu;%u;%lu;%lu;%.2f;%.2f;%.2f;%.2f;",
|
||||||
|
header->src,
|
||||||
|
cc1100_get_address(),
|
||||||
|
wdp->timestamp,
|
||||||
|
local_time,
|
||||||
|
wdp->temperature,
|
||||||
|
wdp->relhum,
|
||||||
|
wdp->relhum_temp,
|
||||||
|
wdp->energy);
|
||||||
|
for (i = 0; i < wdp->hop_counter; i++) {
|
||||||
|
printf("%03u-", wdp->hops[i]);
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
printf("Unknown packet type \"%i\" received.\n", header->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* endless loop for packet handling
|
||||||
|
static void protocol_handler_thread(void) {
|
||||||
|
msg m;
|
||||||
|
puts("Protocol handler thread started.");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
msg_receive(&m);
|
||||||
|
|
||||||
|
packet_t packet;
|
||||||
|
int pos = m.content.value;
|
||||||
|
packet = packet_buffer[pos];
|
||||||
|
|
||||||
|
handle_packet(packet.payload, packet.msg_size, &(packet.packet_info));
|
||||||
|
DEBUG("Packet handler done\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void protocol_handler_thread(void) {
|
||||||
|
packet_t packet;
|
||||||
|
int n = -1;
|
||||||
|
while (1) {
|
||||||
|
n = cib_get(&cib);
|
||||||
|
if (n >= 0) {
|
||||||
|
packet = packet_buffer[n];
|
||||||
|
handle_packet(packet.payload, packet.msg_size, &(packet.packet_info));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thread_sleep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
weather_data_pkt_t wdp;
|
||||||
|
sht11_val_t sht11_val;
|
||||||
|
|
||||||
|
/* initialize variables */
|
||||||
|
uint8_t success = 0;
|
||||||
|
int sending_state = 0;
|
||||||
|
gossip_probability = FLOODING_PROB;
|
||||||
|
cib_init(&cib, PACKET_BUFFER_SIZE);
|
||||||
|
|
||||||
|
/* fill some fields of the packet */
|
||||||
|
wdp.header.seq_nr = 0;
|
||||||
|
wdp.header.type = WEATHER_DATA;
|
||||||
|
wdp.hop_counter = 1;
|
||||||
|
|
||||||
|
/* set initial channel */
|
||||||
|
cc1100_set_channel(15);
|
||||||
|
|
||||||
|
/* boot screen */
|
||||||
|
puts("");
|
||||||
|
puts("WEAtHeR: Wireless Energy-Aware mulTi-Hop sEnsor Reading. V.4.4");
|
||||||
|
puts("");
|
||||||
|
printf("Sending interval: %lu\n", sending_interval / SECOND);
|
||||||
|
extern int cc1100_phy_calc_wor_settings(uint16_t m);
|
||||||
|
printf("Burst count: %i\n", cc1100_phy_calc_wor_settings(T_RX_INTERVAL));
|
||||||
|
|
||||||
|
/* start shell */
|
||||||
|
thread_create(SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell");
|
||||||
|
|
||||||
|
/* initialize message gateway */
|
||||||
|
init_protocol_msg_gateway();
|
||||||
|
/* create thread for radio packet handling */
|
||||||
|
int pid = thread_create(PH_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, protocol_handler_thread, "protocol_handler");
|
||||||
|
set_protocol_handler_thread(pid);
|
||||||
|
|
||||||
|
/* start coulomb counter and RTC */
|
||||||
|
ltc4150_start();
|
||||||
|
rtc_enable();
|
||||||
|
|
||||||
|
/* loop forever */
|
||||||
|
while (1) {
|
||||||
|
DEBUG("Measurement in progress...\n");
|
||||||
|
#ifndef ENABLE_DEBUG
|
||||||
|
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
|
||||||
|
#else
|
||||||
|
success = 1;
|
||||||
|
sht11_val.temperature = 1;
|
||||||
|
sht11_val.relhum = 2;
|
||||||
|
sht11_val.relhum_temp = 3;
|
||||||
|
#endif
|
||||||
|
DEBUG("...done.\n");
|
||||||
|
|
||||||
|
wdp.timestamp = rtc_time(NULL);
|
||||||
|
DEBUG("Timestamp filled\n");
|
||||||
|
|
||||||
|
if (data_src) {
|
||||||
|
wdp.header.src = cc1100_get_address();
|
||||||
|
DEBUG("Src filled\n");
|
||||||
|
wdp.energy = ltc4150_get_total_mAh();
|
||||||
|
DEBUG("Energy filled\n");
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
printf("error;error;error\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wdp.temperature = sht11_val.temperature;
|
||||||
|
wdp.relhum = sht11_val.relhum;
|
||||||
|
wdp.relhum_temp = sht11_val.relhum_temp;
|
||||||
|
wdp.hops[0] = cc1100_get_address();
|
||||||
|
DEBUG("Ready for sending\n");
|
||||||
|
/* send packet with one entry in hop list */
|
||||||
|
sending_state = cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)&wdp, (EMPTY_WDP_SIZE + 1));
|
||||||
|
if (sending_state > 0) {
|
||||||
|
DEBUG("Sending %lu bytes.\n", (EMPTY_WDP_SIZE + 1));
|
||||||
|
wdp.header.seq_nr++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Error on sending packet with code %i!\n", sending_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LED_RED_TOGGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
printf("error;error;error\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef ENABLE_DEBUG_CC1100
|
||||||
|
puts("==================================================");
|
||||||
|
cc1100_print_statistic();
|
||||||
|
puts("--------------------------------------------------");
|
||||||
|
cc1100_print_config();
|
||||||
|
puts("==================================================");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//thread_print_all();
|
||||||
|
printf("$0;%hu;%hu;%lu;%u;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n",
|
||||||
|
cc1100_get_address(),
|
||||||
|
0,
|
||||||
|
wdp.timestamp,
|
||||||
|
0,
|
||||||
|
sht11_val.temperature,
|
||||||
|
sht11_val.relhum,
|
||||||
|
sht11_val.relhum_temp,
|
||||||
|
ltc4150_get_total_mAh(),
|
||||||
|
pidlist[0].energy,
|
||||||
|
pidlist[1].energy);
|
||||||
|
}
|
||||||
|
hwtimer_wait(sending_interval);
|
||||||
|
}
|
||||||
|
puts("Something went wrong.");
|
||||||
|
}
|
||||||
78
projects/WEAtHeR_stable/protocol_msg_gateway.c
Normal file
78
projects/WEAtHeR_stable/protocol_msg_gateway.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <radio/radio.h>
|
||||||
|
#include <radio/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <msg.h>
|
||||||
|
#include <cc1100.h>
|
||||||
|
#include <cib.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "protocol_msg_gateway.h"
|
||||||
|
#include "weather_protocol.h"
|
||||||
|
|
||||||
|
#define NUM_PROTOCOL_HANDLER_PIDS 8
|
||||||
|
|
||||||
|
static uint16_t protocol_handler_pid;
|
||||||
|
|
||||||
|
uint16_t pkts_received = 0;
|
||||||
|
|
||||||
|
packet_t packet_buffer[PACKET_BUFFER_SIZE];
|
||||||
|
|
||||||
|
static void protocol_msg_gateway(void* payload, int msg_size, packet_info_t* packet_info) {
|
||||||
|
int n = -1;
|
||||||
|
extern cib_t cib;
|
||||||
|
|
||||||
|
pkts_received++;
|
||||||
|
if (!cc1100_get_address()) {
|
||||||
|
puts("No address configured, not processing incoming packet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protocol_handler_pid <= 0) {
|
||||||
|
puts("protocol_handler(): received packet without protocol handler. msg dropped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int mypos = packet_buffer_next++;
|
||||||
|
if (packet_buffer_next == PACKET_BUFFER_SIZE) packet_buffer_next = 0;
|
||||||
|
*/
|
||||||
|
n = cib_put(&cib);
|
||||||
|
|
||||||
|
if (n != -1) {
|
||||||
|
packet_t *p = &(packet_buffer[n]);
|
||||||
|
p->packet_info = *packet_info;
|
||||||
|
p->msg_size = msg_size;
|
||||||
|
memcpy(p->payload, payload, msg_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("Buffer full!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
m.type = 0;
|
||||||
|
m.content.value = mypos;
|
||||||
|
int success = msg_send_int(&m, protocol_handler_pid);
|
||||||
|
if (! success) {
|
||||||
|
// should set timer to retry. Dropping pkt for now.
|
||||||
|
DEBUG("protocol_handler(): msg dropped.");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
thread_wakeup(protocol_handler_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_protocol_msg_gateway() {
|
||||||
|
puts("Init protocol msg gateway");
|
||||||
|
cc1100_set_packet_handler(WEATHER_PROTOCOL_NR, protocol_msg_gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
int set_protocol_handler_thread(int pid) {
|
||||||
|
protocol_handler_pid = pid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
projects/WEAtHeR_stable/protocol_msg_gateway.h
Normal file
18
projects/WEAtHeR_stable/protocol_msg_gateway.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef __PROTOCOL_MSG_GATEWAY_H
|
||||||
|
#define __PROTOCOL_MSG_GATEWAY_H
|
||||||
|
|
||||||
|
#define PACKET_BUFFER_SIZE 32
|
||||||
|
#define MAXIMUM_PAYLOAD_SIZE 64
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
packet_info_t packet_info;
|
||||||
|
unsigned int msg_size;
|
||||||
|
char payload[MAXIMUM_PAYLOAD_SIZE];
|
||||||
|
} packet_t;
|
||||||
|
|
||||||
|
void init_protocol_msg_gateway();
|
||||||
|
int set_protocol_handler_thread(int pid);
|
||||||
|
|
||||||
|
extern packet_t packet_buffer[PACKET_BUFFER_SIZE];
|
||||||
|
|
||||||
|
#endif /* __PROTOCOL_MSG_GATEWAY_H */
|
||||||
13
projects/WEAtHeR_stable/tests/hello-world
Executable file
13
projects/WEAtHeR_stable/tests/hello-world
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/expect
|
||||||
|
|
||||||
|
set timeout 5
|
||||||
|
|
||||||
|
spawn pseudoterm $env(PORT)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
"Hello World!" {}
|
||||||
|
timeout { exit 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
puts "\nTest successful!\n"
|
||||||
|
|
||||||
43
projects/WEAtHeR_stable/weather_cc1100.c
Normal file
43
projects/WEAtHeR_stable/weather_cc1100.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cc1100-interface.h>
|
||||||
|
|
||||||
|
#ifdef MODULE_CC110X
|
||||||
|
|
||||||
|
void _cc110x_get_set_address_handler(char *addr) {
|
||||||
|
int16_t a;
|
||||||
|
|
||||||
|
a = atoi(addr+5);
|
||||||
|
if (strlen(addr) > 5) {
|
||||||
|
printf("[cc110x] Setting address %i ... ", a);
|
||||||
|
cc1100_set_address((radio_address_t)a);
|
||||||
|
if (cc1100_get_address() == (radio_address_t)a) {
|
||||||
|
puts("[OK]");
|
||||||
|
} else {
|
||||||
|
puts("Error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[cc1100] Got address: %i\n", cc1100_get_address());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cc110x_get_set_channel_handler(char *addr) {
|
||||||
|
int16_t a;
|
||||||
|
|
||||||
|
a = atoi(addr+5);
|
||||||
|
if (strlen(addr) > 5) {
|
||||||
|
printf("[cc110x] Setting channel %i...", a);
|
||||||
|
cc1100_set_channel(a);
|
||||||
|
if (cc1100_get_channel() == a) {
|
||||||
|
puts("OK");
|
||||||
|
} else {
|
||||||
|
puts("Error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[cc1100] Got address: %i\n", cc1100_get_channel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
43
projects/WEAtHeR_stable/weather_protocol.h
Normal file
43
projects/WEAtHeR_stable/weather_protocol.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef WEATHER_PROTOCOL_H_
|
||||||
|
#define WEATHER_PROTOCOL_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <radio/radio.h>
|
||||||
|
|
||||||
|
#define WEATHER_PROTOCOL_NR 6
|
||||||
|
#define MAX_HOP_LIST (11)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WEATHER_HELLO,
|
||||||
|
WEATHER_CHAT,
|
||||||
|
WEATHER_DATA
|
||||||
|
} packet_types;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t seq_nr;
|
||||||
|
uint8_t src;
|
||||||
|
uint8_t type;
|
||||||
|
} weather_packet_header_t;
|
||||||
|
|
||||||
|
typedef struct __attribute__ ((packed)) {
|
||||||
|
weather_packet_header_t header;
|
||||||
|
} weather_hello_pkt_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
weather_packet_header_t header;
|
||||||
|
uint8_t len;
|
||||||
|
char mesg[40];
|
||||||
|
} weather_chat_pkt_t;
|
||||||
|
|
||||||
|
typedef struct __attribute__ ((packed)) {
|
||||||
|
weather_packet_header_t header;
|
||||||
|
time_t timestamp;
|
||||||
|
double temperature;
|
||||||
|
double relhum;
|
||||||
|
double relhum_temp;
|
||||||
|
double energy;
|
||||||
|
uint8_t hop_counter;
|
||||||
|
uint8_t hops[MAX_HOP_LIST];
|
||||||
|
} weather_data_pkt_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
86
projects/WEAtHeR_stable/weather_routing.c
Normal file
86
projects/WEAtHeR_stable/weather_routing.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <cc1100.h>
|
||||||
|
#include <hwtimer.h>
|
||||||
|
|
||||||
|
#include "weather_protocol.h"
|
||||||
|
#include "weather_routing.h"
|
||||||
|
|
||||||
|
//#define ENABLE_DEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
uint8_t gossip_probability;
|
||||||
|
|
||||||
|
uint16_t pkts_dup = 0;
|
||||||
|
uint16_t pkts_success = 0;
|
||||||
|
uint16_t pkts_dropped = 0;
|
||||||
|
|
||||||
|
static source_timestamp_t sources[MAX_SOURCES];
|
||||||
|
|
||||||
|
uint8_t update_sources(uint8_t id, time_t timestamp) {
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
DEBUG("updating sources list\n");
|
||||||
|
for (i = 0; i < MAX_SOURCES; i++) {
|
||||||
|
/* source id found */
|
||||||
|
if (sources[i].id == id) {
|
||||||
|
DEBUG("source already known, comparing timestamps: %04lX : %04lX\n", sources[i].timestamp, timestamp);
|
||||||
|
/* more current timestamp received, updating */
|
||||||
|
if (sources[i].timestamp < timestamp) {
|
||||||
|
sources[i].timestamp = timestamp;
|
||||||
|
pkts_success++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* timestamp too old, discard this packet */
|
||||||
|
else {
|
||||||
|
pkts_dup++;
|
||||||
|
DEBUG("Timestamp too old, discarding");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* source id not yet stored creating new entry */
|
||||||
|
else if (!sources[i].id) {
|
||||||
|
puts("got to know a new source");
|
||||||
|
sources[i].id = id;
|
||||||
|
sources[i].timestamp = timestamp;
|
||||||
|
pkts_success++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pkts_dropped++;
|
||||||
|
puts("No more sources could be stored!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void route_packet(void* msg, int msg_size) {
|
||||||
|
weather_packet_header_t *header = (weather_packet_header_t*) msg;
|
||||||
|
weather_data_pkt_t* wdp = NULL;
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
if (header->type == WEATHER_DATA) {
|
||||||
|
wdp = (weather_data_pkt_t*) msg;
|
||||||
|
if (!update_sources(wdp->header.src, wdp->timestamp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((100.0 * rand()/(double) RAND_MAX) <= gossip_probability) {
|
||||||
|
DEBUG("Broadcasting packet...");
|
||||||
|
/* if broadcasting weather data, append current hop */
|
||||||
|
if (wdp != NULL) {
|
||||||
|
if (wdp->hop_counter < MAX_HOP_LIST) {
|
||||||
|
wdp->hops[wdp->hop_counter] = cc1100_get_address();
|
||||||
|
wdp->hop_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)msg, msg_size);
|
||||||
|
if (state > 0) {
|
||||||
|
DEBUG("successful!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("failed with code %i!\n", state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
18
projects/WEAtHeR_stable/weather_routing.h
Normal file
18
projects/WEAtHeR_stable/weather_routing.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef WEATHER_ROUTING_H
|
||||||
|
#define WEATHER_ROUTING_H
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define FLOODING_PROB (100)
|
||||||
|
#define MAX_SOURCES (20)
|
||||||
|
#define MAX_INTERVAL (5 * 60)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t id;
|
||||||
|
time_t timestamp;
|
||||||
|
} source_timestamp_t;
|
||||||
|
|
||||||
|
void route_packet(void* msg, int msg_size);
|
||||||
|
uint8_t update_sources(uint8_t id, time_t timestamp);
|
||||||
|
|
||||||
|
#endif /* WEATHER_ROUTING_H */
|
||||||
42
projects/WEAtHeR_stable/weather_rtc.c
Normal file
42
projects/WEAtHeR_stable/weather_rtc.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef MODULE_RTC
|
||||||
|
#include <lpc2387-rtc.h>
|
||||||
|
|
||||||
|
|
||||||
|
void _gettime_handler(void) {
|
||||||
|
struct tm now;
|
||||||
|
rtc_get_localtime(&now);
|
||||||
|
|
||||||
|
printf("%s", asctime(&now));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _settime_handler(char* c) {
|
||||||
|
time_t now;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sscanf(c, "date %lu", &now);
|
||||||
|
|
||||||
|
if (res < 1) {
|
||||||
|
printf("Usage: date <UNIX timestamp>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_set(now);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _date_handler(char* c) {
|
||||||
|
if (strlen(c) == 4) {
|
||||||
|
_gettime_handler();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_settime_handler(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -43,7 +43,6 @@ extern void _get_blocksize(char* unused);
|
|||||||
extern void _get_sectorcount(char* unused);
|
extern void _get_sectorcount(char* unused);
|
||||||
extern void _read_sector(char* sector);
|
extern void _read_sector(char* sector);
|
||||||
extern void _read_bytes(char* bytes);
|
extern void _read_bytes(char* bytes);
|
||||||
extern void _write_bytes(char* bytes);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const shell_command_t _shell_command_list[] = {
|
const shell_command_t _shell_command_list[] = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user