wiki:802.11/wlan_exp/app_notes/tutorial_hop_mac/fast_hopping

Version 9 (modified by chunter, 9 years ago) (diff)

--

Tutorial: A Custom Hopping MAC

based on Ref. Des. v1.3

Fast Hopping Approach

Rather than have an AP decree a hopping event by including the Channel Switch Announcement, instead we can let each node on the network have an a priori known frequency hopping schedule. This will not only dramatically reduce overhead, but will also increase reliability since client stations will not have to decode an explicit announcement prior to hopping to a new channel. If we can synchronize our nodes such that don't drift apart from one another, this approach can let us considerably speed up the hopping rate as compared to the prior approach (milliseconds of dwell time vs 10 seconds of dwell time).

The 802.11 standard specifies the Timing Synchronization Function (TSF) for maintaining a common timebase among nodes in a network. The TSF requires every node implement a 64-bit counter which increments every microsecond. Each node maintains its own TSF timer and derives the microsecond clock from its own local oscillator.

In an infrastructure network, the TSF synchronization scheme designates the microsecond timer at the AP as the authoritative time for the network. As part of its normal operation the AP transmits beacon frames at some pre-defined interval (typically 102400 µsec). Every beacon frame contains the 64-bit value of the AP's TSF timer at the instant the transmission occurs. Critically, the beacon's timestamp field must be set at the time of transmission, not the time of packet creation or enqueuing. This guarantees the timestamp value accurately reflects any transmission delays due to medium activity. Every STA in the network which receives a beacon from the AP must update the its local microsecond timer with the value of the timestamp contained in the beacon payload. With high probability this scheme provides a common timebase across the network, with inter-node time offsets bounded by the maximum oscillator drift in one beacon interval. In other words, with the TSF synchronization already in place as part of the 802.11 Reference Design, we do not need to worry about any kind of explicit synchronization in our fast hopping approach. We can just base out frequency selection on the TSF timer and trust that the value in that timer is synchronized with the other nodes in the network.

Example timeline for fast hopping approach

In this design, the 802.11 DCF MAC will operate independently from the hopping schedule. The channel that a transmission uses is completely determined by the start time of that transmission and the frequency hopping schedule. Multiple frames can be transmitted within a single hop interval or a single transmission can extend beyond the next hop boundary. Any ongoing transmission or reception defers the next frequency tuning event until at least after the transmission or reception completes.

Changes to the 802.11 Reference Design

To implement the frequency hopping schedule, the majority of our changes will take place in CPU_LOW. We will leave the high-level AP and STA applications generally unaware of the underlying frequency hopping behavior. The singular exception to this is that we will build in hooks to enable and disable the frequency hopping so the high-level applications can control whether or not the hopping behavior is active. For example, the STA will only enable the low-level frequency hopping once it has completed an active scan and has fully associated with the AP.

Code Common to CPU_HIGH and CPU_LOW

Changes should be made to wlan_mac_ipc_util.h in the project SDK workspace zip.


We need to define one new type of IPC message between CPU_LOW and CPU_HIGH. This message will be used to enable or disable the frequency hopping behavior. Add the following definition to the wlan_mac_ipc_util.h header file:

#define IPC_MBOX_CONFIG_HOPPING         50

The value of 50 is arbitrary. The only real requirement is that it is distinct from the other IPC definitions. You can find the other IPC_MBOX_ definitions in the same file.

MAC High Framework

Changes should be made to wlan_mac_high.c in the project SDK workspace zip.


We should create two functions to enable and disable the frequency hopping behavior for our AP and STA applications to call. These function will use the new IPC message we just created. Add the following functions to the MAC High Framework:

void wlan_mac_high_enable_hopping(){

    wlan_ipc_msg       ipc_msg_to_low;
    u32                ipc_msg_to_low_payload = 1;

    // Send message to CPU Low
    ipc_msg_to_low.msg_id            = IPC_MBOX_MSG_ID(IPC_MBOX_CONFIG_HOPPING);
    ipc_msg_to_low.num_payload_words = 1;
    ipc_msg_to_low.payload_ptr       = &(ipc_msg_to_low_payload);

    ipc_mailbox_write_msg(&ipc_msg_to_low);

}

void wlan_mac_high_disable_hopping(){

    wlan_ipc_msg       ipc_msg_to_low;
    u32                ipc_msg_to_low_payload = 0;

    // Send message to CPU Low
    ipc_msg_to_low.msg_id            = IPC_MBOX_MSG_ID(IPC_MBOX_CONFIG_HOPPING);
    ipc_msg_to_low.num_payload_words = 1;
    ipc_msg_to_low.payload_ptr       = &(ipc_msg_to_low_payload);

    ipc_mailbox_write_msg(&ipc_msg_to_low);

}

Access Point (AP)

Changes should be made to wlan_mac_ap.c in the project SDK workspace zip.


We can make our changes such that it is easy to toggle between the slow Wi-Fi-compliant approach to frequency hopping or our custom fast hopping approach by defining a new value for the HOP_MODE variable we already created. For clarity, add the following comment above the HOP_MODE global variable definition.

// 0 - No hop
// 1 - Slow hop
// 2 - Fast hop
u8 HOP_MODE;


In the main() function of the AP, we had previously set HOP_MODE to a value of 0 and then let the push button callback set the variable to 1 after the Wi-Fi stations had associated. For the fast approach, we can boot the AP directly into a configuration where fast frequency hopping is enabled. Change the assignment of HOP_MODE in main() to the following:

HOP_MODE = 2;

This will also prevent the AP from including any Channel Switch Announcement tags in outgoing beacons. Finally, just before the primary while(1) loop, add the following code snippet:

    if(HOP_MODE == 2){
        wlan_mac_high_enable_hopping();
    } else {
        wlan_mac_high_disable_hopping();
    }

Station (STA)

Changes should be made to wlan_mac_sta.c in the project SDK workspace zip.


In the upcoming changes, we will make sure that the DCF in CPU_LOW boots into a state where frequency hopping is disabled. It is out job in the STA to explicitly enable the functionality. We will do this after we have associated with an AP and have adopted its TSF timebase. Add the following line to the top of the sta_set_association_state() function:

wlan_mac_high_enable_hopping();

MAC Low Framework

Changes should be made to wlan_mac_low.c in the project SDK workspace zip.


We need to process the new IPC message we created above and notify the DCF code that it should enable or disable the fast hopping mechanism. To begin, we create two new function callbacks as global variables at the top of the MAC low framework:

static function_ptr_t        enable_hopping_callback;
static function_ptr_t        disable_hopping_callback;

These callback should be set to the nullCallback in wlan_mac_low_init(). This will prevent any CPU_LOW crashes if these callbacks are executed prior to being assigned as valid function pointers.

    enable_hopping_callback = (function_ptr_t)nullCallback;
    disable_hopping_callback = (function_ptr_t)nullCallback;

We need to provide the DCF with the ability to assign these callbacks. Add the following functions to the MAC low framework:

inline void wlan_mac_low_set_enable_hopping_callback(function_ptr_t callback){
    enable_hopping_callback = callback;
}

inline void wlan_mac_low_set_disable_hopping_callback(function_ptr_t callback){
    disable_hopping_callback = callback;
}

Finally, we need to execute one of these callbacks when we receive the new IPC message. In the process_ipc_msg_from_high() function, add the following case to the large switch statement:

        case IPC_MBOX_CONFIG_HOPPING:
            if(ipc_msg_from_high_payload[0]){
                enable_hopping_callback();
            } else {
                disable_hopping_callback();
            }
        break;

DCF

Changes should be made to wlan_mac_dcf.c in the project SDK workspace zip.


We need to define the sequence of channels that a node should traverse through over time. Here, we have created a vector of length 1024 where each element is a valid 2.4 GHz Wi-Fi channel chosen pseudorandomly from a uniform distribution over the range of [1, 11]. Add this variable definition to the top of the DCF code:

#define HOP_SEQ_LEN 1024
u8 hop_vec[HOP_SEQ_LEN] = { 2, 10, 9, 6, 1, 3, 11, 8, 3, 8, 2, 7, 9, 5, 1, 7, 8, 2, 10, 6,
 4, 4, 8, 6, 5, 4, 7, 1, 7, 11, 6, 4, 9, 2, 1, 5, 6, 9, 8, 6,
 3, 2, 5, 5, 11, 11, 4, 10, 7, 6, 10, 9, 6, 1, 5, 5, 7, 2, 7, 5,
 1, 2, 5, 6, 4, 10, 7, 3, 2, 9, 8, 4, 1, 5, 6, 6, 10, 11, 5, 3,
 11, 8, 11, 8, 8, 5, 1, 7, 9, 8, 1, 2, 9, 6, 5, 4, 3, 11, 5, 2,
 6, 1, 7, 5, 9, 2, 6, 7, 1, 6, 9, 2, 8, 10, 6, 1, 4, 11, 2, 9,
 4, 4, 6, 5, 11, 4, 2, 3, 2, 9, 7, 8, 8, 7, 4, 2, 10, 4, 7, 6,
 8, 3, 4, 8, 11, 4, 10, 10, 10, 9, 3, 11, 10, 10, 9, 6, 10, 11, 1, 9,
 6, 7, 11, 10, 11, 4, 4, 4, 4, 7, 4, 11, 8, 9, 3, 2, 1, 7, 7, 5,
 1, 2, 6, 9, 9, 11, 9, 5, 4, 2, 7, 3, 2, 9, 6, 8, 2, 5, 7, 10,
 11, 4, 5, 2, 8, 3, 10, 5, 5, 2, 1, 9, 9, 6, 10, 7, 2, 1, 2, 4,
 9, 9, 2, 9, 2, 8, 1, 5, 9, 6, 11, 4, 7, 3, 5, 11, 4, 10, 8, 1,
 6, 8, 5, 2, 7, 11, 11, 11, 10, 8, 10, 10, 9, 2, 1, 6, 2, 5, 4, 5,
 11, 10, 11, 3, 1, 10, 8, 7, 3, 6, 1, 5, 3, 4, 11, 10, 3, 5, 9, 9,
 1, 3, 1, 8, 10, 4, 8, 2, 5, 10, 8, 8, 10, 4, 8, 4, 11, 9, 10, 9,
 9, 5, 2, 2, 9, 1, 6, 10, 11, 6, 1, 6, 3, 4, 11, 2, 9, 4, 6, 2,
 1, 10, 1, 10, 5, 5, 4, 1, 8, 4, 8, 9, 8, 6, 9, 1, 1, 5, 2, 9,
 1, 2, 5, 3, 11, 5, 6, 3, 7, 6, 11, 8, 10, 1, 5, 1, 7, 9, 8, 1,
 8, 4, 4, 8, 2, 3, 5, 7, 4, 5, 4, 11, 8, 2, 8, 1, 9, 1, 5, 8,
 1, 5, 2, 7, 3, 5, 10, 1, 8, 4, 10, 4, 5, 11, 10, 10, 11, 2, 4, 8,
 7, 10, 3, 4, 3, 1, 8, 4, 1, 4, 2, 1, 7, 1, 10, 1, 6, 2, 5, 10,
 8, 11, 5, 5, 9, 10, 8, 2, 4, 3, 3, 8, 4, 11, 10, 7, 10, 4, 7, 7,
 4, 7, 2, 9, 10, 8, 1, 11, 1, 3, 5, 5, 2, 11, 2, 9, 8, 4, 2, 11,
 10, 2, 5, 6, 9, 10, 11, 8, 7, 10, 5, 10, 9, 10, 5, 1, 10, 7, 9, 7,
 11, 2, 8, 2, 1, 7, 7, 9, 1, 1, 7, 9, 3, 6, 7, 7, 1, 3, 2, 6,
 9, 11, 1, 10, 10, 6, 5, 1, 2, 8, 7, 8, 5, 9, 6, 10, 1, 7, 9, 4,
 6, 10, 6, 9, 7, 10, 5, 2, 11, 5, 6, 8, 1, 4, 9, 1, 1, 4, 4, 9,
 3, 5, 8, 10, 7, 11, 11, 7, 11, 10, 4, 11, 10, 5, 9, 4, 2, 9, 7, 7,
 3, 4, 9, 7, 4, 4, 3, 6, 7, 1, 2, 6, 6, 6, 2, 2, 5, 8, 9, 7,
 7, 11, 6, 4, 3, 3, 5, 7, 11, 4, 4, 7, 3, 2, 1, 6, 1, 7, 7, 1,
 5, 9, 7, 5, 6, 5, 1, 9, 9, 7, 7, 7, 7, 3, 9, 8, 9, 2, 1, 9,
 9, 7, 1, 4, 11, 10, 8, 2, 8, 1, 7, 6, 8, 5, 1, 5, 6, 1, 7, 4,
 10, 11, 3, 4, 2, 8, 8, 7, 5, 7, 6, 8, 10, 4, 7, 1, 3, 9, 4, 1,
 8, 8, 8, 10, 2, 8, 5, 8, 4, 8, 4, 11, 5, 8, 9, 3, 8, 9, 8, 2,
 2, 9, 11, 9, 11, 7, 6, 1, 7, 9, 9, 3, 9, 8, 11, 5, 1, 4, 4, 6,
 1, 2, 3, 9, 10, 7, 4, 3, 1, 10, 3, 11, 2, 6, 5, 9, 11, 4, 11, 2,
 1, 10, 11, 7, 1, 10, 10, 7, 6, 1, 5, 9, 6, 6, 10, 1, 3, 2, 1, 4,
 10, 2, 11, 2, 6, 5, 8, 10, 4, 4, 1, 3, 9, 11, 8, 6, 8, 1, 10, 8,
 2, 6, 6, 7, 11, 7, 7, 11, 1, 8, 2, 7, 9, 1, 6, 4, 8, 7, 1, 10,
 11, 2, 1, 11, 5, 9, 11, 10, 11, 4, 8, 10, 10, 10, 1, 10, 7, 7, 9, 6,
 10, 2, 8, 7, 6, 3, 11, 11, 8, 2, 6, 6, 1, 5, 9, 9, 2, 5, 9, 3,
 7, 1, 8, 10, 8, 4, 6, 4, 3, 9, 7, 6, 11, 9, 7, 9, 7, 1, 6, 10,
 5, 3, 6, 5, 9, 9, 4, 11, 4, 3, 2, 4, 11, 8, 3, 4, 4, 10, 6, 7,
 9, 4, 3, 10, 1, 1, 4, 10, 6, 4, 6, 8, 7, 10, 1, 3, 8, 5, 4, 1,
 4, 5, 7, 3, 10, 10, 11, 7, 4, 9, 6, 7, 8, 1, 8, 4, 3, 4, 4, 3,
 2, 8, 4, 3, 7, 1, 10, 1, 3, 4, 8, 7, 8, 4, 11, 4, 6, 2, 10, 3,
 1, 5, 11, 3, 4, 6, 7, 5, 8, 2, 1, 1, 7, 10, 7, 6, 8, 5, 3, 7,
 7, 9, 3, 4, 1, 4, 4, 8, 7, 9, 10, 10, 1, 6, 1, 9, 4, 3, 3, 2,
 3, 10, 9, 9, 3, 2, 1, 4, 8, 7, 7, 3, 5, 4, 10, 9, 10, 5, 9, 1,
 11, 8, 3, 9, 6, 10, 4, 7, 3, 2, 3, 5, 8, 1, 8, 3, 10, 7, 6, 2,
 3, 5, 11, 6, 2, 11, 6, 10, 4, 9, 1, 3, 9, 8, 10, 7, 6, 9, 10, 10,
 10, 8, 5, 1};


Next, we should create a top-level global variable that represents whether or not the frequency hopping mechanism is currently enabled. Add the following new global variable to the DCF code:

static u8 enable_hop;

Next, we'll create setter functions that control this variable. Add the following functions to the DCF code:

void enable_hopping(){
    enable_hop = 1;
}

void disable_hopping(){
    enable_hop = 0;
}

We will now attach these new functions to the callbacks we just created in the MAC Low Framework. We will also explicitly call the disable_hopping() function at boot and wait for a CPU_HIGH project to explicitly tell us when we should enable the frequency hopping behavior. Add the following lines to the initialize code in main():

    disable_hopping();
    wlan_mac_low_set_enable_hopping_callback((void*)enable_hopping);
    wlan_mac_low_set_disable_hopping_callback((void*)disable_hopping);

Characterizing the Design

Oscilloscope Plots
Fast Hopping 802.11 Throughput vs. Time
Standard 802.11
Slow Frequency Hopping 802.11
Fast Frequency Hopping 802.11