当前位置:网站首页>The solution of frame dropping problem in gnuradio OFDM operation

The solution of frame dropping problem in gnuradio OFDM operation

2022-07-08 01:22:00 You roll, I don't roll

Recently running GNURadio Medium OFDM The problem of losing frames was found during routine .

The use of gnuradio yes 3.8 Version of ,Ubuntu by 20.04, And at least for now  gnuradio 3.9 There's a problem , Here are the causes and solutions .

When using the original routine ( One time transmission 10 frame 960 Bytes of data ) There is no frame loss during the test , But when we replace the data to be sent with picture data to send, we cannot receive it correctly , Even if the channel condition is changed to an ideal noise-free and distortion free channel in the simulation, the same number of data frames will still be lost at the same location .

Found in debugging , When the interval between two trigger signals of timing information is generally 4 In this case , Respectively 958、959、960、961. But only when the job is 958( A complete OFDM The data frame is 960 individual QPSK data ) Frame loss will occur , No problem with anything else , and 958 And normal 960 Two short QPSK data . in addition , The generation of trigger signal for timing is normal , The problem should be in the module that uses the trigger signal after the trigger signal is generated .

After re analyzing the process of data sending and parsing in the routine , I think it could be Header/Payload Demux Problems in the module source code , So let's look at the source code of this module .

chart 1

Source code process and problems :

in general , The reason for frame loss is that the interval between two adjacent timing signals is too short , When extracting data from the current frame, the timing signal of the data of the next frame is read as the data of the current frame , In this way, the timing signal of the next frame of data is lost , Therefore, it causes the phenomenon of frame loss . This phenomenon is inherent in the source code . The specific analysis is as follows :

chart 2 The parallel transmission relationship between the data and the trigger signal is strictly implemented at the corresponding position ,Header/Payload Demux Module read first trigger The signal , When reading the value 1 Time is considered to be the beginning of a frame of data , At this time, it starts from the corresponding position of the data signal and then extracts 1919 Data is output as the data of the current frame .

chart 2

According to the data processing process of the source code , In the source code, every time a timing signal is received , Will be extracted immediately after the timing signal 959 Data is output as the current frame , Therefore, it puts forward high requirements for the accuracy of timing signals , If the interval between two adjacent timing signals is smaller than the length of the normal data frame , For example, the normal interval is 960, If there is an interval of 958 The interval of , Pictured 3, Then in the subsequent extraction 959 The timing signal of the next frame will be read together with the data of the current frame when the data is received , In this way, the timing signal of the next frame of data is lost , Therefore, it causes the phenomenon of frame loss .

chart 3

The way to solve this problem is to modify the source code , On the basis of ensuring that adjacent timing signals do not want to interfere with each other, compile and install the source code again . The source code that needs to be modified is  gr-digital/lib/header_payload_demux_impl.cc as well as  gr-digital/lib/header_payload_demux_impl.h . First, in the  header_payload_demux_impl.h Add variables to :

int d_next_trigger_offset;

  And then in  header_payload_demux_impl.cc Change in  find_trigger_signal Function as follows :

......
    int trigger_nums = 0;
    if (max_rel_offset < skip_items) {
        return rel_offset;
    }
    if (in_trigger) {
        for (int i = skip_items; i < max_rel_offset; i++) {
            if (in_trigger[i]) {
                trigger_nums++;
                // record location of the first trigger
                if(trigger_nums == 1) {
                    rel_offset = i;
                }
                // If there is a second trigger signal,record offset of between the first and second trigger
                else if (trigger_nums == 2) {
                    d_next_trigger_offset = i - rel_offset;
                    break;
                }
            }
        }
    }
......

And then modify general_work() Medium case STATE_PAYLOAD In state  consume The process is as follows :

......
            // Calculate whether the current frame consumes the trigger signal of the next frame data
            // If yes, then make corrections
            int consume_compensation = 0;
            int consume_nums = 0;
            // Calculate total consumption
            consume_nums = (d_curr_payload_len + d_header_len) * (d_items_per_symbol + d_gi) + 
                            d_header_padding_total_items + 
                            d_curr_payload_offset - 
                            items_padding ;
            // make a decision
            if(d_next_trigger_offset <= consume_nums) {
                consume_compensation = consume_nums - d_next_trigger_offset + 1;
            }
            else {
                consume_compensation = 0;
            }
            // add the corrections
            const int items_to_consume =
                d_curr_payload_len * (d_items_per_symbol + d_gi) - items_padding - consume_compensation;
......

After modification, compile and install the source code again , Problem solving ~

原网站

版权声明
本文为[You roll, I don't roll]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130542480690.html