📄 basestation.c
字号:
/*
* Copyright (c) 2008 Stanford University.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Stanford University nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
* UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Base station implementation using tosthreads
*
* @author Kevin Klues <klueska@cs.stanford.edu>
*/
//#include "stack.h"
#include "tosthread.h"
#include "tosthread_amradio.h"
#include "tosthread_amserial.h"
#include "tosthread_leds.h"
#include "tosthread_threadsync.h"
#define MSG_QUEUE_SIZE 3
//Parameters associated with each of the two base station paths
// radio -> serial
// serial -> radio
typedef struct bs_params {
tosthread_t receive_handle;
tosthread_t snoop_handle;
tosthread_t send_handle;
mutex_t mutex;
condvar_t condvar;
message_t shared_msgs[MSG_QUEUE_SIZE];
uint8_t shared_msg_queue_size;
uint8_t shared_msg_queue_index;
} bs_params_t;
//Declare parameters associated with radio RX thread
bs_params_t radioRx_params;
void radioReceive_thread(void* arg);
void radioSnoop_thread(void* arg);
void serialSend_thread(void* arg);
//Declare parameters associated with serial RX thread
bs_params_t serialRx_params;
void serialReceive_thread(void* arg);
void radioSend_thread(void* arg);
/********* Initialize base station parameters ********/
void bs_params_init(bs_params_t* p) {
mutex_init( &(p->mutex) );
condvar_init( &(p->condvar) );
p->shared_msg_queue_size = 0;
p->shared_msg_queue_index = 0;
}
/*********** Main function thread ************/
void tosthread_main(void* arg) {
bs_params_init( &radioRx_params );
bs_params_init( &serialRx_params );
amRadioStart();
amSerialStart();
tosthread_create(&(radioRx_params.receive_handle), radioReceive_thread, NULL, 200);
tosthread_create(&(radioRx_params.snoop_handle), radioSnoop_thread, NULL, 200);
tosthread_create(&(radioRx_params.send_handle), serialSend_thread, NULL, 200);
tosthread_create(&(serialRx_params.receive_handle), serialReceive_thread, NULL, 200);
tosthread_create(&(serialRx_params.send_handle), radioSend_thread, NULL, 200);
}
/******************** Enqueue and dequeue Messages ****************/
error_t enqueueMsg(bs_params_t* p, message_t* m) {
if(p->shared_msg_queue_size < MSG_QUEUE_SIZE) {
(p->shared_msgs)[p->shared_msg_queue_index] = *m;
(p->shared_msg_queue_index) = (p->shared_msg_queue_index + 1) % MSG_QUEUE_SIZE;
(p->shared_msg_queue_size)++;
return SUCCESS;
}
return FAIL;
}
message_t* dequeueMsg(bs_params_t* p) {
if(p->shared_msg_queue_size > 0) {
message_t* m;
m = &((p->shared_msgs)[(p->shared_msg_queue_index + (MSG_QUEUE_SIZE - p->shared_msg_queue_size)) % MSG_QUEUE_SIZE]);
(p->shared_msg_queue_size)--;
return m;
}
return NULL;
}
/******************** Send Serial vs. Radio Messages ****************/
error_t sendSerialMsg(message_t* msg) {
am_id_t id = amRadioGetType(msg);
am_addr_t source = amRadioGetSource(msg);
am_addr_t dest = amRadioGetDestination(msg);
uint8_t len = radioGetPayloadLength(msg);
serialClear(msg);
amSerialSetSource(msg, source);
return amSerialSend(dest, msg, len, id);
}
error_t sendRadioMsg(message_t* msg) {
am_id_t id = amSerialGetType(msg);
am_addr_t source = amSerialGetSource(msg);
am_addr_t dest = amSerialGetDestination(msg);
uint8_t len = serialGetPayloadLength(msg);
radioClear(msg);
amRadioSetSource(msg, source);
return amRadioSend(dest, msg, len, id);
}
/***********************************************************/
/** Generic implementations of send/receive functionality **/
/***********************************************************/
void bs_receive(error_t (*recv_func)(message_t*, uint32_t, am_id_t), bs_params_t* p) {
message_t m;
for(;;) {
if( (*(recv_func))(&m, 0, AM_RECEIVE_FROM_ANY) == SUCCESS ) {
led0Toggle();
mutex_lock( &(p->mutex) );
while( enqueueMsg(p, &m) == FAIL )
condvar_wait( &(p->condvar), &(p->mutex) );
mutex_unlock( &(p->mutex) );
condvar_signalAll( &(p->condvar) );
}
else led2Toggle();
}
}
void bs_send(void* send_func, bs_params_t* p) {
message_t m;
message_t* m_ptr;
for(;;) {
mutex_lock( &(p->mutex) );
while( (m_ptr = dequeueMsg(p)) == NULL )
condvar_wait( &(p->condvar), &(p->mutex) );
m = *m_ptr;
mutex_unlock( &(p->mutex) );
condvar_signalAll( &(p->condvar) );
if(send_func == amSerialSend)
sendSerialMsg(&m);
else
sendRadioMsg(&m);
led1Toggle();
}
}
/******************** Actual thread implementations ******************/
void radioReceive_thread(void* arg) {
bs_receive(amRadioReceive, &radioRx_params);
}
void radioSnoop_thread(void* arg) {
bs_receive(amRadioSnoop, &radioRx_params);
}
void serialSend_thread(void* arg) {
bs_send(amSerialSend, &radioRx_params);
}
void serialReceive_thread(void* arg) {
bs_receive(amSerialReceive, &serialRx_params);
}
void radioSend_thread(void* arg) {
bs_send(amRadioSend, &serialRx_params);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -