📄 c-vm5.html
字号:
<b><a name="84993"> /* make sure can access global virtual memory */</a></b><dd> <b><a name="84995"> printf (string);</a></b><dd> <b><a name="84997"> taskDelay (sysClkRateGet() * 10); } } return (OK); }</a></b><dd> <b><a name="85003">/************************************************************************ * * testVmContextGet - return a task's virtual memory context stored in TCB * * Used with vmContextShow()<sup><a href="#foot"><b class="FootnoteMarker">1</b></a></sup></pre> to display a task's virtual memory context. <br>* For example, from the shell, type: <br>* -> tid = sp (testTask) <br>* -> vmContextShow (testVmContextGet (tid)) <br>*/</a></b></pre><dd><pre class="Code"><b><a name="85019">VM_CONTEXT_ID testVmContextGet ( UINT tid ) { return ((VM_CONTEXT_ID) ((taskTcb (tid))->spare1)); }</a></b></pre></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="85027">7.5.3 Noncacheable Memory</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85029"> </a>Architectures that do not support bus snooping must disable the memory caching that is used for interprocessor communication (or by DMA devices). If multiple processors are reading from and writing to a memory location, you must guarantee that when the CPU accesses the data, it is using the most recent value. If caching is used in one or more CPUs in the system, there can be a local copy of the data in one of the CPUs' data caches. In the example in <a href="c-vm5.html#85036">Figure 7-3</a>, a system with multiple CPUs share data, and one CPU on the system (CPU 0) caches the shared data. A task on CPU 0 reads the data [1] and then modifies the value [2]; however, the new value may still be in the cache and not flushed to memory when a task on another CPU (CPU 1) accesses it [3]. Thus the value of the data used by the task on CPU 1 is the old value and does not reflect the modifications done by the task on CPU 0; that value is still in CPU 0's data cache [2].<div class="frame"><h4 class="EntityTitle"><a name="85036"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 7-3: Example of Possible Problems with Data Caching</font></a></h4><dl class="margin"><div class="Anchor"><a name="85074"> </a><img class="figure" border="0" src="images/c-vma2.gif"></div></dl></div></p><dd><p class="Body"><a name="85076"> </a>To disable caching on a page basis, use<b class="routine"><i class="routine"> vmStateSet</i></b><b>(</b> <b>)</b>; for example:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85077">vmStateSet (pContext, pSData, len, VM_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_NOT) </a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85079"> </a>To allocate noncacheable memory, see the reference entry for <b class="routine"><i class="routine">cacheDmaMalloc</i></b><b>( )</b>.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="85080">7.5.4 Nonwritable Memory</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85082"> </a>Memory can be marked as nonwritable. Sections of memory can be write-protected using <b class="routine"><i class="routine">vmStateSet</i></b><b>(</b> <b>)</b> to prevent inadvertent access. </p><dd><p class="Body"><a name="85084"> </a>One use of this is to restrict modification of a data object to a particular routine. If a data object is global but read-only, tasks can read the object but not modify it. Any task that must modify this object must call the associated routine. Inside the routine, the data is made writable for the duration of the routine, and on exit, the memory is set to <b class="symbol_UC">VM_STATE_WRITABLE_NOT</b>. </p></dl></dl><h4 class="EntityTitle"><a name="85087"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 7-2: Nonwritable Memory </font></a></h4><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85088"> </a>In this code example, to modify the data structure pointed to by <b class="symbol_lc">pData</b>, a task must call <b class="routine"><i class="routine">dataModify</i></b><b>(</b> <b>)</b>. This routine makes the memory writable, modifies the data, and sets the memory back to nonwritable. If a task tries to read the memory, it is successful; however, if it tries to modify the data outside of <b class="routine"><i class="routine">dataModify</i></b><b>(</b> <b>)</b>, a bus error occurs.</p></dl><dl class="margin"><dd><hr class="Line"></dl><dl class="margin"><dd><pre class="Code"><b><a name="85090">/* privateCode.h - header file to make data writable from routine only */</a></b><dd> <b><a name="85092">#define MAX 1024</a></b><dd> <b><a name="85094">typedef struct myData { char stuff[MAX]; int moreStuff; } MY_DATA;</a></b></pre></dl><dl class="margin"><dd><hr class="Line"></dl><dl class="margin"><dd><pre class="Code"><b><a name="85101">/* privateCode.c - uses VM contexts to make data private to a code segment */ </a></b><dd> <b><a name="85103">#include "vxWorks.h" #include "vmLib.h" #include "semLib.h" #include "privateCode.h"</a></b><dd> <b><a name="85108">MY_DATA * pData; SEM_ID dataSemId; int pageSize;</a></b><dd> <b><a name="85112">/*********************************************************************** * * initData - allocate memory and make it nonwritable * * This routine initializes data and should be called only once. * */</a></b><dd> <b><a name="85120">STATUS initData (void) { pageSize = vmPageSizeGet();</a></b><dd> <b><a name="85124"> /* create semaphore to protect data */</a></b><dd> <b><a name="85126"> dataSemId = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);</a></b><dd> <b><a name="85128"> /* allocate memory = to a page */</a></b><dd> <b><a name="85130"> pData = (MY_DATA *) valloc (pageSize);</a></b><dd> <b><a name="85132"> /* initialize data and make it read-only */</a></b><dd> <b><a name="85134"> bzero (pData, pageSize); if (vmStateSet (NULL, pData, pageSize, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT) == ERROR) { semGive (dataSemId); return (ERROR); }</a></b><dd> <b><a name="85142"> /* release semaphore */</a></b><dd> <b><a name="85144"> semGive (dataSemId); return (OK); }</a></b><dd> <b><a name="85148">/******************************************************************** * * dataModify - modify data * * To modify data, tasks must call this routine, passing a pointer to * the new data. * To test from the shell use: * -> initData * -> sp dataModify * -> d pData * -> bfill (pdata, 1024, 'X') */</a></b><dd> <b><a name="85161">STATUS dataModify ( MY_DATA * pNewData ) {</a></b><dd> <b><a name="85167"> /* take semaphore for exclusive access to data */</a></b><dd> <b><a name="85169"> semTake (dataSemId, WAIT_FOREVER);</a></b><dd> <b><a name="85171"> /* make memory writable */</a></b><dd> <b><a name="85813"> if (vmStateSet (NULL, pData, pageSize, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE) == ERROR) { semGive (dataSemId); return (ERROR); }</a></b><dd> <b><a name="85814"> /* update data*/</a></b><dd> <b><a name="85181"> bcopy (pNewData, pData, sizeof(MY_DATA));</a></b><dd> <b><a name="85183"> /* make memory not writable */</a></b><dd> <b><a name="85185"> if (vmStateSet (NULL, pData, pageSize, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT) == ERROR) { semGive (dataSemId); return (ERROR); }</a></b><dd> <b><a name="85192"> semGive (dataSemId);</a></b><dd> <b><a name="85194"> return (OK); }</a></b></pre></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="85197">7.5.5 Troubleshooting</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85200"> </a>If <b class="symbol_UC">INCLUDE_MMU_FULL_SHOW</b> is included in the project facility VxWorks view, you can use<b class="routine"><i class="routine"> vmContextShow</i></b><b>(</b> <b>)</b> to display a virtual memory context on the standard output device. In the following example, the current virtual memory context is displayed. Virtual addresses between 0x0 and 0x59fff are write protected; 0xff800000 through 0xffbfffff are noncacheable; and 0x2000000 through 0x2005fff are private. All valid entries are listed and marked with a <i class="i">V+</i>. Invalid entries are not listed.</p><dl class="margin"><dd><pre class="Code2"><b><a name="85202"></b><tt class="output">-></tt><b> vmContextShow 0 </b><tt class="output">value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="85203"> </a>The output is sent to the standard output device, and looks like the following:</p><dl class="margin"><dd><pre class="Code2"><b><a name="85204"></b><tt class="output">VIRTUAL ADDR BLOCK LENGTH PHYSICAL ADDR STATE 0x0 0x5a000 0x0 W- C+ V+ (global) 0x5a000 0x1f3c000 0x5a000 W+ C+ V+ (global) 0x1f9c000 0x2000 0x1f9c000 W+ C+ V+ (global) 0x1f9e000 0x2000 0x1f9e000 W- C+ V+ (global) 0x1fa0000 0x2000 0x1fa0000 W+ C+ V+ (global) 0x1fa2000 0x2000 0x1fa2000 W- C+ V+ (global) 0x1fa4000 0x6000 0x1fa4000 W+ C+ V+ (global) 0x1faa000 0x2000 0x1faa000 W- C+ V+ (global) 0x1fac000 0xa000 0x1fac000 W+ C+ V+ (global) 0x1fb6000 0x2000 0x1fb6000 W- C+ V+ (global) 0x1fb8000 0x36000 0x1fb8000 W+ C+ V+ (global) 0x1fee000 0x2000 0x1fee000 W- C+ V+ (global) 0x1ff0000 0x2000 0x1ff0000 W+ C+ V+ (global) 0x1ff2000 0x2000 0x1ff2000 W- C+ V+ (global) 0x1ff4000 0x2000 0x1ff4000 W+ C+ V+ (global) 0x1ff6000 0x2000 0x1ff6000 W- C+ V+ (global) 0x1ff8000 0x2000 0x1ff8000 W+ C+ V+ (global) 0x1ffa000 0x2000 0x1ffa000 W- C+ V+ (global) 0x1ffc000 0x4000 0x1ffc000 W+ C+ V+ (global) 0x2000000 0x6000 0x1f96000 W+ C+ V+ 0xff800000 0x400000 0xff800000 W- C- V+ (global) 0xffe00000 0x20000 0xffe00000 W+ C+ V+ (global) 0xfff00000 0xf0000 0xfff00000 W+ C- V+ (global)</tt><b> </a></b></pre></dl></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="85229">7.5.6 Precautions</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85232"> </a>Memory that is marked as global cannot be remapped using <b class="routine"><i class="routine">vmMap</i></b><b>(</b> <b>)</b>. To add to global virtual memory, use <b class="routine"><i class="routine">vmGlobalMap</i></b><b>(</b> <b>)</b>. For further information on adding global virtual memory, see <a href="c-vm5.html#84584"><i class="title">7.5.2 Private Virtual Memory</i></a>.</p><dd><p class="Body"><a name="85237"> </a>Performances of MMUs vary across architectures; in fact, some architectures may cause the system to become non-deterministic. For additional information, see the architecture-specific documentation for your hardware.</p></dl></dl><a name="foot"><hr></a><p class="FootnoteNumberMarker">1: <span class="Footnote"><a name="85009"> </a>This routine is <i class="emphasis">not</i> built in to the Tornado shell. To use it from the Tornado shell, you must define <b class="symbol_UC">INCLUDE_MMU_FULL_SHOW </b>in your VxWorks configuration; see the <i class="title">Tornado User's Guide: Projects</i>. When invoked this routine's output is sent to the standard output device.</span><p class="navbar" align="right"><a href="index.html"><img border="0" alt="[Contents]" src="icons/contents.gif"></a><a href="GuideIX.html"><img border="0" alt="[Index]" src="icons/index.gif"></a><a href="c-vm.html"><img border="0" alt="[Top]" src="icons/top.gif"></a><a href="c-vm4.html"><img border="0" alt="[Prev]" src="icons/prev.gif"></a><a href="c-config.html"><img border="0" alt="[Next]" src="icons/next.gif"></a></p></body></html><!---by WRS Documentation (), Wind River Systems, Inc. conversion tool: Quadralay WebWorks Publisher 4.0.11 template: CSS Template, Jan 1998 - Jefro --->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -