B-mac

Version 16 (Artur Balanuta, 03/12/2015 07:20 pm)

1 15 Anthony Rowe
h1. B-MAC
2 1 Anthony Rowe
3 15 Anthony Rowe
4 15 Anthony Rowe
B-MAC is a low-power listen CSMA (lpl-csma) protocol.  More information can be found in the original "B-MAC paper":http://www.polastre.com/papers/sensys04-bmac.pdf. The main idea about low-power-listen CSMA is that instead of leaving the receiver on 100% the radio is active for short bursts used to check for channel activity.  If activity is detected, the radio remains on in order to receive the data. In order to ensure that a neighboring node receives the message, an extended preamble the length of the check interval is required.  
5 15 Anthony Rowe
6 1 Anthony Rowe
7 16 Artur Balanuta
!rx_tx.png!
8 16 Artur Balanuta
9 4 Anthony Rowe
There is a trade-off between checking more often or sending a longer preamble. For any particular sampling point (sensor sampling rate etc) there is an energy optimal checking rate. 
10 1 Anthony Rowe
11 16 Artur Balanuta
!chk_vs_sample.png!
12 4 Anthony Rowe
13 4 Anthony Rowe
Using the optimal radio checking rate derived from the best energy efficiency at a particular sampling point you can see the following life-time relationship.
14 4 Anthony Rowe
15 16 Artur Balanuta
!chk_vs_life.png!
16 5 Anthony Rowe
17 5 Anthony Rowe
18 11 Anthony Rowe
The current Nano-RK implementation of BMAC has no internal transmit or receive buffers. Applications or higher level network layers must provide their own transmit and receive buffers.  B-MAC will pass transmit buffers directly to the basic_rf transmit functions where additional information like a CRC checksum is added.  When data is received, B-MAC will store this data in the last set receive buffer until the bmac_rx_release() function is called by a higher layer or application.  The reception of a packet will generate a signal notifying any waiting tasks that the packet is ready. Received packets can be checked in a polling fashion using the bmac_rx_status() function, or a task can suspend until a packet arrives using the bmac_rx_packet_get() function.  Timeouts on packet reception can be achieved using the wait until next wakeup configuration commands provided by Nano-RK.  If a timeout occurs, bmac_wait_until_rx_packet() will return an error code.  To allow efficient network layer development, the receive buffer can be changed using the bmac_rx_pkt_set_buffer() function. This should only be done after a packet is received or at startup.  If a new receive buffer pointer has been set, it is then safe to call bmac_rx_pkt_release() indicating that the B-MAC task is allowed to buffer new packets at that memory location.
19 2 Anthony Rowe
20 1 Anthony Rowe
21 1 Anthony Rowe
22 6 Anthony Rowe
The application or network layer is required to allocate static buffers. These should typically be globally defined at the top of your application:
23 1 Anthony Rowe
24 15 Anthony Rowe
<pre>
25 15 Anthony Rowe
<code class="c">
26 1 Anthony Rowe
   uint8_t tx_buf[RF_MAX_PAYLOAD_SIZE];
27 1 Anthony Rowe
   uint8_t rx_buf[RF_MAX_PAYLOAD_SIZE];
28 15 Anthony Rowe
</code></pre>
29 6 Anthony Rowe
30 6 Anthony Rowe
31 7 Anthony Rowe
Here is a sample of how you initialize BMAC and receive data (found in the basic_bmac sample project):
32 6 Anthony Rowe
33 15 Anthony Rowe
<pre>
34 15 Anthony Rowe
<code class="c">
35 10 Anthony Rowe
void rx_task()
36 7 Anthony Rowe
{
37 7 Anthony Rowe
  uint8_t i,len;
38 7 Anthony Rowe
  int8_t rssi,val;
39 7 Anthony Rowe
  uint8_t *local_rx_buf;
40 7 Anthony Rowe
   
41 7 Anthony Rowe
  printf( "rx_task PID=%d\r\n",nrk_get_pid());
42 7 Anthony Rowe
43 6 Anthony Rowe
  // init bmac on channel 25 
44 6 Anthony Rowe
  bmac_init(25);
45 6 Anthony Rowe
  // This sets the next RX buffer.
46 6 Anthony Rowe
  // This can be called at anytime before releaseing the packet
47 6 Anthony Rowe
  // if you wish to do a zero-copy buffer switch
48 1 Anthony Rowe
  bmac_rx_pkt_set_buffer(rx_buf,RF_MAX_PAYLOAD_SIZE);
49 7 Anthony Rowe
50 7 Anthony Rowe
  while(1)
51 7 Anthony Rowe
	{
52 7 Anthony Rowe
	// Wait until an RX packet is received
53 7 Anthony Rowe
	val=bmac_wait_until_rx_packet();	
54 7 Anthony Rowe
	// Get the RX packet 
55 7 Anthony Rowe
  	nrk_set_led(BLUE_LED); 
56 7 Anthony Rowe
	local_rx_buf=bmac_rx_pkt_get(&len,&rssi);
57 7 Anthony Rowe
	printf( "Got RX packet len=%d RSSI=%d [",len,rssi );
58 7 Anthony Rowe
        for(i=0; i<len; i++ )
59 1 Anthony Rowe
                   printf( "%c", local_rx_buf[i]);
60 7 Anthony Rowe
        printf( "]\r\n" );
61 7 Anthony Rowe
	// Release the RX buffer so future packets can arrive 
62 1 Anthony Rowe
  	nrk_clr_led(BLUE_LED); 
63 1 Anthony Rowe
	bmac_rx_pkt_release();
64 7 Anthony Rowe
	}
65 7 Anthony Rowe
66 7 Anthony Rowe
}
67 15 Anthony Rowe
</code></pre>
68 8 Anthony Rowe
69 8 Anthony Rowe
70 8 Anthony Rowe
Here is an example of how you would transmit data using BMAC:
71 8 Anthony Rowe
72 15 Anthony Rowe
<pre>
73 15 Anthony Rowe
<code class="c">
74 8 Anthony Rowe
void tx_task()
75 8 Anthony Rowe
{
76 8 Anthony Rowe
  uint8_t j, i,val,len,cnt;
77 8 Anthony Rowe
  
78 8 Anthony Rowe
  printf( "tx_task PID=%d\r\n",nrk_get_pid());
79 8 Anthony Rowe
  
80 8 Anthony Rowe
  // Wait until the tx_task starts up bmac
81 8 Anthony Rowe
  // This should be called by all tasks using bmac that
82 8 Anthony Rowe
  // do not call bmac_init()...
83 8 Anthony Rowe
  while(!bmac_started()) nrk_wait_until_next_period();
84 8 Anthony Rowe
  cnt=0;
85 8 Anthony Rowe
  while(1)
86 8 Anthony Rowe
	{
87 8 Anthony Rowe
	// Build a TX packet
88 8 Anthony Rowe
	sprintf( tx_buf, "This is a test %d",cnt );
89 1 Anthony Rowe
	cnt++;
90 1 Anthony Rowe
	// Transmit the packet 
91 8 Anthony Rowe
  	nrk_set_led(ORANGE_LED); 
92 8 Anthony Rowe
	val=bmac_tx_packet(tx_buf, strlen(tx_buf));
93 8 Anthony Rowe
	// Task gets control again after TX complete
94 8 Anthony Rowe
  	nrk_clr_led(ORANGE_LED); 
95 8 Anthony Rowe
	printf( "TX task sent data!\r\n" );
96 8 Anthony Rowe
	nrk_wait_until_next_period();
97 8 Anthony Rowe
	}
98 8 Anthony Rowe
99 8 Anthony Rowe
}
100 15 Anthony Rowe
</code></pre>
101 10 Anthony Rowe
102 15 Anthony Rowe
For more detailed information see the [[bmac-api]].