User Tools

Site Tools


lab3

Implementarea unui protocol de acces la mediu în rețele de senzori wireless

Comunicatia intre noduri

Compilati codul de mai jos si rulati pe doua noduri de adrese diferite: nodul cu adresa 1 este cel care trimite pachete iar al doilea (adresa diferita de 1) va receptiona pachetele trimise. Receptia va fi semnalata prin aprinderea led-ului de pe PB5 pe placa de extensie.

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
 
#define TRX_FRAME_BUFFER(index) (*(volatile uint8_t *)(0x180 + (index)))
 
volatile uint8_t rxPayload;
 
uint8_t nod1_address __attribute__((section(".data"))) = 2;
uint8_t node_address __attribute__((section(".data"))) = 2;
 
 
void initLeds()
{
	DDRB = 0xff;
	PORTB = 0x00;
}
 
void setState(uint8_t state)
{
	TRX_STATE = CMD_FORCE_TRX_OFF;
	TRX_STATE = state;
	while (state != TRX_STATUS_struct.trx_status); 
}
 
// send a short frame with a magic payload
void sendFrame()
{
	setState(CMD_PLL_ON);
 
	TRX_FRAME_BUFFER(0) = 3;	//length - minimum length is 3
	TRX_FRAME_BUFFER(1) = 0x00;	//magic payload
 
 
	// start transmission
	TRX_STATE = CMD_TX_START;
}
 
 
// upon receipt make a simple verification of correctness
ISR(TRX24_RX_END_vect)
{
	rxPayload = TRX_FRAME_BUFFER(0);
	if (rxPayload == 0)
		PORTB ^= (1<<PB5);
	setState(CMD_RX_ON);
}
 
void rfInit(void)
{
	setState(CMD_TRX_OFF);
 
	IRQ_STATUS = 0xff;
	IRQ_MASK_struct.rx_end_en = 1;
	sei();
 
	//PHY_CC_CCA_struct.channel = 0x0b;
	TRX_CTRL_2_struct.rx_safe_mode = 1;
}
 
int main()
{
	rfInit();
	initLeds();
 
	while(1)
	{
		if (node_address == 1)
		{
			sendFrame();
			PORTB ^= (1<<PB7);
			_delay_ms(3000);
		}
		else 
		{
			PORTB &= ~(_BV(PB5));
			setState(CMD_RX_ON);
			while (rxPayload != 0) asm("nop");
		}
	}
 
	return 0;
}

Nodurile vor urma un program comun de activitate wireless, vor transmite la început un broadcast pentru a obține informații de rutare apoi vor transmite un pachet de la un nod specificat către nodul desemnat base-station (nodul 0).

Ipoteză simplificatoare: Senzorii sunt sincronizați perfect. Senzorii vor trebui să alterneze între perioade active și perioade de conservare a energiei și vor putea face acest lucru simultan, fără alt ajutor din partea voastră.

Cerințe

- Veți implementa alternanța între perioada de activitate și perioada de conservare de energie

- Implementarea se va face cu ajutorul timer-ului pe 32 de biți SymbolCounter. Urmăriți tutorialul de pe wiki

- În perioada inactivă atât microcontroller-ul cât și transceiver-ul wireless vor intra în starea Sleep. Urmăriți tutorialul

- Veți implementa transmiterea inițială a unui broadcast în toată rețeaua, ce va genera informații minime de rutare către nodul 0

- Veți implementa metoda de transmitere a pachetelor normale către nodul 0, urmărind protocolul

- Veți trimite un pachet de test în frame-ul 10 de la nodul cu indexul 1. Încercați mai multe topologii (exemplu de topologii simple aveți aici)

Descrierea protocolului

Protocolul presupune următorii pași:

  1. Broadcast inițial din partea Base-station-ului (nodul cu indicele 0). Toți senzorii rețin numărul de hop-uri până la base-station și next-hop până la base-station. Pentru a minimiza șansele ca mesajul de broadcast să fie pierdut, fiecare nod care primește un mesaj de broadcast (prima oară) va transmite în următoarele două frame-uri câte un broadcast.
  1. Orice pachet este direcționat înspre base-station (în cazul nostru simplificat).
  • Pentru a transmite un pachet, un nod va trimite mai întâi un scurt pachet RTS (care conține destinația hop-ului curent). Trimiterea acestui pachet se face cu contention period, nodul va aștepta un interval random mărginit de un sfert din perioada activă (deci între 0 și ACTIVE_PERIOD/4) înainte de a trimite, și se abține dacă a fost transmis între timp alt pachet RTS.
  • Nodul care este adresat ca next hop va răspunde cu un mesaj CTS
  • Pachetul poate fi transmis în acea perioadă activă imediat după recepționarea CTS

Schelet de cod

Scheletul de cod conține câteva definiții și funcții ce vă pot fi utile:

  1. Frame_t este structura ce definește un frame venit pe rețea
  1. node_address este indexul nodului
  1. initRF este o funcție de inițializare a transceiver-ului
  1. setState este funcția ce setează o nouă stare
  1. initTimer inițializează timer-ul
  1. ISR(SCNT_CMP1) și ISR(TRX24_RX_END) sunt cele două întreruperi pe care trebuie să le folosiți
  1. se recomandă să folosiți cât mai puțin cod în întreruperi (urmărind modelul în care se amână diverse procesări pentru bucla din main, cum apare și în schelet)

Testare

Pentru testare este necesar ca rețeaua să execute următorii pași

1) Fiecare nod să aprindă led-ul roșu (PE4) în perioada activă și să-l stingă în celelalte momente. Implementarea folosește SymbolCounter.

2) Nodul 0 trebuie să trimită broadcast-ul, pentru ca fiecare nod să poată ști cum să ruteze pachete către el

3) Fiecare nod va retransmite de două ori mesajul de broadcast, în două perioade succesive (diametrul rețelei va fi limitat la 9 pentru ca mesajele de broadcast să înceteze înainte de transmiterea pachetelor efective)

4) În timpul frame-ului 10, nodul cu indexul 1 va trimite un pachet conform protocolului către 0

lab3.txt · Last modified: 2013/11/26 17:08 by dan.tudose