⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 howto.tex

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 TEX
📖 第 1 页 / 共 4 页
字号:
\paragraph{stats-structure}So we're able to retrieve the SNR from the outside, we have to writeit in this structure:\begin{lyxcode}typedef~struct~\{~~double~snr;\}~stats\_t;~\end{lyxcode}\paragraph{rcv\_init}Let's just start with a SNR of -2.3:\begin{lyxcode}stats->snr~=~-2.3;config->type~=~0;~\end{lyxcode}\paragraph{rcv\_reconfigure}\begin{lyxcode}private->type~=~config->type;~\end{lyxcode}The functions \emph{rcv\_configure\_input} and \emph{rcv\_configure\_output}can be deleted, as this module is at the end of the chain.\paragraph{rcv\_pdata}Here goes the working function. It's just about implementing the aboveformula. Let's go through step by step. Definition of variables:\begin{lyxcode}stats\_t~{*}stats;SYMBOL\_COMPLEX~{*}in,~{*}buf\_rnd;U8~{*}in\_rnd;double~signal~=~0.,~noise~=~0.;int~i;~\end{lyxcode}Then we have to make sure that we have both the signal from the channeland the random-data:\begin{lyxcode}if~(~!data\_available(0)~||~!data\_available(1)~)\{~~PR\_DBG(~4,~\char`\"{}Not~all~data~available~yet\textbackslash{}n\char`\"{}~);~~return~0;\}\end{lyxcode}Now we reconstruct $x$ so that we can implement the formula givenabove. Instead of calculating $x$ and then taking the sign of it,we directly calculate $x$ with an amplitude of $\pm1$. Again, oncefor the QPSK-signals on the axes, and once for the signals tiltedby $\frac{\pi}{4}$\begin{lyxcode}in\_rnd~=~buffer\_in(1);buf\_rnd~=~swr\_malloc(~size\_in(0)~{*}~sizeof(~SYMBOL\_COMPLEX~)~);for~(~i=0;~i<size\_in(0);~i++~)\{~~switch(~private->type~)\{~~case~0:~~~~buf\_rnd{[}i{]}.real~=~(~2~{*}~(~{*}in\_rnd~\&~1~)~-~1~);~~~~{*}in\_rnd~=~{*}in\_rnd~>\,{}>~1;~~~~buf\_rnd{[}i{]}.imag~=~(~2~{*}~(~{*}in\_rnd~\&~1~)~-~1~);~~~~{*}in\_rnd~=~{*}in\_rnd~>\,{}>~1;~~~~break;~~case~1:~~~~if~(~{*}in\_rnd~\&~1~)\{~~~~~~{*}in\_rnd~=~{*}in\_rnd~>\,{}>~1;~~~~~~buf\_rnd{[}i{]}.real~=~(~2~{*}~(~{*}in\_rnd~\&~1~)~-~1~);~~~~~~buf\_rnd{[}i{]}.imag~=~0;~~~~\}~else~\{~~~~~~{*}in\_rnd~=~{*}in\_rnd~>\,{}>~1;~~~~~~buf\_rnd{[}i{]}.imag~=~(~2~{*}~(~{*}in\_rnd~\&~1~)~-~1~);~~~~~~buf\_rnd{[}i{]}.real~=~0;~~~~\}~~~~{*}in\_rnd~=~{*}in\_rnd~>\,{}>~1;~~~~break;~~\}~~//~Get~the~next~input-byte~of~random~~if~(~i~\&\&~!(~i~\%~4~)~)\{~~~~in\_rnd++;~~\}\}\end{lyxcode}Now we can calculate the amplitude of the signal:\begin{lyxcode}in~=~buffer\_in(0);//~Calculate~signal~energyfor~(~i=0;~i<size\_in(0);~i++~)\{~~signal~+=~(double)(~in{[}i{]}.real~)~{*}~buf\_rnd{[}i{]}.real~+~~~~(double)(~in{[}i{]}.imag~)~{*}~buf\_rnd{[}i{]}.imag;\}signal~=~signal~/~size\_in(0);~\end{lyxcode}And the noise-variance:\begin{lyxcode}for~(~i=0;~i<size\_in(0);~i++~)\{~~noise~+=~pow(~(double)in{[}i{]}.real~-~signal~{*}~buf\_rnd{[}i{]}.real,~2~)~+~~~~pow(~(double)in{[}i{]}.imag~-~signal~{*}~buf\_rnd{[}i{]}.imag,~2~);\}noise~=~noise~/~size\_in(0)~/~2;~\end{lyxcode}Finally we can calculate the snr:\begin{lyxcode}PR\_DBG(~2,~\char`\"{}signal\_amp:~\%i,~noise\_amp:~\%g\textbackslash{}n\char`\"{},~~~~~~~~~(int)signal,~noise~);~~//~And~write~the~snrswr\_sdb\_get\_stats\_struct(~context->id,~(void{*}{*})\&stats~);if~(~noise~>~0~)\{~~stats->snr~=~10~{*}~(~log10(~signal~)~{*}~2~-~log10(~noise~)~);\}swr\_free(~buf\_rnd~);\end{lyxcode}Again, the \emph{rcv\_user\_msg} is not used and can be deleted.\paragraph{rcv\_module\_init}We have only 1 input, no output, 1 config-variable and 1 stats-variable,and lots of functions are not used:\begin{lyxcode}desc~=~swr\_spc\_get\_new\_desc(~1,~0,~1,~1~);UM\_STATS\_DOUBLE(~''snr''~);UM\_INPUT(~SIG\_SYMBOL\_COMPLEX,~0~);desc->fn\_init~~~~~~~~~~~~~~=~rcv\_init;desc->fn\_reconfigure~~~~~~~=~rcv\_reconfig;desc->fn\_process\_data~~~~~~=~rcv\_pdata;~~~desc->fn\_finalize~~~~~~~~~~=~rcv\_finalize;~rcv\_id~=~swr\_cdb\_register\_spc(~\&desc,~\char`\"{}snr\_rcv\char`\"{}~);~\end{lyxcode}\subsubsection{Makefile}In the makefile we have to tell the final name of the module, as wellthat we use the math-library:\begin{lyxcode}MODULE\_NAME~=~snrMATH~=~true~\end{lyxcode}\subsection{Compile it}Now you can try to compile it by typing \emph{make} on the command-line.If there are any errors, try to fix them, the above lines should work,they have been tested. In order to include this module even betterin the MSR, you can add the name of the directory to the file \emph{Modules/Signals/Makefile}in the line \emph{DIRS} = . Like this a top-level \emph{make} willalso update the SNR-module.\section{Testing}Up to now only the module has been written. It is not yet in a usablestate, as it is only registered with the CDB, but not yet instantiated.Theoretically we could write everything in the module to make an instance,but this would turn upside-down the idea of modules. So what we needis an own program that implements the chain and runs it, just to lookhow good it runs.Perhaps as a surprise, this program will again be a module, but thistime a module that does actually something. Implementing a simplechain. So there is a function called \emph{um\_module\_init} thatwill be called upon inserting the module. This function itself createsa new thread that will be used to create the chain. In order to becompatible for further RTLinux implementation, we have to do thistwo-step calling.\subsection{The Directory}In the MSR, there is a directory called \emph{Test} which holds alreadydifferent tests. The test for the SNR is of course in a directorycalled \emph{Test/SNR}. The templates for the test-module are in\begin{lyxcode}Conventions\emph{/}test\_template\emph{.c}~Conventions\emph{/}Makefile\emph{.}module~\end{lyxcode}Again, for easier handling they are renamed:\begin{lyxcode}test\_template.c~->~test\_snr.cMakefile.module~->~Makefile~\end{lyxcode}\subsection{Makefile}The makefile wants to know the name of the module, which is \emph{test\_snr},as well as the modules to load in order for the MSR to function correctly.In our case, these are the modules \emph{random, snr, midamble, rrc}and \emph{block}:\begin{lyxcode}MODULE\_NAME~=~test\_snrDEPENDS~=~random~snr~midamble~rrc~block~\end{lyxcode}\subsection{test\_snr.c}Let's have a look at the documentation:\begin{lyxcode}Make~a~simple~chain:random~-~snr\_send~-~midamble~-~rrc~-~block~-~~~~~~~~~~matched\_filter~-~snr\_rcvand~additionally:random~-~snr\_rcv(2)\end{lyxcode}Then we can create our main-function, which is called \emph{start\_it}for the test-program.\subsubsection{start\_it}The first thing we have to do is to create a \emph{chain} of modules.A chain is a logical suit of signal-processing modules, that takesome input and produce some output that is handled further down thechain.When using the \emph{swr\_chain\_create} functionwe give a list ofall modules, that will be automatically connected together, and finishthe list with END\_CHAIN. In this call to \emph{swr\_chain\_create},you see three different kind of macros, \emph{NEW\_SPC\_VAR}, \emph{NEW\_SPC}and OLD\_SPC\_IN all of which are described in \ref{sub:Subsystem-DataBase}.In short, while the former allows you to give a variable where a referenceto the module will be stored, the latter just creates the module andconnects it, without giving the reference of the created module. Thethird takes an already defined module for further connections.\begin{lyxcode}swr\_sdb\_id~rnd,~mafi,~snr\_rcv;test\_chain~=~swr\_chain\_create(~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC\_VAR(~''random'',~rnd~),~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC\_VAR(~''snr\_send''~),~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC(~''midamble''~),~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC(~''rrc''~),~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC\_VAR(~''block''~),~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC\_VAR(~''matched\_filter'',~mafi~),~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC\_VAR(~''snr\_rcv'',~snr\_rcv~),~~~~~~~~~~~~~~~~~~~~~~END\_CHAIN~);test\_chain\_2~=~swr\_chain\_create(~~~~~~~~~~~~~~~~~~~~~~NEW\_SPC\_VAR(~''random'',~rnd2~),~~~~~~~~~~~~~~~~~~~~~~OLD\_SPC\_IN(~snr\_rcv,~1~),~~~~~~~~~~~~~~~~~~~~~~END\_CHAIN~);~\end{lyxcode}So we have created a chain. The modules have the following function:\begin{lyxlist}{00.00.0000}\item [random]create random bytes \item [snr\_send]our module created above, takes some random bytes as input,and creates a QPSK output \item [midamble]inserts the training-sequence in the middle of the stream \item [rrc]Root Raised Cosine pulse-shape filtering \item [block]a very simple channel-simulation \item [matched\_filter]uses the training-sequence to make a channel-estimationand does a matched-filtering on the received samples \item [snr\_rcv]our module to calculate the SNR \end{lyxlist}If we compile and test our module with \emph{make; make user}, thischain will be created and the program will exit. What we forgot isto really use this chain. For this, the \emph{random} module listensto user-messages, and begins creating a random-output whenever itreceives such a user-message. But first we have to make sure thatboth random-modules create the same values:\begin{lyxcode}swr\_sdb\_set\_config\_int(~rnd,~\char`\"{}seed\char`\"{},~0x1234~);swr\_sdb\_set\_config\_int(~rnd2,~\char`\"{}seed\char`\"{},~0x1234~);~\end{lyxcode}Then we adjust a bit the amplitudes, so that we don't run all thetime on the edge:\begin{lyxcode}swr\_sdb\_set\_config\_int(~snr\_send,~\char`\"{}amplitude\char`\"{},~16384~/~4~);swr\_sdb\_set\_config\_int(~mid,~\char`\"{}amplitude\char`\"{},~16384~/~4~);~\end{lyxcode}To make it a bit more nice, we have a look at different values, usingthe \emph{sigma} parameter of the \emph{block} module:\begin{lyxcode}for~(~i=0;~i<50;~i+=5~)\{~~swr\_sdb\_set\_config\_double(~block,~\char`\"{}sigma\char`\"{},~i~);~~swr\_sdb\_send\_msg(~rnd,~SUBS\_MSG\_USER,~NULL,~-1~);~~swr\_sdb\_send\_msg(~rnd2,~SUBS\_MSG\_USER,~NULL,~-1~);~~PR(~\char`\"{}Amp:~\%2i:\%2i,~Noise:~\%3i:\%3i~~SNR~:~\%5.5g~-~\%5.5g~=~\%5.5g\textbackslash{}n\char`\"{},~~~~~~swr\_sdb\_get\_stats\_int(~mafi,~\char`\"{}mid\_amp\char`\"{}~),~~~~~~swr\_sdb\_get\_stats\_int(~snr\_rcv,~\char`\"{}amp\char`\"{}~),~~~~~~swr\_sdb\_get\_stats\_int(~mafi,~\char`\"{}noise\_var\char`\"{}~),~~~~~~swr\_sdb\_get\_stats\_int(~snr\_rcv,~\char`\"{}var\char`\"{}~),~~~~~~swr\_sdb\_get\_stats\_double(~mafi,~\char`\"{}snr\char`\"{}~),~~~~~~swr\_sdb\_get\_stats\_double(~snr\_rcv,~\char`\"{}snr\char`\"{}~),~~~~~~swr\_sdb\_get\_stats\_double(~mafi,~\char`\"{}snr\char`\"{}~)~-~~~~~~swr\_sdb\_get\_stats\_double(~snr\_rcv,~\char`\"{}snr\char`\"{}~)~);\}\end{lyxcode}And after a \emph{make; make user} you should see something like:\begin{lyxcode}Amp:~63:63,~Noise:~~~1:1~~~SNR~:~34.40~-~34.24~=~~0.15426Amp:~62:62,~Noise:~~~5:6~~~SNR~:~28.52~-~28.10~=~~0.42007Amp:~62:62,~Noise:~~27:26~~SNR~:~21.50~-~21.58~=~-0.077267Amp:~62:62,~Noise:~~66:63~~SNR~:~17.61~-~17.83~=~-0.21601Amp:~62:61,~Noise:~122:111~SNR~:~14.96~-~15.34~=~-0.37944Amp:~61:61,~Noise:~190:187~SNR~:~12.89~-~13.07~=~-0.18071Amp:~58:59,~Noise:~179:219~SNR~:~12.72~-~12.01~=~~0.70692

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -