📄 howto.tex
字号:
\part{HOWTOs}\chapter{From Conception to Measurement}\index{From Conception to Measurement|(}Of course the main idea behind the MSR is that you're able to writenew modules for it. This chapter will give an introduction with anactual example of a module as well as an implementation of a radio-transmission.After this you should be able to create your own modules and put theminto use. An important introduction can be found in chapter \ref{cha:A-Basic-System}.You should also already have run the example in chapter \ref{cha:Getting-Started}.This part is a bit heavy on coding, but you won't be able to writemodules without a good knowledge of C.\section{Defining New Modules}\index{From Conception to Measurement!Defining new modules}In here you will learn the most important things about a module, howit works, how to use it, and how to extend it. This example is alreadypresent in the tree, but you can read this section to get a feel ofit.The goal of this module will be to measure the SNR of the signal.Even though this functionality is already implemented in a module,it is a nice idea to have a possibility to compare the results ofthe two approaches. The existing module compares the received trainingsequence with the original in order to calculate the SNR. As the trainingsequence is only part of a transmitted slot, it is a good idea tocompare this SNR with the SNR computed in here.%\begin{figure}\begin{center}\includegraphics{figures/example_slot}\end{center}\caption{\label{cap:The-example-slot}The example slot}\end{figure}In order to calculate the SNR differently, we will transmit a randomsequence and then compare it after the transmission. This is depictedin fig. \ref{cap:The-example-slot}. In order to know the exact amplitude,it is important to know the random sequence in advance. This is doneby setting the \emph{seed} parameter of the random-module.Once we have the received signal $y=y_{r}+iy_{i}=[y_{0r}y_{1r}...y_{n-1r}]+i[y_{0i}y_{1i}...y_{n-1i}]$and the transmitted signal $x$, we can calculate the amplitude:\[a=\frac{\sum_{l=0}^{n-1}y_{lr}sign(x_{lr})+y_{li}sign(x_{li})}{n}\]and also the variance:\[v=\frac{\sum_{l=0}^{n-1}(y_{lr}-a\, sign(x_{lr}))^{2}+(y_{li}-a\, sign(x_{li}))^{2}}{2n}\]and the signal to noise ratio is then\[SNR=10*\log(\frac{a^{2}}{v})\]The correctness of this assertion is left as an exercise to the reader.\subsection{The Files}Now that we know what it is about, let's have a look at the writtenfiles. For your information you will learn where the templates forthe files come from in every section. The discussion then is onlyabout the parts that have been added. In the directory \emph{Modules/Signals},there is a directory called \emph{SNR}. in there you find the codefor the SNR-module. The MSR knows about this directory because ofthe file \emph{Modules/Signals/Makefile} that has an entry \emph{SNR}in the list of \emph{DIRS}. You can have a look at this Makefile tosee it.The template files come from the \emph{Conventions} directory andare called:\begin{lyxcode}Conventions/multi\_{*}.cConventions/Makefile.module~\end{lyxcode}Most of the modules come in two parts: one sending part and one receivingpart. But as they usually are used in a pair, they are put togetherinto one module. So as not to be confused with different modules,they are renamed to:\begin{lyxcode}multi\_template.c~->~snr.cmulti\_template\_send.c~->~snr\_send.cmulti\_template\_rcv.c~->~snr\_rcv.cMakefile.module~->~Makefile~\end{lyxcode}\subsubsection{snr.c}Now look first at the file \emph{snr.c} and look at the places thatcontain some documentation. It is really important to keep this documentationup-to-date, so that other people know what it's about:\begin{lyxcode}SNR~-~measure~the~signal~to~noise~ratio~of~a~transmitted~slot.~~~In~order~to~do~this,~we~send~a~slot~of~known~random~data~thatis~measured~on~the~other~side.~\end{lyxcode}This is all that is needed. Not a big description, just enough toknow what it's about.What it does is the following: once the module \emph{snr} is loadedinto the memory, the function \emph{spc\_module\_init} is called,which in turn calls \emph{rcv\_module\_init} from \emph{snr\_rcv.c}and \emph{send\_module\_init} from \emph{snr\_send.c}. These two functionsare responsible to tell the CDB about their name, their input andoutput as well as their paramters.\subsubsection{snr\_send.c}This is the part that prepares the slot.\paragraph{documentation. }At the top of the file, you see again a short description of the module\begin{lyxcode}snr\_send.c~-~sends~a~slot~of~random~symbols~\end{lyxcode}and a bit further down (after the copyright message) a bit more ofdescription.\begin{lyxcode}This~module~expects~some~random~input~that~is~then~modulatedusing~QPSK~modulation~so~that~the~noise~can~be~mesured.~It~cansend~the~QPSK~symbols~either~on~the~axis~or~in~the~corners.~\end{lyxcode}\paragraph{config-structure}We want the user to be able to change the amplitude of what we sendover the channel. So, edit the config-structure, and make it somethinglike:\begin{lyxcode}typedef~struct~\{~~//~The~amplitude~of~the~generated~QPSK-signal~~int~amplitude;~~//~The~QPSK-type,~0->in~the~corner,~1->on~the~axes~~int~type;\}~config\_t;~\end{lyxcode}It may seem strange that we take an integer for the amplitude, butyou have to know that the signals are all in 16-bit integers, so whatusually is between $+1$ and $-1$ is now between $+32767$ and $-32768$.\paragraph{private-structure}Once the user changed the configuration, we will store it in our privatevariable. This is more for convenience than anything else:\begin{lyxcode}typedef~struct~\{~~int~amplitude;~~int~type;\}~private\_t;~\end{lyxcode}The other structure may be left empty, we don't need it for this example.Just after the structures is a function called\paragraph{send\_init}Why another initialisation function, you might ask. Well, rememberfrom chapter \ref{cha:The-Framework} that first the module is registeredwith the CDB, before it is possible to instantiate it. So, this functionis what is called each time this module is instantiated. In our example,we just want to put a default-value in the amplitude-part of the configuration,so add this line:\begin{lyxcode}config->amplitude~=~32767;config->type~=~0;~\end{lyxcode}32767 is the maximum number that we can have in a 16-bit signed variable.\paragraph{send\_configure\_input}This function is called whenever the MSR wants to know what the sizeof the input should be, given the size of the output. So, for each2 bit of input, we create one symbol with the QPSK representation.This means that two bits of input create one symbol of output, atleast for an even number of symbol-outputs. The only tricky part hereis that the input is not counted in bits, but rather in bytes. So$size_{input}=\frac{2*size_{output}}{8}$, which is written in thisfunction as\begin{lyxcode}size\_in(0)~=~(~size\_out(0)~+~7~)~{*}~2~/~8;~\end{lyxcode}This assures that we always have enough bits to write to the output.\paragraph{send\_configure\_output}The same as before, but this time the opposite direction:\begin{lyxcode}size\_out(0)~=~size\_in(0)~{*}~8~/~2;~\end{lyxcode}\paragraph{send\_reconfig}We use this function to copy the configuration-data to our privatestructure:\begin{lyxcode}private->amplitude~=~config->amplitude;private->type~=~config->type;~\end{lyxcode}\paragraph{send\_pdata}Now comes finally the processing function. This is where the mainaction takes place. Let's first define some variables:\begin{lyxcode}//~Definition~of~variables~-~don't~touchstats\_t~{*}stats;int~i,~amp;U8~{*}in;SYMBOL\_COMPLEX~{*}out;~\end{lyxcode}To get to the input and output-buffers, we have to do the following:\begin{lyxcode}in~=~buffer\_in(0);out~=~buffer\_out(0);~\end{lyxcode}The first line deletes the \emph{data} bit on the input-port, signalingthe MSR that the input-port is free again to receive some data. Furthermoreit returns a pointer to the input-buffer of this module. The secondline gets the output-buffer of this module and sets the \emph{data}bit on the output-port. Once this function returns, the MSR checksfor the \emph{data}-bit in the output-port and, if it is set, handlesthe processing to the next module.OK, now we just have to process the data:\begin{lyxcode}//~Fill~the~slot~with~random~QPSK~symbols~~for~(~i=0;~i<size\_out(0);~i++~)\{~~switch(~2~)\{~~case~1:~~~~//~The~amplitude~in~this~case~is~~~~//~Sqrt(~Re\textasciicircum{}2~+~Im\textasciicircum{}2~)~and~thus~the~~~~//~desired~amplitude~has~to~be~divided~by~~~~//~sqrt(2)~~~~amp~=~private->amplitude~/~sqrt(~2~);~~~~out{[}i{]}.real~=~(~2~{*}~(~{*}in~\&~1~)~-~1~)~{*}~amp;~~~~{*}in~=~{*}in~>\,{}>~1;~~~~out{[}i{]}.imag~=~(~2~{*}~(~{*}in~\&~1~)~-~1~)~{*}~amp;~~~~{*}in~=~{*}in~>\,{}>~1;~~~~break;~~case~2:~~~~amp~=~private->amplitude;~~~~if~(~{*}in~\&~1~)\{~~~~~~{*}in~=~{*}in~>\,{}>~1;~~~~~~out{[}i{]}.real~=~(~2~{*}~(~{*}in~\&~1~)~-~1~)~{*}~amp;~~~~~~out{[}i{]}.imag~=~0;~~~~\}~else~\{~~~~~~{*}in~=~{*}in~>\,{}>~1;~~~~~~out{[}i{]}.imag~=~(~2~{*}~(~{*}in~\&~1~)~-~1~)~{*}~amp;~~~~~~out{[}i{]}.real~=~0;~~~~\}~~~~{*}in~=~{*}in~>\,{}>~1;~~~~break;~~\}~~//~Get~the~next~input-byte~of~random~~if~(~i~\&\&~!(~i~\%~4~)~)\{~~~~in++;~~\}\}\end{lyxcode}You might not be completely fond of this example, but it works (yetto check).\paragraph{send\_custom\_message}This function is not needed and can be deleted\paragraph{send\_module\_init}Registers this module with the CDB. The CDB first wants to be informedabout the type of module to be attached%\footnote{For further information, look at \ref{sub:Class-DataBase}%}. In our case, we have one input, one output, one config-parameterand 0 stats-parameter:\begin{lyxcode}desc~=~swr\_spc\_get\_new\_desc(~1,~1,~2,~0~);~\end{lyxcode}Then we have to tell about the config-parameter, the input-type andthe output-type:\begin{lyxcode}UM\_CONFIG\_INT(~''amplitude''~);UM\_CONFIG\_INT(~''type''~);UM\_INPUT(~SIG\_U8,~0~);UM\_OUTPUT(~SIG\_SYMBOL\_COMPLEX,~0~);~\end{lyxcode}In order for the MSR to know what functions to call in what case,we have to define 'call-back functions'. As these are always the same,they are already pre-defined in the templates, and we only have todelete the \emph{send\_custom\_msg} entry. Now the module-descriptionis complete, save for the name:\begin{lyxcode}send\_id~=~swr\_cdb\_register\_spc(~\&desc,~\char`\"{}snr\_send\char`\"{}~);~\end{lyxcode}\subsubsection{snr\_rcv.c}Let's start with the comment in the beginning of the file:\begin{lyxcode}This~module~receives~the~stream~from~the~matched~filter~~and~the~stream~of~random-signals~that~are~supposed~to~bethe~same~that~have~been~used~by~the~snr\_send.~It~thencalculates~the~amplitude,~the~variance~and~the~snr.~\end{lyxcode}This means that this module has two inputs: one from the channel,and another one from the random-module.\paragraph{config-structure}Again we have the possibility to change the type:\begin{lyxcode}typedef~struct~\{~~//~The~QPSK-type,~0->in~the~corner,~1->on~the~axes~~~~~int~type;~\}~config\_t;~\end{lyxcode}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -