<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://www.xcore.com/wiki/skins/common/feed.css?207"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>XCore Exchange - New pages [en]</title>
		<link>http://www.xcore.com/wiki/index.php/Special:NewPages</link>
		<description>From XCore Exchange</description>
		<language>en</language>
		<generator>MediaWiki 1.15.1</generator>
		<lastBuildDate>Thu, 09 Sep 2010 09:52:46 GMT</lastBuildDate>
		<item>
			<title>VDP-1 by yzoer</title>
			<link>http://www.xcore.com/wiki/index.php/VDP-1_by_yzoer</link>
			<description>&lt;p&gt;Yzoer:&amp;#32;Created page with ''''VDP - Video Display Processor''' VDP-1 is the first in a series of Video Display Processors, primarily modelled after console / handheld hardware such as the Sega Genesis and …'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''VDP - Video Display Processor'''&lt;br /&gt;
VDP-1 is the first in a series of Video Display Processors, primarily modelled after console / handheld hardware such as the Sega Genesis and Nintendo's Gameboy Advance.&lt;br /&gt;
&lt;br /&gt;
With only a handful of resistors to form an R2R DAC, a single-core XS1 using VDP-1 can output either VGA or NTSC. Given the nature of a tile- and spritebased architecture, the memory footprint for applications is surprisingly small and allows for applications to be loaded concurrently.&lt;br /&gt;
&lt;br /&gt;
'''Overview'''&lt;br /&gt;
&lt;br /&gt;
As mentioned before, VDP-1 uses a tile- and spritebased architecture. What this boils down to is that the system doesn't use a frame-buffer but instead uses a scanline based rendering approach, saving significant amounts of memory. VDP-1 can render 2 independently controlled Backgrounds that can be moved both horizontally and vertically, on a per-pixel basis.&lt;br /&gt;
&lt;br /&gt;
Similarly, the system allows for 32 independently controlled objects, called sprites. Sprites can be compared to 'mini-backgrounds' and range from 8x8 to 64x64 pixels. Like backgrounds, the can be positioned on a per-pixel basis.&lt;br /&gt;
&lt;br /&gt;
In order to use VDP-1 efficiently, a brief description of the system will be described below.&lt;br /&gt;
&lt;br /&gt;
'''Tiles'''&lt;br /&gt;
&lt;br /&gt;
Tiles are the foundation of VDP-1. A tile is the base unit for both backgrounds and sprites and consists of 8x8 pixels. Each pixel in a tile can take one of 16 colors. Each color is therefore encoded as a 4-bit nibble. With 4-bits per pixel and 64 pixels per tile, the total memory footprint for a tile is 32 bytes.&lt;br /&gt;
&lt;br /&gt;
'''Palettes'''&lt;br /&gt;
&lt;br /&gt;
VDP-1 supports 16 palettes of 16 colors each, giving a grand total of 256 colors on-screen at once. Each palette entry consists of 5 bits for red,green and blue respectively ( 5:5:5 ) and therefore occupies 2 bytes per entry. The total palette foot-print therefore comes in at 512 bytes ( 16 palettes x 16 entries x 2 bytes per entry = 512 ).&lt;br /&gt;
&lt;br /&gt;
Palettes are closely related to tiles ( and sprites ) in that each 4-bit pixels in a tile serves as a look-up into a specified palette. In order to see the relationship between pixels on-screen, tiles and palettes, consider the following scenario:&lt;br /&gt;
&lt;br /&gt;
Tile pattern definition in hexadecimal:&lt;br /&gt;
&lt;br /&gt;
unsigned int tiledata[] = {&lt;br /&gt;
    0x11111111,&lt;br /&gt;
    0x10000001,&lt;br /&gt;
    0x10000001,&lt;br /&gt;
    0x10022001,&lt;br /&gt;
    0x10022001,&lt;br /&gt;
    0x10000001,&lt;br /&gt;
    0x10000001,&lt;br /&gt;
    0x11111111,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
and a corresponding palette:&lt;br /&gt;
&lt;br /&gt;
unsigned short palette[16] = {&lt;br /&gt;
    RGB(0,0,0),   // black&lt;br /&gt;
    RGB(31,0,0),    // red,&lt;br /&gt;
    RGB(0,31,0),  // blue&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
For each nibble in the tile, a corresponding color is fetched from its referenced palette. So for each pixel that is serialized out of the tile, a 15-bit RGB value is displayed on-screen. By limiting the number of colors in a tile to 16, we saved ourselves 4 times the amount of memory!&lt;br /&gt;
&lt;br /&gt;
'''Backgrounds'''&lt;br /&gt;
&lt;br /&gt;
Now that we know how a tile gets defined in memory and how each pixels gets a color from its specified palette, we need to figure out a way to organize the tiles together so we can create more interesting images. This is where backgrounds come in. Backgrounds are yet another level of indirection, which is often somewhat confusing.&lt;br /&gt;
&lt;br /&gt;
A background is a rectangular area in memory that specifies which tiles get rendered where and with what palette. Each background is made up of 64x32 'cells', creating a 512x256 image.&lt;br /&gt;
&lt;br /&gt;
Cells contain the index and palette number of the tile to be rendered as well as two additional bits to allow for tiles to be flipped horizontally and vertically. Since tiles are always of a fixed size, each index is internally multiplied by 32.&lt;br /&gt;
&lt;br /&gt;
- more to come -&lt;/div&gt;</description>
			<pubDate>Wed, 18 Aug 2010 18:01:01 GMT</pubDate>			<dc:creator>Yzoer</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:VDP-1_by_yzoer</comments>		</item>
		<item>
			<title>Boot and initialisation</title>
			<link>http://www.xcore.com/wiki/index.php/Boot_and_initialisation</link>
			<description>&lt;p&gt;Jamie:&amp;#32;/* Synchronisation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page gives a brief description of the boot and initialisation process for single chip or networks of XS1 processors and how these may be replaced.&lt;br /&gt;
&lt;br /&gt;
The boot and initialisation process is generated automatically by the mapper and included in the final multi-core program binary. It works in three phases, and it is possible to disable any of these enabling the use of a different method. Each of these phases are described below.&lt;br /&gt;
&lt;br /&gt;
==Network bringup==&lt;br /&gt;
&lt;br /&gt;
Network bringup is only necessary in systems with externally linked chips, such as the XMP-64, in order to establish node labelings and Xlink and routing table setup. When booting from JTAG, this phase is performed by loading an executing a separate binary (Loadable 1) for each core in the system. Once the execution of this has finished, the second program binary for each code (Loadable 2) is loaded and executed. When booting from flash the automatically generated second stage loader performs network bringup and loading. For more details see the XE file format section of the [http://www.xmos.com/published/tools-development-guide?ver=1.0 Tools Developer Guide].&lt;br /&gt;
&lt;br /&gt;
The network bringup phase can excluded from a multi-core binary either by using xobjdujmp to manually construct it with ELF images for each core, or to extract it, again using xobjdump.&lt;br /&gt;
&lt;br /&gt;
==C/XC runtime startup==&lt;br /&gt;
&lt;br /&gt;
The runtime startup initialises the environment for C and XC programs to run, which includes setting up pointers, threads and channels. This is included in the program binary and is executed before the main function in the program. The inclusion of this can be disabled with the '-nostdlib' compiler flag. When this is disabled, the ELF symbol '_start' must be defined, as execution will start from that address.&lt;br /&gt;
&lt;br /&gt;
==Synchronisation==&lt;br /&gt;
&lt;br /&gt;
Channels, possibly over Xlinks, are used to ensure that all cores are in a known state and ready and some additional cleanup is performed. The top-level channel ends are allocated and the values communicated between cores. Then, on each core the correct top-level functions are called. This phase can be disabled by using the '--nochaninit' mapper flag.&lt;br /&gt;
&lt;br /&gt;
Synchronisation is performed using a spare register in the switch (register number 3) of node 0. This is referred to at the scratch register. On power up the scratch register has value 0. When node 0, core 0 is ready to synchronise it writes 1 to it then polls, waiting for it to reach num_cores.&lt;br /&gt;
&lt;br /&gt;
Each of the other cores is assigned a unique number in the range 1..num_cores-1 (let's call it boot_id) in the linker-generated code. At startup each core polls the scratch register waiting for it to reach boot_id. When it does, it sets it to boot_id+1.&lt;br /&gt;
&lt;br /&gt;
In order to reach num_cores each of the cores must have detected its own number and written the next. Thus they are all known to have reached a known point in the boot.&lt;/div&gt;</description>
			<pubDate>Mon, 02 Aug 2010 11:44:41 GMT</pubDate>			<dc:creator>Jamie</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Boot_and_initialisation</comments>		</item>
		<item>
			<title>Interrupts</title>
			<link>http://www.xcore.com/wiki/index.php/Interrupts</link>
			<description>&lt;p&gt;Segher:&amp;#32;/* Its stack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page gives some description of, and example code showing how to use interrupts in the XS1 ISA. The details are all included in the [http://www.xmos.com/published/xmos-xs1-architecture-0?ver=xs1_en.pdf XS1 Architecture] manual, but this is intended to be a higher-level and more practical description.&lt;br /&gt;
&lt;br /&gt;
Interrupts are a special kind of event that trigger entry to a predefined point of the program whilst saving the program counter (pc), status register (sr) and exception data (ed) registers in the saved pc (spc), sr (ssr) and ed (sed) registers respectively. This allows execution to resume at the point of interruption once the cause has been dealt with.&lt;br /&gt;
&lt;br /&gt;
=Generating interrupts=&lt;br /&gt;
&lt;br /&gt;
Interrupts can be generated in three ways: by exceptions, kernel calls and resources. An exception may be raised automatically by an illegal operation, such as an unaligned memory access, or explicitly by an ECALL instruction. In both cases, pc, sr and ed are saved, and control is transferred to the kernel entry point (kep). A kernel call can be made by executing the KCALL instruction, which again saves state and sets the pc to kep+64. Resources can also be setup to generate interrupts, and each can be assigned its own interrupt handler: the event vector (ev). The following example code shows how to setup a channel resource to generate interrupts on receiving a message.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
getr r11, XS1_RES_TYPE_CHANEND            # Get a channel&lt;br /&gt;
eeu  res[r11]                             # Enable events and interrupts on the channel&lt;br /&gt;
setc res[r11], XS1_SETC_IE_MODE_INTERRUPT # Set the resource control bits to generate interrupts&lt;br /&gt;
ldap r10, intrhandler                     # Load the address of the interrupt handler&lt;br /&gt;
setv res[r11], r10                        # Set the event vector to the interrupt handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The kernel=&lt;br /&gt;
&lt;br /&gt;
Interrupts are intended to ''interrupt'' the normal execution of the program, possibly at an unexpected moment. This is in contrast with events which are waited on to occur. Whether the interrupt is caused by an exception, kernel call or resource action, the general idea is to deal with the cause and then return to the original location and state of execution. This can be achieved with the use of a ''kernel'' to save ''all'' of the execution state, handle the interrupt and then restore it to resume.&lt;br /&gt;
&lt;br /&gt;
==Its stack==&lt;br /&gt;
&lt;br /&gt;
The kep can be initialised using the SETKEP instruction. Once in the interrupt handler, the kernel may operate using the program stack or with a seperate ''kernel stack'', by executing KENTSP instead of ENTSP. There is no specific instruction to set the kernel stack pointer (ksp), but it can be set using the following sequence:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set sp, r11    # Set the stack pointer&lt;br /&gt;
stw r11, sp[0] # Copy this into the location krestsp expects to find sp&lt;br /&gt;
krestsp 0      # Execute KRESTSP to set ksp = sp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Preserving execution state==&lt;br /&gt;
&lt;br /&gt;
On entering the kernel in the event of an interrupt, the state of the executing program (i.e. the registers available to it), must be preserved so none are overwritten by the execution of the handler. There are several instructions provided to store/load special saved regsiters: spc, ssr, sed, to/from the stack. As an example, on entry to the kernel, we can store all the registers that might be used by the handler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kentsp 17      # Switch to kernel stack and allocate 17 words&lt;br /&gt;
stw spc, sp[1]&lt;br /&gt;
stw ssr, sp[2]&lt;br /&gt;
stw sed, sp[3]&lt;br /&gt;
stw r0,  sp[4]&lt;br /&gt;
stw r1,  sp[5]&lt;br /&gt;
stw r2,  sp[6]&lt;br /&gt;
stw r3,  sp[7]&lt;br /&gt;
stw r4,  sp[8]&lt;br /&gt;
stw r5,  sp[9]&lt;br /&gt;
stw r6,  sp[10]&lt;br /&gt;
stw r7,  sp[11]&lt;br /&gt;
stw r8,  sp[12]&lt;br /&gt;
stw r9,  sp[13]&lt;br /&gt;
stw r10, sp[14]&lt;br /&gt;
stw r11, sp[15]&lt;br /&gt;
stw lr,  sp[16]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And then restore them, when we exit the kernel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldw spc, sp[1]&lt;br /&gt;
ldw ssr, sp[2]&lt;br /&gt;
ldw sed, sp[3]&lt;br /&gt;
ldw r0,  sp[4]&lt;br /&gt;
ldw r1,  sp[5]&lt;br /&gt;
ldw r2,  sp[6]&lt;br /&gt;
ldw r3,  sp[7]&lt;br /&gt;
ldw r4,  sp[8]&lt;br /&gt;
ldw r5,  sp[9]&lt;br /&gt;
ldw r6,  sp[10]&lt;br /&gt;
ldw r7,  sp[11]&lt;br /&gt;
ldw r8,  sp[12]&lt;br /&gt;
ldw r9,  sp[13]&lt;br /&gt;
ldw r10, sp[14]&lt;br /&gt;
ldw r11, sp[15]&lt;br /&gt;
ldw lr,  sp[16]&lt;br /&gt;
krestsp 17      # Contract the kernel stack and switch to user stack&lt;br /&gt;
kret            # Return from interrupt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Resuming execution==&lt;br /&gt;
&lt;br /&gt;
Interrupts can be renabled at the point of returning from the kernel by modifying ssr in sp[2]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldw r11, sp[2]    # Load ssr into r11&lt;br /&gt;
ldc r10, SR_IEBLE # (0x2)&lt;br /&gt;
or  r11, r11, r10 # Set SR_IEBLE bit&lt;br /&gt;
stw r11, sp[2]    # Save the modified value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although the pc is pre-incremented, so that it always holds the address of the next instruciton to execute, when an interrupt occurs, it remains at the address of the current instruction. Because of this, the program counter needs to be manually incremented before returning from an interrupt, except in two cases. &lt;br /&gt;
&lt;br /&gt;
The first is when the interrupted instruction was paused for some reason such as waiting on a channel input. This can be check by inspecting the WAITING bit in the thread's status register (now in ssr or on the stack):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldw r10, sp[2]     # Load ssr into r10&lt;br /&gt;
ldc r9, SR_WAITING # (0x40)&lt;br /&gt;
and r10, r10, r9   # Mask off the WAITING bit&lt;br /&gt;
eq r10, r10, r9    # Check if it was set&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second case is when another interrupt is generated and waiting while a previous one is beging handled, so that on exit from the handler, the next interrupt is immediately generated and entry to the handler caused before the original waiting instruction is executed. In this case, it is not necessary to increment the pc again before returining from the handler. One way to solve this problem is to compare the spc value to another saved pc vlaue (at dp[_pc]), which is updated only when there is a change:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ldw r11, sp[1]&lt;br /&gt;
ldw r10, dp[_pc]&lt;br /&gt;
eq  r11, r11, r10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enabling interrupts==&lt;br /&gt;
&lt;br /&gt;
When the source has been configured, the interrupt handler set and you are ready to receive interrupts, the status register of the thread must be set using SETSR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clrsr SR_EEBLE # If events are enabled, clear this bit&lt;br /&gt;
setsr SR_IEBLE # Enable interrupts&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Things to be aware of=&lt;br /&gt;
&lt;br /&gt;
* Receiving on a channel with interrupts or events enabled will cause an ILLEGAL_RESOURCE exception. Disable events and interrupts before attempting to use a channel for input.&lt;/div&gt;</description>
			<pubDate>Mon, 02 Aug 2010 11:05:23 GMT</pubDate>			<dc:creator>Jamie</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Interrupts</comments>		</item>
		<item>
			<title>PiXC</title>
			<link>http://www.xcore.com/wiki/index.php/PiXC</link>
			<description>&lt;p&gt;Jhrose:&amp;#32;Add PiXC version 0.3 source&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= A proposal for Pi-calculus extensions to XC (PiXC) =&lt;br /&gt;
Copyright © XMOSlinkers jhrose, 2009-2010. Version 0.3. These notes are distributed with the [http://www.gnu.org/copyleft/fdl.html FSF Free Documentation License version 1.3] as a community work. &lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&amp;lt;nowiki&amp;gt;XC [&amp;lt;/nowiki&amp;gt;2] is a general purpose programming language, for expressing parallel algorithms. PiXC is a proposal to extend XC with mobility, using Milner's p&amp;lt;nowiki&amp;gt;i-calculus [&amp;lt;/nowiki&amp;gt;12] as a model. Mobility enables the program function and data control flow to evolve in response to run-time input. &lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
The aims of PiXC are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;To use the pi-calculus [&amp;lt;/nowiki&amp;gt;12&amp;lt;nowiki&amp;gt;] as a model to extend XC [&amp;lt;/nowiki&amp;gt;2] with mobility&lt;br /&gt;
* To formalise (extensions to) a compiler for PiXC that targets XMOS processors&amp;lt;nowiki&amp;gt; [&amp;lt;/nowiki&amp;gt;1]&lt;br /&gt;
&lt;br /&gt;
== Version Control ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
| 0.1&lt;br /&gt;
| Initial proposal for mobile channels and mobile processes (to target a dynamic Operating System). &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 0.2&lt;br /&gt;
| Added initial bindings (mobile:b) and endpoint qualifiers (mobile:01) for mobile channels; added initial bindings for mobile processes. Took design patterns into a new section. Added section for semantics. Added section for case studies. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 0.2.1&lt;br /&gt;
| Reposition PiXC as a general purpose programming language (well-positioned to implement a dynamic Operating System). &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 0.3&lt;br /&gt;
| Described protocols.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;XMOS processors such as the XS-1 core [&amp;lt;/nowiki&amp;gt;1&amp;lt;nowiki&amp;gt;] equip system designers with process-oriented hardware and software building blocks, not unlike the INMOS Transputer [&amp;lt;/nowiki&amp;gt;7&amp;lt;nowiki&amp;gt;] cores which predated them. An XMOS XS-1 is a multi-core processor, each core with its own memory and i/o links [&amp;lt;/nowiki&amp;gt;1&amp;lt;nowiki&amp;gt;]. The cores embed support for a number of services commonly provided by an operating system on general purpose processors, including multi-threading, communication, general purpose i/o, and timers. And like INMOS with Occam [&amp;lt;/nowiki&amp;gt;5&amp;lt;nowiki&amp;gt;], XMOS provide a parallel programming language in XC [&amp;lt;/nowiki&amp;gt;2]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Milner writes [&amp;lt;/nowiki&amp;gt;12&amp;lt;nowiki&amp;gt;], &amp;quot;[pi is]...a calculus for analysing properties of concurrent communicating proceses, which may grow and shrink and move about&amp;quot;. This fluidity takes the pi-Calculus to a level not reached by CCS, CSP or classical automata. Broadly, pi is an extension to CCS that allows the very channels used for inter-process communication to be passed as communication elements. In communicating a channel, the effect is a dynamic re-mapping of the architecture. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Mobility in the pi-calculus [&amp;lt;/nowiki&amp;gt;12&amp;lt;nowiki&amp;gt;] can be used to express parallel algorithms, and Occam 2.1 [&amp;lt;/nowiki&amp;gt;5&amp;lt;nowiki&amp;gt;] has been extended with elements of mobility in Occam-pi [&amp;lt;/nowiki&amp;gt;9&amp;lt;nowiki&amp;gt;], so these ideas might be usefully added to XC [&amp;lt;/nowiki&amp;gt;2&amp;lt;nowiki&amp;gt;]. PiXC makes programming with the Pi-calculus accessible and familiar, by modestly extending the XC [&amp;lt;/nowiki&amp;gt;2] programming language. These extensions allow mobile processes and channels to be declared and have a language semantics. &lt;br /&gt;
&lt;br /&gt;
=== Where we were ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;From Barron's concept for the transputer [&amp;lt;/nowiki&amp;gt;6&amp;lt;nowiki&amp;gt;] that &amp;quot;a calculus is likely to take the form of a program language, which has primitive operations enabling communication between parallel processes&amp;quot;, the relationship between Occam and CSP was exploited heavily by INMOS. From its beginning [&amp;lt;/nowiki&amp;gt;3&amp;lt;nowiki&amp;gt;] Hoare's CSP postulated &amp;quot;...that input and output are basic primitives of programming and that parallel composition of communicating sequential processes is a fundamental program structuring method.&amp;quot; Over time CSP evolved into a model for concurrency [&amp;lt;/nowiki&amp;gt;4] which tests processes against logical specifications (e.g. failures and trace semantics), when Occam took-up the software baton. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Independently of and at about the same time as CSP emerged, and in response to a critique of von-Neumann automata, CCS [&amp;lt;/nowiki&amp;gt;11&amp;lt;nowiki&amp;gt;] surfaced with the assertion that &amp;quot;communication and concurrency are complementary notions&amp;quot; CCS theories of observational equivalence test process automata against each other at their communication ports. This provides a complementary viewpoint to testing logical specifications and properties, and is a good fit with Barron's ideas of a component [&amp;lt;/nowiki&amp;gt;6] &amp;quot;The transputer focuses interest on the transfer of information across a boundary, rather than on the processing of information within that boundary.&amp;quot; &lt;br /&gt;
&lt;br /&gt;
=== Where we are ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Aside from influential ideas, several of which have re-emerged in different forms, Occam has brought about neither significant developments in Operating System Architecture nor a compelling reason for industry to make the costly transition to parallel programming en masse. However, the ideas continue to evolve and nowadays the Occam mantel lies with KroC [&amp;lt;/nowiki&amp;gt;8&amp;lt;nowiki&amp;gt;] and Occam-pi [&amp;lt;/nowiki&amp;gt;9]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;While the XMOS architecture makes it practical to use software to perform many functions that are traditionally implemented in hardware, transition to the new technology could be made more widespread through a general purpose programming language that can express mobile algorithms, i.e. ones in which the data flow and control flow change dynamically in response to system input. And it is with the pi-calculus [&amp;lt;/nowiki&amp;gt;12] successor to CCS, where processes can migrate and channels themselves can be passed between processes, that a significant theoretical breakthrough has been made, so that instead of a static architecture we have a dynamic model. &lt;br /&gt;
&lt;br /&gt;
=== Where we want to be ===&lt;br /&gt;
The aim is to bring the new hardware and theoretical advances to bear on a mobile programming language, to ease the transition for designers and industry more widely into parallel system design and process-oriented software development, using XMOS processors.&lt;br /&gt;
&lt;br /&gt;
Aside from an entry in [http://en.wikipedia.org/wiki/XCore_XS1-L1 Wikipedia]&amp;lt;nowiki&amp;gt;, &amp;quot;[XMOS] Threads can also use Channels to communicate and synchronise allowing a CSP style of programming&amp;quot;, there is scant detail relating to the formal CSP-basis of XC/XS-1. Whether one will emerge likely depends on any academic gain in &amp;quot;translating&amp;quot; to XC from Occam. And, like the theoretical foundation for Occam-pi [&amp;lt;/nowiki&amp;gt;9&amp;lt;nowiki&amp;gt;] has evolved (by blending elements of the CSP, pi-Calculus and Petri-net models [&amp;lt;/nowiki&amp;gt;10]), we can adapt a model best-suited for expressing mobile algorithms in the pi-calculus to XC. &lt;br /&gt;
&lt;br /&gt;
==== Fluid architecture ====&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Pi is well-suited for modelling internets [&amp;lt;/nowiki&amp;gt;12]; consider an internet (TCP/IP) server that accepts socket connection requests at a well-known address, and spawns a child process to serve each new connection concurrently. Pi is also well-suited for general purpose programming and expressing algorithms; t&amp;lt;nowiki&amp;gt;he dynamic communication of mobile channels and mobile processes through channels enables the function and data control flow to evolve in response to run-time events [&amp;lt;/nowiki&amp;gt;10]. &lt;br /&gt;
&lt;br /&gt;
= Constructs =&lt;br /&gt;
Existing operational constructs in XC/XS-1 required to implement mobility are first identified, then new syntactic constructs for XC are proposed based upon Pi-calculus semantics. &lt;br /&gt;
&lt;br /&gt;
== Operational constructs ==&lt;br /&gt;
PiXC requires operational constructs in the XS-1 in order to migrate runnable processes and to allocate dynamic channel endpoints. &lt;br /&gt;
&lt;br /&gt;
=== Runnable processes ===&lt;br /&gt;
The XS-1 instruction set provides for runnable processes through thread allocation and freeing, which is commonly accessed using the XC PAR construct. This operates quite distinctly from a ''fork'' in UNIX, and requires code for the process entry point to be statically linked. A process is run when code and data pointers are loaded into a set of registers, which are presented to the XS-1 scheduler. And a process terminates on return (or join), when its register set is freed. &lt;br /&gt;
&lt;br /&gt;
=== Dynamic channels ===&lt;br /&gt;
Dynamic channels are those channel endpoint resources which are allocated to a process, and eventually freed, for which XS-1 instructions and registers are provided. &lt;br /&gt;
&lt;br /&gt;
== New constructs ==&lt;br /&gt;
New syntactic constructs are needed to program mobility in PiXC. &lt;br /&gt;
&lt;br /&gt;
=== Mobile processes ===&lt;br /&gt;
Mobile processes are those which migrate, to run at different locations at different times. To be mobile, rather than just invoked in the accepted way, a process has to preserve some state and provide various function entry points, which suggests a mobile context operating entirely within the process. And to be safe, a process has to be sent through a channel to a new location. &lt;br /&gt;
&lt;br /&gt;
==== Applications ====&lt;br /&gt;
Consider a dynamic master-slave scenario, where the master measures runtime performance for some application (we don't say how this measurement works) and decides to run a mobile slave process to take some of the workload on a new processor. &lt;br /&gt;
&lt;br /&gt;
Consider a dynamic device driver, where a runtime event is input and a mobile driver process is run to service it. &lt;br /&gt;
&lt;br /&gt;
==== Declarations ====&lt;br /&gt;
A mobile process is a function declared with the ''mobile'' qualifier. This provides a guide to the compiler in scoping both a ''mobile'' code segment and process member variables. &lt;br /&gt;
&lt;br /&gt;
 mobile void p0( chanend out, chanend in )    // p0 is a qualified function&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In general the ''mobile'' qualifier has no effect on the function body operational semantics, or on any nested function calls; however, there are certain restrictions on code and data scope which follow. &lt;br /&gt;
&lt;br /&gt;
A mobile process cannot be invoked like a normal function. &lt;br /&gt;
&lt;br /&gt;
 int f( chanend top0, chanend fromp0 )&lt;br /&gt;
 {&lt;br /&gt;
     p0( fromp0, top0 );    // compiler error, cannot invoke mobile process&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Rather, before a mobile process is run, it first has to be received along a channel by a running process context (see  2.2.1.5 ), following which a new thread (runnable process) is scheduled. &lt;br /&gt;
&lt;br /&gt;
==== Mobile context ====&lt;br /&gt;
Mobile context refers to the scope of static variables and functions accessed by a mobile process. The compilation must arrange storage for a mobile process to enable its member functions and data to reside in different XS-1 core memories at different times. &lt;br /&gt;
&lt;br /&gt;
===== Member variables =====&lt;br /&gt;
Process member variables maintain state across migrations. In particular they support mobile processes being communicated along channels, to resume at a new future location and context. &lt;br /&gt;
&lt;br /&gt;
There are no new syntactic qualifiers for mobile process member variables. The static keyword serves in the usual way, so that member variables are taken to lie within ''mobile'' process scope. &lt;br /&gt;
&lt;br /&gt;
 mobile void p1( chanend out, chanend in )&lt;br /&gt;
 {&lt;br /&gt;
     mobile static int i = 0;    // i is a static int in mobile scope&lt;br /&gt;
     mobile static timer t;        // t is a static timer in mobile scope&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The ''mobile'' qualifier on static variables would not be written by programmers; it shows how the compiler needs to allocate storage for member variables, as if it had been written. The compiler may rename the member variables to qualify the mobile context: p1::i, p1::t, p1::in and p1::out, which is not exposed as syntax the programmer would write. &lt;br /&gt;
&lt;br /&gt;
===== Non-member variables =====&lt;br /&gt;
Variables nested within a mobile process without the static qualifier are just taken as temporary automatic (stack) variables. &lt;br /&gt;
&lt;br /&gt;
===== Member functions =====&lt;br /&gt;
Process member functions are those referenced within a ''mobile'' process scope. In particular they support mobile processes being communicated along channels, to run at a new future location.&lt;br /&gt;
&lt;br /&gt;
There are no new syntactic qualifiers for mobile process member functions. The static keyword serves to declare member functions in a new way (for XC) within ''mobile'' process scope. &lt;br /&gt;
&lt;br /&gt;
 mobile void p2( chanend out, chanend in )&lt;br /&gt;
 {&lt;br /&gt;
     mobile static int f( );     // f is a static function in mobile scope&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The ''mobile'' qualifier on static function declarations would not be written by programmers; it shows how the compilation needs to allocate a code segment for member functions, as if it had been written. The compiler may rename member functions to qualify the mobile context: p2::f. &lt;br /&gt;
&lt;br /&gt;
Member functions themselves are written as static functions at file level, with no further qualifiers. &lt;br /&gt;
&lt;br /&gt;
 mobile static int f( void )&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The ''mobile'' qualifier would not be written by programmers; rather the compiler always assumes it is inherited if and only if a static function is referenced by a mobile process. &lt;br /&gt;
&lt;br /&gt;
===== Nested member variables =====&lt;br /&gt;
Follows as  2.2.1.3.1 &amp;lt;nowiki&amp;gt;; a &amp;lt;/nowiki&amp;gt;''mobile'' qualifier on static variables would not be written by programmers but is assumed by the compiler when a nested function inherits the ''mobile'' qualifier. &lt;br /&gt;
&lt;br /&gt;
===== Nested member functions =====&lt;br /&gt;
Follows as  2.2.1.3.3 &amp;lt;nowiki&amp;gt;; a &amp;lt;/nowiki&amp;gt;''mobile'' qualifier on static functions would not be written by programmers; but the referenced function should be declared within mobile process scope. The source code:&lt;br /&gt;
&lt;br /&gt;
 mobile void p3( chanend out, chanend in )    // p3 is a mobile process&lt;br /&gt;
 {&lt;br /&gt;
     int i;            // i is an automatic (stack) int&lt;br /&gt;
     static int f( );         // f is a static function in process scope&lt;br /&gt;
     static int g( );         // g is a static function in process scope&lt;br /&gt;
     i = f( );            // i holds the result of f of g&lt;br /&gt;
 }&lt;br /&gt;
 static int f( void )&lt;br /&gt;
 {&lt;br /&gt;
     return( g( ));        // result is value of f of g&lt;br /&gt;
 }&lt;br /&gt;
 static int g( void )&lt;br /&gt;
 {&lt;br /&gt;
     return( 0 );        // result is value of g&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===== Non-member functions =====&lt;br /&gt;
There is no such thing as a non-member function. A non-static function cannot be called within ''mobile'' process scope, and results in a compilation error. &lt;br /&gt;
&lt;br /&gt;
 mobile void p4( chanend out, chanend in )&lt;br /&gt;
 {&lt;br /&gt;
     int f( );     // compiler error, function needs static in mobile context&lt;br /&gt;
     g( );        // compiler warning, function g not declared in mobile context&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The reason for this threefold: to allow the compiler to treat file-scope and process-scope in similar yet distinct ways; to avoid the compiler having to search through other compiled units to locate required code; and to prevent the need for multiple (and hence incoherent) copies of data. For the latter, consider if a function, ''g'', is both called by a mobile process and also called elsewhere by a plain function, then it would be necessary to store two copies of ''g'' member variables, as the copy for the mobile process may be communicated into a remote core memory. &lt;br /&gt;
&lt;br /&gt;
Note the caveat that library functions cannot be called within mobile process scope (unless the whole mobile process and its members are compiled into the same library unit). &lt;br /&gt;
&lt;br /&gt;
===== Initial binding =====&lt;br /&gt;
Unless otherwise received, mobile processes are initially bound (as if they had been received) by passing mobile processes as parameters to process threads. Here ''myThread'' is a function that is run as a process (from a ''par'' statement). &lt;br /&gt;
&lt;br /&gt;
 void myThread( mobile p1 )&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The compiler will check each mobile process is given at most one initial binding. If no initial binding is provided for a mobile process, the program may deadlock as no running thread would ever receive or be able to send the mobile; the compiler could issue a warning in this case. (This is made more clear in the case studies in section  5.1.2 .)&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
A mobile process is declared precisely to enable its communication along a channel, for execution by a receiving process context as a new thread. &lt;br /&gt;
&lt;br /&gt;
The top-level mobile process is sent as a unit. Here, ''q0'' is a function running in the source process context, where it is assumed ''p1'' is currently bound. &lt;br /&gt;
&lt;br /&gt;
 void q0( chanend c )&lt;br /&gt;
 {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;c &amp;lt;: p1;&amp;lt;/nowiki&amp;gt;    // p1 is sent along channel c; its state ceases to exist in&lt;br /&gt;
             // the context of q0 process, and its thread is terminated&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There is no new syntax, and the existing communication output primitive serves. When a mobile process is sent, a destructor may be called and its state goes out of context in ''q0''. &lt;br /&gt;
&lt;br /&gt;
At runtime the compiler will cause the (fully qualified) member variables to be sent as a single packet or structure (or Occam 2.1 style protocol, see  2.2.3 ) to the receiving process. &lt;br /&gt;
&lt;br /&gt;
At buildtime, where it is communicated, the linker will link the object code for a mobile process with each processor's executable unit (so the code itself is not sent at runtime), and allocate space to receive the mobile process member variables. &lt;br /&gt;
&lt;br /&gt;
==== Receiving ====&lt;br /&gt;
Until a mobile process is received (into a destination process context) no valid state exists for it. A mobile process is received by a destination process along a channel; the top-level unit as a whole is received. Here, ''q1'' is a function running in the receiving destination process context. &lt;br /&gt;
&lt;br /&gt;
 void q1( chanend c )&lt;br /&gt;
 {&lt;br /&gt;
     chan i, o;&lt;br /&gt;
     c :&amp;gt; p1( o, i );    // p1 is received along channel c; &lt;br /&gt;
                 // its state exists in the context of q1 process, &lt;br /&gt;
                 // bound to the local chanends,&lt;br /&gt;
                 // and p1 runs concurrently as a new thread&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There is no new syntax, and the existing communication input primitive serves. Once a mobile process is received, a constructor may be called and its state comes into context; this includes binding its input and output chanends to local channels. &lt;br /&gt;
&lt;br /&gt;
Rather than a free variable name, the input parameter is the bound mobile process name; this defines the data structure received, being the process member variables. &lt;br /&gt;
&lt;br /&gt;
The ''p1'' state remains valid for the duration of the receiving process context, after which a mobile process destructor may be called, which includes un-binding the local chanends. If ''p1'' should persist beyond the lifetime of the destination process context, it should be communicated to another process before this destination process terminates.&lt;br /&gt;
&lt;br /&gt;
=== Mobile channels ===&lt;br /&gt;
Mobile channels are those which migrate, to bind with different endpoints at different times. &lt;br /&gt;
&lt;br /&gt;
To be mobile, rather than just used in the accepted way, a channel has first to be emptied before migrating. And to be safe, a channel has to be sent from a source process through a channel, possibly itself, to a destination process. Once sent, the source process can no longer access the migrated channel; and the destination process can only access the migrated channel once received. &lt;br /&gt;
&lt;br /&gt;
==== Applications ====&lt;br /&gt;
Consider a dynamic master-slave example, where the master measures runtime performance for some algorithm (we don't say how this measurement works) and decides to send a channel (endpoint) to a slave process on some other processor for it to take some of the workload. &lt;br /&gt;
&lt;br /&gt;
Consider a dynamic device driver, where a runtime event is input and a channel (endpoint) is sent to a driver process for it to service the event. &lt;br /&gt;
&lt;br /&gt;
==== Declarations ====&lt;br /&gt;
New syntax declares mobile channels and mobile chanends. &lt;br /&gt;
&lt;br /&gt;
===== channel =====&lt;br /&gt;
A mobile channel is a channel declared with the ''mobile'' qualifier. This provides a guide to the compiler for allocating and binding channel endpoints. &lt;br /&gt;
&lt;br /&gt;
 chan mobile c;        // c is a qualified channel&lt;br /&gt;
&lt;br /&gt;
A mobile channel can be used at global level by a sequential process, or, unlike a conventional channel, passed as an argument to multiple processes in a ''PAR'' statement. This allows the compiler to know which contexts the channel may bind in. &lt;br /&gt;
&lt;br /&gt;
 chan mobile data;&lt;br /&gt;
 par&lt;br /&gt;
 {&lt;br /&gt;
     procA( data );&lt;br /&gt;
     procB( data );&lt;br /&gt;
     procC( data );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In general the mobile qualifier has no effect on a channel semantics as a point-to-point pipe; rather it extends endpoints with variable-like semantics, allowing them to be dynamically (re-)bound. &lt;br /&gt;
&lt;br /&gt;
===== chanend =====&lt;br /&gt;
Mobile endpoints are bound in two cases: when a mobile channel is input by a destination process; or when a processes fixes it, by omitting the ''mobile'' qualifier from its definition.&lt;br /&gt;
&lt;br /&gt;
Channel endpoints are passed into functions as parameters. The ''mobile'' qualifier is used when declaring a mobile channel endpoint in a function scope. &lt;br /&gt;
&lt;br /&gt;
 void x0( chanend mobile c )        // c is not bound on entry to x0&lt;br /&gt;
 {                        // (it may have been bound by the caller)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== Mobile context ====&lt;br /&gt;
The ''mobile'' qualifier is used by the compiler to allocate storage space for channel endpoints, but not to bind them. The compiler may rename mobile channels to qualify the mobile context: x0::c. &lt;br /&gt;
&lt;br /&gt;
===== constructor =====&lt;br /&gt;
The compiler may call channel (endpoint) constructor functions in two different cases: on entry to a function if the channel is fixed, and if ''c'' is input communicated. &lt;br /&gt;
&lt;br /&gt;
 void x1( chanend c )        // c is bound (fixed) on entry to x1&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Without a ''mobile'' qualifier, x1::c is fixed (bound), even if the endpoint passed in is qualified. &lt;br /&gt;
&lt;br /&gt;
===== Initial binding =====&lt;br /&gt;
Unless otherwise fixed, unbound chanend points are initially bound (as if they had been received) by further qualifying the function definition of a mobile channel with ''mobile:b''. &lt;br /&gt;
&lt;br /&gt;
 void x2( chanend mobile:b c )    // c is initially bound on entry to x2&lt;br /&gt;
 {                        // (but otherwise behaves as a mobile)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Each channel has exactly two endpoints that can be fixed or initially bound. The compiler will check that the allowed endpoints are initially bound or fixed. &lt;br /&gt;
&lt;br /&gt;
===== destructor =====&lt;br /&gt;
The compiler may call channel (endpoint) destructor functions in two different cases: on exit from a function, where the channel endpoint may no longer be bound (once it passes out of scope); and if ''c'' is output communicated, where the channel is always unbound. &lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
Mobile channels may be sent from a source process to a destination, communicated along a channel, to re-bind with the destination process. &lt;br /&gt;
&lt;br /&gt;
 void x3( chanend d, chanend mobile c )&lt;br /&gt;
 {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;d &amp;lt;: c;&amp;lt;/nowiki&amp;gt;    // mobile channel endpoint c is sent along channel d,&lt;br /&gt;
             // its destructor unbinds c from the process context of x3&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There is no new syntax, and the existing communication output primitive serves. Once a channel is sent, an (endpoint) destructor may be called and the channel is unbound. &lt;br /&gt;
&lt;br /&gt;
===== Sending itself =====&lt;br /&gt;
A mobile channel may be sent from one process to another along itself, to bind at a new endpoint. &lt;br /&gt;
&lt;br /&gt;
 void x4( chanend mobile c )&lt;br /&gt;
 {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;c &amp;lt;: c;&amp;lt;/nowiki&amp;gt;    // mobile channel endpoint c is sent along channel c,&lt;br /&gt;
             // its destructor unbinds c from the process context of x4&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There is no new syntax, and the existing communication output primitive serves. The compiler will cause the channel endpoint to be sent. Once a channel is sent, an (endpoint) destructor may be called and the channel is unbound. &lt;br /&gt;
&lt;br /&gt;
Sending a channel along itself is useful if you consider a master-slave process relationship, in which the master sends a channel to a slave process for servicing and when that slave is done it returns the channel (see  3.2.2 ). &lt;br /&gt;
&lt;br /&gt;
==== Receiving ====&lt;br /&gt;
Mobile channels may be received by a destination process from a source, communicated along channels, to bind at a new endpoint. &lt;br /&gt;
&lt;br /&gt;
 void y0( chanend d, chanend mobile e )    // e is not bound on entry to y0&lt;br /&gt;
 {&lt;br /&gt;
     d :&amp;gt; e;    // mobile channel endpoint e is received along channel d,&lt;br /&gt;
             // when its constructor is called and e is bound&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There is no new syntax, and the existing communication input primitive serves. The chanend ''e'' is within scope from the local function declaration, ''y0'', but unbound. The chanend ''e'' will be able to receive valid input only after it is itself received in a channel communication. On receipt, an (endpoint) constructor may be called and the channel ''e'' is bound; after which ''e'' is able to receive valid input. &lt;br /&gt;
&lt;br /&gt;
===== Receiving itself =====&lt;br /&gt;
Any mobile channel (endpoint) can input to itself. The new input value overwrites the former value with immediate effect. &lt;br /&gt;
&lt;br /&gt;
 void y1( chanend d, chanend mobile e )    // e is not bound on entry to y1&lt;br /&gt;
 {&lt;br /&gt;
     d :&amp;gt; e;    // mobile channel endpoint e is received on d and bound&lt;br /&gt;
     e :&amp;gt; e;    // mobile channel endpoint e is received on e and re-bound&lt;br /&gt;
     d :&amp;gt; d;    // compiler error, received channel is not mobile (or fixed)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This allows the compiler to treat channel scope in a consistent way, in an extended variable-like semantics.&lt;br /&gt;
&lt;br /&gt;
=== Protocols ===&lt;br /&gt;
As mobile processes and mobile channels are developed and re-used, maintaining correct data exchange between processes can become a source of errors. A ''protocol''&amp;lt;nowiki&amp;gt; can be used to specify the data structure that is communicated over a channel. This can be used with both mobile and plain (non-mobile) channels to enable compiler checking for data exchange. The idea is based on the protocol found in Occam 2.1 [&amp;lt;/nowiki&amp;gt;5], or perhaps more like Pascal records. &lt;br /&gt;
&lt;br /&gt;
==== Channel context ====&lt;br /&gt;
A protocol can be used in the context of a channel and chanends. &lt;br /&gt;
&lt;br /&gt;
===== Channel protocol =====&lt;br /&gt;
A channel is qualified with a protocol by specifying a data structure. This provides a guide to the compiler for binding channel endpoints. &lt;br /&gt;
&lt;br /&gt;
 chan c0:int;        // c0 is a channel qualified with a simple protocol&lt;br /&gt;
&lt;br /&gt;
A mobile channel can be similarly qualified with a protocol.&lt;br /&gt;
&lt;br /&gt;
 chan mobile c1:int;    // c1 is a mobile channel qualified with a protocol&lt;br /&gt;
&lt;br /&gt;
The protocol data structure is a container, which is a sequence of data types. A simple protocol contains a single (scalar) data type, such as c0 and c1 above. A complex protocol contains more than one data type in a sequence. &lt;br /&gt;
&lt;br /&gt;
 chan c2:int:char;    // c2 is a channel which communicates a complex protocol&lt;br /&gt;
&lt;br /&gt;
While the definition of a protocol shares similarities with a structure (or class), its elements are not named and cannot be communicated independently of each other. &lt;br /&gt;
&lt;br /&gt;
===== Chanend protocol =====&lt;br /&gt;
A channel endpoint (mobile or otherwise) can be bound with a protocol.&lt;br /&gt;
&lt;br /&gt;
 void x0( chanend c:int )        // c is bound on entry to x0 by a protocol&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The compiler shall perform static checks on the protocol data type consistency of a channel declaration, its binding to chanends, and its use within process and function scope. &lt;br /&gt;
&lt;br /&gt;
==== Protocol types ====&lt;br /&gt;
A protocol is a type of sequence, named using the ''protocol'' keyword.&lt;br /&gt;
&lt;br /&gt;
 protocol p0        // p0 is a named protocol&lt;br /&gt;
 {&lt;br /&gt;
     int:char;        // p0 is a sequence of int then char&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Once a named protocol type is defined, it can be used to qualify a channel or a chanend.&lt;br /&gt;
&lt;br /&gt;
 chan c3:p0;        // c3 uses a complex protocol of type p0&lt;br /&gt;
&lt;br /&gt;
===== Protocol case =====&lt;br /&gt;
A protocol can be constructed by embedding cases to form a named case protocol. &lt;br /&gt;
&lt;br /&gt;
 protocol p1        // p1 is a named case protocol&lt;br /&gt;
 {&lt;br /&gt;
     case int:char;    // p1 is a sequence of either int then char,&lt;br /&gt;
     case int:int;    //    or int then int;&lt;br /&gt;
     case void;        //    or default cases&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The void case supports default processing when no receiving pattern match is wanted; it cannot be sent. &lt;br /&gt;
&lt;br /&gt;
===== Protocol array types =====&lt;br /&gt;
One or more variables of the same type may be combined to form an array.&lt;br /&gt;
&lt;br /&gt;
 protocol p2&lt;br /&gt;
 {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;case unsigned char[10];&amp;lt;/nowiki&amp;gt;        // p2 is a sequence of 10 unsigned chars,&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;case int:char[2];&amp;lt;/nowiki&amp;gt;            //    or an int then 2 chars&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
===== Ambiguity =====&lt;br /&gt;
The compiler may raise a warning or an error if a protocol definition is potentially ambiguous.&lt;br /&gt;
&lt;br /&gt;
 protocol p3&lt;br /&gt;
 {&lt;br /&gt;
     case int:char;&lt;br /&gt;
     case int;        // compiler warning, potential protocol ambiguity&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Static ambiguity occurs when more than one receive case cannot be uniquely decided. A protocol is unambiguous when outputting on a channel bound to a protocol. &lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
Data is sent along channels bound to a protocol using the usual mechanism, with a small extension for sending sequences. The compiler will check the data type sequence used occurs in the channel protocol definition. &lt;br /&gt;
&lt;br /&gt;
 void x5( chanend mobile c:p3 )&lt;br /&gt;
 {&lt;br /&gt;
     int v;&lt;br /&gt;
     char w;&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;c &amp;lt;: v,w;&amp;lt;/nowiki&amp;gt;    // v,w is a sequence of int:char, a case in protocol p3&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;c &amp;lt;: w;&amp;lt;/nowiki&amp;gt;    // compiler error, no such case in protocol&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== Receiving ====&lt;br /&gt;
Data is received along channels bound to a protocol using the channel input mechanism of XC. The compiler will check all possible protocol cases are provided for. For an unnamed protocol a select statement is not required; where one is required for a named case protocol. &lt;br /&gt;
&lt;br /&gt;
 void y2( chanend d:p2 )&lt;br /&gt;
 {&lt;br /&gt;
     int v;&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;unsigned char w[10];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     select&lt;br /&gt;
     {&lt;br /&gt;
         case d :&amp;gt; w;    &amp;lt;nowiki&amp;gt;// w matches unsigned char[10] found in p3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         case d :&amp;gt; v:w;    &amp;lt;nowiki&amp;gt;// v:w matches with the sequence int:char[2] in p3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;In the second case for function y2, type int:char[2] is found in p3 and this is allowed because v:w of type int:char[10] can contain the received data correctly. If the compiler enforces strict type checking then v:w would not match int:char[2], in both array dimension and unsigned-ness. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ambiguous receive =====&lt;br /&gt;
 void y3( chanend mobile e:p3 )&lt;br /&gt;
 {&lt;br /&gt;
     int v;&lt;br /&gt;
     char w;&lt;br /&gt;
     select&lt;br /&gt;
     {&lt;br /&gt;
         case e :&amp;gt; v,w;    // v,w is a sequence of int:char found in p3&lt;br /&gt;
         case e :&amp;gt; v;    // int is found in p3, but possibly&lt;br /&gt;
     }    // compiler error, select statement with ambiguous protocol&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In the case of y3, the compiler cannot determine if more data is expected after the leading int and therefore cannot distinguish the case. &lt;br /&gt;
&lt;br /&gt;
===== Default receive =====&lt;br /&gt;
When a case protocol is defined with a void case, a receiving function can provide a default case for un-matched entries. This allows functions to match a subset of the protocol cases, and discard all others. &lt;br /&gt;
&lt;br /&gt;
 void y4( chanend mobile e:p1 )&lt;br /&gt;
 {&lt;br /&gt;
     int v;&lt;br /&gt;
     char w;&lt;br /&gt;
     select&lt;br /&gt;
     {&lt;br /&gt;
         case e :&amp;gt; v,w;    // v and w contain input values&lt;br /&gt;
         case void&lt;br /&gt;
         {&lt;br /&gt;
             // handle all other input cases (no values known)&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Without a default case, the compiler would generate an error for un-handled protocol cases in y4. &lt;br /&gt;
&lt;br /&gt;
If within a source file the scope of a protocol is fully contained and any particular case is never sent, then an omitted receive case can be cast away silently or just issued with a warning. This is allowed because the suspect case will never be communicated. &lt;br /&gt;
&lt;br /&gt;
= Design patterns =&lt;br /&gt;
Several design patterns can illustrate how to use mobile processes and channels. These also provide a further insight into the extended PiXC syntax and its meaning. &lt;br /&gt;
&lt;br /&gt;
== Mobile processes ==&lt;br /&gt;
Mobile processes allow services to migrate, such that the program control flow is changed. But for such powerful concepts, they are actually fairly simple building blocks. A crucial concept of processes is statefulness, so that even after migrating (from one hardware processor to another) they can resume where they left off. &lt;br /&gt;
&lt;br /&gt;
=== State machine pattern ===&lt;br /&gt;
The state machine pattern is used to enable a mobile process to resume execution after migrating. There are no special constructs required for a state machine; rather, a design pattern using a static variable with process-qualified scope serves. &lt;br /&gt;
&lt;br /&gt;
 mobile void p0( chanend out, chanend in )&lt;br /&gt;
 {&lt;br /&gt;
     static int p0_state = 0;&lt;br /&gt;
     switch( p0_state )&lt;br /&gt;
     {&lt;br /&gt;
         case 0 :&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
         break;&lt;br /&gt;
         ...&lt;br /&gt;
         default :&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Roaming pattern ===&lt;br /&gt;
In the roaming pattern, mobile processes migrate between contexts as a function of their data- or event-driven processing. Here, ''roam0'' is a function in some process context. &lt;br /&gt;
&lt;br /&gt;
 void roam0( chanend c, chanend i, chanend o )&lt;br /&gt;
 {&lt;br /&gt;
     int t = 1;            // initially assume task 1&lt;br /&gt;
     c :&amp;gt; p1( o, i );        // wait to receive mobile process p1&lt;br /&gt;
     for( ; t &amp;gt; 0; )&lt;br /&gt;
     {&lt;br /&gt;
                     // calculate next task, t, on p1 state&lt;br /&gt;
         switch( t )&lt;br /&gt;
         {&lt;br /&gt;
             case 1:&lt;br /&gt;
             {&lt;br /&gt;
                     // perform task t1, interacting with p1&lt;br /&gt;
             }&lt;br /&gt;
             break;&lt;br /&gt;
             ...&lt;br /&gt;
             default :&lt;br /&gt;
             {&lt;br /&gt;
                     // not a task for roam0 in this context&lt;br /&gt;
                 &amp;lt;nowiki&amp;gt;c &amp;lt;: p1( o, i );&amp;lt;/nowiki&amp;gt;    // migrate mobile process p1&lt;br /&gt;
                 t = 0;    // exit loop&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Mobile channels ==&lt;br /&gt;
Mobile channels allow data to be shared by processes such that the program data flow follows data event processing. Sharing data allows processes to be small and purposeful, handing over channels (and the data that passes through them) to other processes in turn. This is a powerful concept, in which data flows over a network of inter-connected processes, and yet mobile channels are fairly simple building blocks. &lt;br /&gt;
&lt;br /&gt;
=== Master-Slave pattern ===&lt;br /&gt;
In the case of a master-slave process arrangement, each master-slave share a ''control'' channel over which will be communicated a ''data'' channel. A seperate source process outputting on the ''data'' channel does not (need to) know which slave it is connected with. This pattern seperates control flow on fixed channels from the data flow over mobile channels. Note master initially binds mobile channel data, before it is able to send it; the compiler checks each chanend is fixed or initially bound once. &lt;br /&gt;
&lt;br /&gt;
 chan controlA, controlB;&lt;br /&gt;
 chan mobile data;&lt;br /&gt;
&lt;br /&gt;
 par&lt;br /&gt;
 {&lt;br /&gt;
     source( data );&lt;br /&gt;
     master( controlA, controlB, data );&lt;br /&gt;
     slaveA( controlA, data );&lt;br /&gt;
     slaveB( controlB, data );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void master( chanend A, chanend B, chanend mobile:b D )&lt;br /&gt;
 {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;A &amp;lt;: D;&amp;lt;/nowiki&amp;gt;        // give data channel D endpoint to slaveA&lt;br /&gt;
     A :&amp;gt; D;        // take data channel D endpoint from slaveA&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;B &amp;lt;: D;&amp;lt;/nowiki&amp;gt;        // give data channel D endpoint to slaveB&lt;br /&gt;
     B :&amp;gt; D;        // take data channel D endpoint from slaveB&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void slaveA( chanend ctrl, chanend mobile data )&lt;br /&gt;
 {&lt;br /&gt;
     ctrl :&amp;gt; data;    // wait for a worker channel from master&lt;br /&gt;
                 // process i/o on data&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;ctrl &amp;lt;: data;&amp;lt;/nowiki&amp;gt;    // return data to master&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void slaveB( chanend ctrl, chanend mobile data )&lt;br /&gt;
 {&lt;br /&gt;
     ctrl :&amp;gt; data;    // wait for a worker channel from master&lt;br /&gt;
                 // process i/o on data&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;ctrl &amp;lt;: data;&amp;lt;/nowiki&amp;gt;    // return data to master&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void source( chanend out )        // out is fixed&lt;br /&gt;
 {&lt;br /&gt;
     // perform i/o on out&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Processes ''master'', ''slaveA'', ''slaveB'' and ''source'' may reside on different processor cores and memories. &lt;br /&gt;
&lt;br /&gt;
=== Self-Send pattern ===&lt;br /&gt;
A channel can be received, and when done with, sent along itself to the peer process. This pattern mixes both control flow and data flow on mobile channels. (However, it doesn't do away with the need for a control channel to send the initial mobile endpoint.) &lt;br /&gt;
&lt;br /&gt;
 chan controlA, controlB;&lt;br /&gt;
 chan mobile dandc;&lt;br /&gt;
&lt;br /&gt;
 par&lt;br /&gt;
 {&lt;br /&gt;
     selfsend( controlA, controlB, dandc, dandc );&lt;br /&gt;
     slaveA( controlA, dandc );&lt;br /&gt;
     slaveB( controlB, dandc );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void selfsend( &lt;br /&gt;
   chanend A, &lt;br /&gt;
   chanend B, &lt;br /&gt;
   chanend dac0,            /* fix endpoint0 of dandc */&lt;br /&gt;
   chanend mobile:1b dac1   /* specify which endpoint, and initial bind */&lt;br /&gt;
   )&lt;br /&gt;
 {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;A &amp;lt;: dac1;&amp;lt;/nowiki&amp;gt;        &amp;lt;nowiki&amp;gt;// give mobile channel dandc[1] to slaveA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
                 &amp;lt;nowiki&amp;gt;// process i/o on dandc[0] with slaveA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     dac0 :&amp;gt; dac1;    &amp;lt;nowiki&amp;gt;// receive mobile channel into dandc[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;B &amp;lt;: dac1;&amp;lt;/nowiki&amp;gt;        &amp;lt;nowiki&amp;gt;// give mobile channel dandc[1] to slaveB&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
                 &amp;lt;nowiki&amp;gt;// process i/o on dandc[0] with slaveB&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     dac0 :&amp;gt; dac1;    &amp;lt;nowiki&amp;gt;// receive mobile channel into dandc[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void slaveA( chanend ctrl, chanend mobile dac )&lt;br /&gt;
 {&lt;br /&gt;
     ctrl :&amp;gt; dac;    // wait for a mobile channel from master&lt;br /&gt;
                 // process i/o on dac&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;dac &amp;lt;: dac;&amp;lt;/nowiki&amp;gt;        // return dac&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void slaveB( chanend mlink, chanend mobile c )&lt;br /&gt;
 {&lt;br /&gt;
     ctrl :&amp;gt; dac;    // wait for a mobile channel from master&lt;br /&gt;
                 // process i/o on dac&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;dac &amp;lt;: dac;&amp;lt;/nowiki&amp;gt;        // return dac&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;The two endpoints dandc[0] and dandc[1] are identified, in this case by explicitly binding dac1 to &amp;lt;/nowiki&amp;gt;chanend mobile:1&amp;lt;nowiki&amp;gt; so that defacto the compiler will bind the remaining endpoint dandc[0] to dac0 which also happens to be fixed. The endpoint dac1 is also initially bound to &amp;lt;/nowiki&amp;gt;''selfsend''. The processes ''master'', ''slaveA'' and ''slaveB'' may reside on different processors. &lt;br /&gt;
&lt;br /&gt;
=== Pipeline pattern ===&lt;br /&gt;
The pipeline pattern is analogous to data passing through a processor pipeline. In this pattern for mobile channels, data passes through a set of processes by communicating a mobile channel between them. When it holds the mobile channel each process performs some function(s) on the data input from it, before deciding which process is next to receive the mobile channel. Unlike a static arrangement, the sequence of processes does not have to be pre-determined. &lt;br /&gt;
&lt;br /&gt;
A variation on the master-slave pattern, prior to returning the mobile channel, each slave first sends a value along it to identify which slave process should be the next receiver. &lt;br /&gt;
&lt;br /&gt;
 chan controlA, controlB;&lt;br /&gt;
 chan mobile data;&lt;br /&gt;
&lt;br /&gt;
 par&lt;br /&gt;
 {&lt;br /&gt;
     pipeline( controlA, controlB, data, data );&lt;br /&gt;
     slaveA( controlA, data );&lt;br /&gt;
     slaveB( controlB, data );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void pipeline( chanend A, chanend B, chanend D0, chanend mobile:b1 D1 )&lt;br /&gt;
 {&lt;br /&gt;
     int v = 0;        &amp;lt;nowiki&amp;gt;// initially send server channel D[1] to slaveA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     for( ;; )&lt;br /&gt;
     {&lt;br /&gt;
         switch( v )&lt;br /&gt;
         {&lt;br /&gt;
             case 0:&lt;br /&gt;
             {&lt;br /&gt;
                 &amp;lt;nowiki&amp;gt;A &amp;lt;: D1;&amp;lt;/nowiki&amp;gt;    &amp;lt;nowiki&amp;gt;// give server channel D[1] to slaveA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
             }&lt;br /&gt;
             break;&lt;br /&gt;
             case 1:&lt;br /&gt;
             {&lt;br /&gt;
                 &amp;lt;nowiki&amp;gt;B &amp;lt;: D1;&amp;lt;/nowiki&amp;gt;    &amp;lt;nowiki&amp;gt;// give server channel D[1] to slaveB&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
             }&lt;br /&gt;
             break;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
             &amp;lt;nowiki&amp;gt;// process i/o on D[0] with slave&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
         D0 :&amp;gt; v;    // identity of next slave to receive mobile channel&lt;br /&gt;
         D0 :&amp;gt; D1;    &amp;lt;nowiki&amp;gt;// receive mobile channel into D[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void slaveA( chanend ctrl, chanend mobile d )&lt;br /&gt;
 {&lt;br /&gt;
     int v = 1;    // default next process identity&lt;br /&gt;
     for( ;; )&lt;br /&gt;
     {&lt;br /&gt;
         ctrl :&amp;gt; d;    // wait for a worker channel from master&lt;br /&gt;
&lt;br /&gt;
                 // process i/o on d&lt;br /&gt;
&lt;br /&gt;
                 // calculate v, identity of next receiving process&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;d &amp;lt;: v;&amp;lt;/nowiki&amp;gt;    // send identity of next process in pipeline&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;d &amp;lt;: d;&amp;lt;/nowiki&amp;gt;    // return d&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void slaveB( chanend ctrl, chanend mobile d )&lt;br /&gt;
 {&lt;br /&gt;
     int v = 0;    // default next process identity&lt;br /&gt;
     for( ;; )&lt;br /&gt;
     {&lt;br /&gt;
         ctrl :&amp;gt; d;    // wait for a worker channel from master&lt;br /&gt;
&lt;br /&gt;
                 // process i/o on d&lt;br /&gt;
&lt;br /&gt;
                 // calculate v, identity of next receiving process&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;d &amp;lt;: v;&amp;lt;/nowiki&amp;gt;    // send identity of next process in pipeline&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;d &amp;lt;: d;&amp;lt;/nowiki&amp;gt;    // return d&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Semantics =&lt;br /&gt;
== Informal meaning ==&lt;br /&gt;
The semantics of PiXC can be informally presented, to better understand certain implementation issues.&lt;br /&gt;
&lt;br /&gt;
=== Mobile context ===&lt;br /&gt;
The x::y mobile context for member variables and functions serves as a convenience to denote compiler semantics for mobile processes. It is not parsed as input syntax, and the programmer would not write it. The mobile context for processes does not extend beyond data and function encapsulation, constructors and destructors. &lt;br /&gt;
&lt;br /&gt;
==== Minimal impact ====&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Section A.3 of Programming XC [&amp;lt;/nowiki&amp;gt;2], names and storage, helps to estimate the likely cost of extensions. PiXC should impose the minimal set of changes on XC, that do what is needed. &lt;br /&gt;
&lt;br /&gt;
==== Non-explicit ====&lt;br /&gt;
It is not necessary to introduce (C++-style) classes or namespaces or to explicate a mobile context, and would increase what the XC compiler would have to do anew. Namespaces provide a context for symbols, and group related functions and data spread over several source files or libraries. &lt;br /&gt;
&lt;br /&gt;
==== Issues ====&lt;br /&gt;
A mobile context is needed for the XC compiler to allocate storage space for mobile processes, which are long-lived and can migrate. A mobile context solves several implementation issues, including memory map, liveness, coherency and scalability, amongst others. &lt;br /&gt;
&lt;br /&gt;
===== Memory Maps =====&lt;br /&gt;
The PiXC compiler should generate mobile process object code exactly once. During compilation global variables (or memory allocated to hold them) are fixed offset from dp (register 13). If a mobile context for member variables were omitted, then either:&lt;br /&gt;
&lt;br /&gt;
* the memory maps of different processors would have to be made the same, in order for the common mobile process object code to access member variables,which is wasteful, or&lt;br /&gt;
* the object code would need to be compiled seperately for each processor, in order to access member variables in the different memory maps, which is also wasteful.&lt;br /&gt;
&lt;br /&gt;
By using a mobile context, the compiler can offset member variables with respect to another register, say r11, per thread; or the compiler could treat member variables like far pointers, and go through a jump table; or another method could be used. &lt;br /&gt;
&lt;br /&gt;
===== Liveness =====&lt;br /&gt;
A mobile process is constructed when it is received by a process. Similarly it is destructed when it is sent by a process. If a mobile context for member variables were omitted, each variable would need a 'lifetime' guard, which would need testing, on each and every access by a non-mobile process.&lt;br /&gt;
&lt;br /&gt;
===== Coherency =====&lt;br /&gt;
When a process migrates from a source to a destination processor, its destination data members need to store the values already calculated in the source processor. If a mobile context for member variables were omitted, overwriting them when a mobile is received at the destination processor would appear as a corruption to other processes running on the destination processor.&lt;br /&gt;
&lt;br /&gt;
And running on the new destination processor, changes written by the mobile process to global data would not be visible to other processes running on the original source processor. &lt;br /&gt;
&lt;br /&gt;
The Hoare/Dijkstra multiple-update solution requires a guard on sharedglobal data; accessing a global from parallel processes is guarded in XC at compile time, so only one thread is permitted to write to a global. A mobile context gives a dynamic alternative to this solution.&lt;br /&gt;
&lt;br /&gt;
===== Scalability =====&lt;br /&gt;
PiXC should provide for the future when mobility is extended to heterogenous networks, to avoid the need to change or break existing programs or language features. Using a mobile context solves mobility problems generally, which should scale up to heterogenous processor networks.&lt;br /&gt;
&lt;br /&gt;
= Case Studies =&lt;br /&gt;
Case studies provide more in-depth examples of mobile processes and channels. &lt;br /&gt;
&lt;br /&gt;
== Ethernet ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;The Ethernet case study extends the example in chapter 6.5 of XMOS Programming XC [&amp;lt;/nowiki&amp;gt;2]. Changes to the extended source code are deliberately kept as few as possible, for ease of drawing a direct comparison. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;This case study shows how 2 mobile process transmit clients can share the single ethernet driver without conflict, that mobile processes can act like a semaphore over multiple processors, and member variable state is maintained over mobility. First the text book [&amp;lt;/nowiki&amp;gt;2] code is given (with corrections, and including a dummy program) and second extended versions are given; one with mobile processes and the other using mobile channels. &lt;br /&gt;
&lt;br /&gt;
=== Basic program ===&lt;br /&gt;
 /*&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* Programming XC chapter 6.5&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* A single thread on an XS1 device can be used to implement a full duplex &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;100Mbps Ethernet Media Independent Interface (MII) protocol [2]. This &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; protocol implements the data transfer signals between the link layer and &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; physical device (PHY).&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* The signals are as follows:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  TXCLK is a free running 25MHz clock generated by the PHY.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  TXEN is a data valid signal driven high by the transmitter during frame &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;   transmission.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  TXD carries a nibble of data per clock period from the transmitter to&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;   the PHY.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  RXCLK is a free running clock generated by the PHY.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  RXDV is a data valid signal driven high by the PHY during frame&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;   transmission.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  RXD carries a nibble of data per clock period from the PHY to the&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;   receiver.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* The transmitter starts by sending a preamble of nibbles of value 0x5,&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; followed by two nibbles of values 0x5 and 0xD. The data, which must be in &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; the range of 64 to 1500 bytes, is then transmitted, least significant bit  &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; first, followed by four bytes containing a CRC.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#include&amp;lt;/nowiki&amp;gt;'''&amp;lt;nowiki&amp;gt; &amp;lt;xs1.h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' MORE 0&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' DONE 1&lt;br /&gt;
&lt;br /&gt;
   /* The port TXD performs a 32-to-4 bit serialisation of data onto its pins.  &lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; It is synchronised to the 1-bit port TXCLK and uses the 1-bit port TXEN  &lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; as a ready-out strobe signal that is driven high whenever data is&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; driven.  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''static''' '''port''':32 '''out''' '''buffered''' TXD = XS1_PORT_4B;&lt;br /&gt;
 '''static''' '''port''' '''out''' TXEN = XS1_PORT_1K;&lt;br /&gt;
 '''static''' '''port''' '''in''' TXCLK = XS1_PORT_1J;&lt;br /&gt;
 '''static''' '''port''' '''in''' TXER = XS1_PORT_1L;&lt;br /&gt;
&lt;br /&gt;
   /* The port RXD performs a 4-to-32-bit deserialisation of data from its&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; pins.&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; It is synchronised to the 1-bit port RXCLK and uses the 1-bit port RXDV &lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; as a ready-in strobe signal that causes data to be sampled only when&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; the strobe is high.&lt;br /&gt;
   &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''static''' '''port''':32 '''in''' '''buffered''' RXD = XS1_PORT_4A ;&lt;br /&gt;
 '''static''' '''port''' '''in''' RXDV = XS1_PORT_1I ;&lt;br /&gt;
 '''static''' '''port''' '''in''' RXCLK = XS1_PORT_1H ;&lt;br /&gt;
 '''static''' '''port''' '''out''' RXER = XS1_PORT_1G;&lt;br /&gt;
&lt;br /&gt;
 '''static''' '''clock''' clktx = XS1_CLKBLK_1;&lt;br /&gt;
 '''static''' '''clock''' clkrx = XS1_CLKBLK_2;&lt;br /&gt;
&lt;br /&gt;
 '''static''' '''int''' txerr = 0;&lt;br /&gt;
 '''static''' '''int''' rxerr = 0;&lt;br /&gt;
&lt;br /&gt;
 /* In this configuration, the processor has only to output data once every&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; eight clock periods and does not need to explicitly output the data valid &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; signal.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; miiConfigTransmit defines and configures the ports in this way.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''static''' '''void''' '''miiConfigTransmit'''( &lt;br /&gt;
   '''clock''' clk,&lt;br /&gt;
   '''in''' '''port''' TXCLK,&lt;br /&gt;
   '''buffered''' '''out''' '''port''':32 TXD, &lt;br /&gt;
   '''out''' '''port''' TXEN,&lt;br /&gt;
   '''in''' '''port''' TXER&lt;br /&gt;
   ) &lt;br /&gt;
 {&lt;br /&gt;
   '''configure_clock_src'''( clk, TXCLK );   /* TXCLK provides edges for clk */&lt;br /&gt;
   '''configure_out_port'''( TXD, clk, 0 );   /* TXD clocked by clk, initially 0 */&lt;br /&gt;
   '''configure_out_port'''( TXEN, clk, 0 );  /* TXEN clocked by clk, initially 0 */&lt;br /&gt;
&lt;br /&gt;
     /* TXD to drive TXEN high whenever data is output; initial output 0;&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;* the strobe remains 1 for sizeof( TXD ) clocks */&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''configure_out_port_strobed_master'''( TXD, TXEN, clk, 0 );&lt;br /&gt;
&lt;br /&gt;
   TXER :&amp;gt; txerr;  /* initial state of TXER */&lt;br /&gt;
&lt;br /&gt;
   start_clock( clk );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* In this configuration, the port can sample eight values before the data &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  must be input by the processor, and the processor does not need to &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  explicitly wait for the data valid signal. &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* miiConfigReceive defines and configures the ports in this way.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''static''' '''void''' '''miiConfigReceive'''( &lt;br /&gt;
   '''clock''' clk, &lt;br /&gt;
   '''in''' '''port''' RXCLK,&lt;br /&gt;
   '''buffered''' '''in''' '''port''':32 RXD, &lt;br /&gt;
   '''in''' '''port''' RXDV, &lt;br /&gt;
   '''out''' '''port''' RXER &lt;br /&gt;
   ) &lt;br /&gt;
 {&lt;br /&gt;
   '''configure_clock_src'''( clk, RXCLK );    /* RXCLK provides edges for clk */&lt;br /&gt;
   '''configure_in_port'''( RXD, clk );        /* RXD clocked by clk */&lt;br /&gt;
   '''configure_in_port'''( RXDV, clk );       /* RXDV clocked by clk */&lt;br /&gt;
&lt;br /&gt;
     /* RXD to drive RXDV high whenever data is output;&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;* the strobe remains 1 for sizeof( TXD ) clocks */&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''configure_in_port_strobed_slave'''( RXD, RXDV, clk );&lt;br /&gt;
&lt;br /&gt;
   rxerr = 0;&lt;br /&gt;
   &amp;lt;nowiki&amp;gt;RXER &amp;lt;: rxerr; &amp;lt;/nowiki&amp;gt; /* clear RXER */&lt;br /&gt;
&lt;br /&gt;
   start_clock( clk );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* Configure the receive and transmit ports to the PHY device&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''miiConfigRxTx'''( '''void''' )&lt;br /&gt;
 {&lt;br /&gt;
   miiConfigReceive( clkrx, RXCLK, RXD, RXDV, RXER );&lt;br /&gt;
   miiConfigTransmit( clktx, TXCLK, TXD, TXEN, TXER );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* miiTransmitFrame takes frame data from another thread and outputs it to &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; the MII ports. For simplicity, the error signals and CRC are ignored.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* It first inputs from the channel c the size of the frame in bytes. It then&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; outputs a 32-bit preamble to TXD, which is driven on the pins as nibbles &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; over eight clock periods. On each iteration of the for loop, the next 32  &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; bits of data are then output to TXD for serialising onto the pins. This  &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; gives the processor enough time to get around the loop before the next  &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; block of data must be driven.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''miiTransmitFrame'''( &lt;br /&gt;
   '''out''' '''buffered''' '''port''':32 TXD,&lt;br /&gt;
   '''streaming''' '''chanend''' c&lt;br /&gt;
   )&lt;br /&gt;
 {&lt;br /&gt;
   '''int''' numBytes;&lt;br /&gt;
   '''int''' tailBytes;&lt;br /&gt;
   '''int''' tailBits;&lt;br /&gt;
   '''int''' data;&lt;br /&gt;
&lt;br /&gt;
     /* Input size of next packet */&lt;br /&gt;
   c :&amp;gt; numBytes;&lt;br /&gt;
   tailBytes =( numBytes / 4 );&lt;br /&gt;
   tailBits =( tailBytes * 8 );&lt;br /&gt;
&lt;br /&gt;
     /* Output row of 0x5s followed by 0xD (little endian) */&lt;br /&gt;
   &amp;lt;nowiki&amp;gt;TXD &amp;lt;: 0xD5555555;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     /* Output complete 32-bit words for serialisation */&lt;br /&gt;
   '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt;( numBytes - tailBytes ); i+=4 )&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
     c :&amp;gt; data;    /* input data from client thread */&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;TXD &amp;lt;: data;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
     /* Output partial 32-bits of data for serialisation */&lt;br /&gt;
   '''if'''( 0 != tailBits )&lt;br /&gt;
   {&lt;br /&gt;
     c :&amp;gt; data;   /* input data from client thread */&lt;br /&gt;
&lt;br /&gt;
       /* Output the remaining bits of data that represent valid frame data */&lt;br /&gt;
     partout( TXD, tailBits, data );  /* __builtin partout( ) */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* miiReceiveFrame receives a single error-free frame and outputs it to &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; another thread. For simplicity, the error signal and CRC are ignored.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* The processor waits for the last nibble of the preamble (0xD) to be &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; sampled by the port RXD. The actual data is then received, which is in  &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; the range of 64 to 1500 bytes, least significant nibble first, followed &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; by four bytes containing a CRC. On each iteration of the loop, it waits &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; for either next eight nibbles of data to be sampled for input by RXD or &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; for the data valid signal RXDV to go low.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* XS1 devices provide a single-entry buffer up to 32-bits wide and a 32-bit &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; shift register, requiring up to 64 bits of data being input over two &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; input statements once the data valid signal goes low.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''miiReceiveFrame'''(&lt;br /&gt;
   '''in''' '''buffered''' '''port''':32 RXD, &lt;br /&gt;
   '''in''' '''port''' RXDV,&lt;br /&gt;
   '''streaming''' '''chanend''' c&lt;br /&gt;
   ) &lt;br /&gt;
 {&lt;br /&gt;
   '''int''' dataValid;&lt;br /&gt;
   '''int''' data;&lt;br /&gt;
   '''int''' tail;          /* stores bit-count in last received part-word */&lt;br /&gt;
&lt;br /&gt;
     /* Wait for start of frame */&lt;br /&gt;
   RXD '''when''' pinseq( 0xD ):&amp;gt; '''void'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   RXDV :&amp;gt; dataValid;&lt;br /&gt;
&lt;br /&gt;
     /* Receive frame data /crc */&lt;br /&gt;
   '''do'''&lt;br /&gt;
   {&lt;br /&gt;
     '''select'''&lt;br /&gt;
     {&lt;br /&gt;
       '''case''' RXD :&amp;gt; data :&lt;br /&gt;
       {&lt;br /&gt;
           /* Input next 32 bits of data */&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c &amp;lt;: MORE; &amp;lt;/nowiki&amp;gt;  /* indicate to receiving thread, more data follows */&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c &amp;lt;: data; &amp;lt;/nowiki&amp;gt;  /* send next data word to receiving thread */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''case''' RXDV '''when''' pinseq( 0 ):&amp;gt; dataValid :&lt;br /&gt;
       {&lt;br /&gt;
           /* An effect of using a port’s serialisation and strobing &lt;br /&gt;
            &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; capabilities together is that the ready-in signal may go low  &lt;br /&gt;
            &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; before a full transfer width’s worth of data is received.&lt;br /&gt;
            &amp;lt;nowiki&amp;gt;* Input any bits remaining in port. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
            &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         tail = endin( RXD );  /* __builtin endin( ) */&lt;br /&gt;
&lt;br /&gt;
           /* send remaining data words to receiving thread */&lt;br /&gt;
         '''for'''( '''int''' byte =( tail &amp;gt;&amp;gt; 3 ); byte &amp;gt; 0; byte -= '''sizeof'''( '''int''' )) &lt;br /&gt;
         {&lt;br /&gt;
           RXD :&amp;gt; data;&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;c &amp;lt;: MORE;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;c &amp;lt;: data;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
           /* indicate to receiving thread, end of data and how many bits are&lt;br /&gt;
            &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; valid in the last word */&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c &amp;lt;: DONE ;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c &amp;lt;: tail &amp;gt;&amp;gt; 3;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       }&lt;br /&gt;
       '''break''' ;&lt;br /&gt;
     }&lt;br /&gt;
   } &lt;br /&gt;
   '''while'''( 0 != dataValid );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* Dummy program follows *************************************&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 /* txClient dummy&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''txClient'''( '''chanend''' '''streaming''' c )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''const''' '''int'''&amp;lt;nowiki&amp;gt; dataOut[ ]={ 'H', 'e', 'l', 'l', 'o' };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''static''' '''int''' runCount = 0;&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;c &amp;lt;:( &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut )/ '''sizeof'''&amp;lt;nowiki&amp;gt;( dataOut[ 0 ]));&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut ); i++ )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;c &amp;lt;: dataOut[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     runCount++;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* rxClient dummy&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''rxClient'''( '''chanend''' '''streaming''' c )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''int'''&amp;lt;nowiki&amp;gt; buf[ 1500 ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''int''' todo;&lt;br /&gt;
   '''int''' validBits;&lt;br /&gt;
&lt;br /&gt;
   '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( buf ); i++ )&lt;br /&gt;
   {&lt;br /&gt;
     c :&amp;gt; todo;&lt;br /&gt;
     '''switch'''( todo )&lt;br /&gt;
     {&lt;br /&gt;
       '''case''' MORE :&lt;br /&gt;
       {&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c :&amp;gt; buf[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''case''' DONE :&lt;br /&gt;
       {&lt;br /&gt;
         c :&amp;gt; validBits;&lt;br /&gt;
         i = '''sizeof'''( buf );  /* exit loop */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''default''' :&lt;br /&gt;
       {&lt;br /&gt;
           /* protocol breakdown */&lt;br /&gt;
         i = '''sizeof'''( buf );  /* exit loop */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   '''if'''( DONE != todo )&lt;br /&gt;
   {&lt;br /&gt;
     /* protocol failure, or ran out of buffer space */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* Run the drivers and dummy client threads in parallel&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''int''' '''main'''( '''void''' )&lt;br /&gt;
 {&lt;br /&gt;
   '''chan''' '''streaming''' txc;&lt;br /&gt;
   '''chan''' '''streaming''' rxc;&lt;br /&gt;
&lt;br /&gt;
     miiConfigRxTx( );&lt;br /&gt;
&lt;br /&gt;
   '''par'''&lt;br /&gt;
   {&lt;br /&gt;
     '''while'''( ! txerr )&lt;br /&gt;
     {&lt;br /&gt;
       '''par'''&lt;br /&gt;
       {&lt;br /&gt;
         miiTransmitFrame( TXD, txc );&lt;br /&gt;
         txClient( txc );&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
     '''while'''( ! rxerr )&lt;br /&gt;
     {&lt;br /&gt;
       '''par'''&lt;br /&gt;
       {&lt;br /&gt;
         miiReceiveFrame( RXD, RXDV, rxc );&lt;br /&gt;
         rxClient( rxc );&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   '''return'''( txerr + rxerr );    &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Mobile processes ===&lt;br /&gt;
 /*&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* PiXC version of Programming XC chapter 6.5 using mobile processes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* ... rest of header as &amp;lt;/nowiki&amp;gt;''' 5.1.1 '''&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#include&amp;lt;/nowiki&amp;gt;'''&amp;lt;nowiki&amp;gt; &amp;lt;xs1.h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' MORE 0&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' DONE 1&lt;br /&gt;
&lt;br /&gt;
   /* Because mobile processes names are bound on receiving, we use a simple &lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; protocol enum to allow a random selection for receipt.&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''typedef''' '''enum'''&lt;br /&gt;
 {&lt;br /&gt;
   ''CLIENTA'' = 0,&lt;br /&gt;
   ''CLIENTB'' = 1&lt;br /&gt;
 } CLIENT_ID;&lt;br /&gt;
&lt;br /&gt;
 ... port definitions as ''' 5.1.1 '''&lt;br /&gt;
 '''... clock definitions as  5.1.1 '''&lt;br /&gt;
&lt;br /&gt;
 '''static''' '''int''' txerr = 0;&lt;br /&gt;
 '''static''' '''int''' rxerr = 0;&lt;br /&gt;
&lt;br /&gt;
 ... '''miiConfigTransmit as  5.1.1 '''&lt;br /&gt;
 ... '''miiConfigReceive as  5.1.1 '''&lt;br /&gt;
 '''... miiConfigRxTx as  5.1.1 '''&lt;br /&gt;
 ... '''miiTransmitFrame as  5.1.1 '''&lt;br /&gt;
 ... '''miiReceiveFrame as  5.1.1 '''&lt;br /&gt;
&lt;br /&gt;
 /* Dummy program follows *************************************&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 /* txClient dummy&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* Chanends txaIn and txaOut are fixed (or bound)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 mobile '''void''' '''txClientA'''( '''chanend''' txaOut, '''chanend''' txaIn )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''const''' '''int'''&amp;lt;nowiki&amp;gt; dataOut[ ]={ 'H', 'e', 'l', 'l', 'o', ' ', 'A' };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''static''' '''int''' runCount = 0;  /* mobile process member variable */&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;txaOut &amp;lt;: &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut );&lt;br /&gt;
     '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut ); i++ )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;txaOut &amp;lt;: dataOut[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     runCount++;  /* member variable maintained over mobility */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* txClient dummy&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* Chanends txbIn and txbOut are fixed (or bound)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 mobile '''void''' '''txClientB'''( '''chanend''' txbOut, '''chanend''' txbIn )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''const''' '''int'''&amp;lt;nowiki&amp;gt; dataOut[ ]={ 'H', 'e', 'l', 'l', 'o', ' ', 'B' };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''static''' '''int''' runCount = 0;  /* mobile process member variable */&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;txbOut &amp;lt;: &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut );&lt;br /&gt;
     '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut ); i++ )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;txbOut &amp;lt;: dataOut[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     runCount++;  /* member variable maintained over mobility */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* txClient scheduler.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; Randomly selects which transmit client is given access to the ethernet &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  driver.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  Send the chosen mobile process (context) to main thread.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  Wait for its return.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''txSched'''( chanend ch, mobile txClientA, mobile txClientB )&lt;br /&gt;
 {&lt;br /&gt;
   '''timer''' t0;  /* timer, used as a random choice */&lt;br /&gt;
   '''int''' t;&lt;br /&gt;
&lt;br /&gt;
   '''for'''( ;; )&lt;br /&gt;
   {&lt;br /&gt;
     t0 :&amp;gt; t;&lt;br /&gt;
     '''if'''( 0x1 &amp;amp; t )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: CLIENTA;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: txClientA; &amp;lt;/nowiki&amp;gt; /* send mobile process (and lose its context) */&lt;br /&gt;
       ch :&amp;gt; txClientA;  /* receive mobile process bound name (and context) */&lt;br /&gt;
     }&lt;br /&gt;
     '''else'''&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: CLIENTB;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: txClientB; &amp;lt;/nowiki&amp;gt; /* send mobile process (and lose its context) */&lt;br /&gt;
       ch :&amp;gt; txClientB;  /* receive mobile process bound name (and context) */&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* rxClient dummy&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''rxClient'''( '''chanend''' '''streaming''' c )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''int'''&amp;lt;nowiki&amp;gt; buf[ 1500 ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''int''' todo;&lt;br /&gt;
   '''int''' validBits;&lt;br /&gt;
&lt;br /&gt;
   '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( buf ); i++ )&lt;br /&gt;
   {&lt;br /&gt;
     c :&amp;gt; todo;&lt;br /&gt;
     '''switch'''( todo )&lt;br /&gt;
     {&lt;br /&gt;
       '''case''' MORE :&lt;br /&gt;
       {&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c :&amp;gt; buf[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''case''' DONE :&lt;br /&gt;
       {&lt;br /&gt;
         c :&amp;gt; validBits;&lt;br /&gt;
         i = '''sizeof'''( buf );  /* exit loop */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''default''' :&lt;br /&gt;
       {&lt;br /&gt;
           /* protocol breakdown */&lt;br /&gt;
         i = '''sizeof'''( buf );  /* exit loop */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   '''if'''( DONE != todo )&lt;br /&gt;
   {&lt;br /&gt;
     /* protocol failure, or ran out of buffer space */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* Run the drivers and dummy client threads in parallel&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''int''' '''main'''( '''void''' )&lt;br /&gt;
 {&lt;br /&gt;
   '''chan''' '''streaming''' rxc;&lt;br /&gt;
   '''chan''' sc;&lt;br /&gt;
   '''chan''' txaIn;&lt;br /&gt;
   '''chan''' txaOut;&lt;br /&gt;
   '''chan''' txbIn;&lt;br /&gt;
   '''chan''' txbOut;&lt;br /&gt;
   CLIENT_ID id;&lt;br /&gt;
&lt;br /&gt;
     miiConfigRxTx( );&lt;br /&gt;
&lt;br /&gt;
   '''par'''&lt;br /&gt;
   {&lt;br /&gt;
     txSched( sc, txclientA, txClientB );  /* initially bind  txclientA,  txclientB */&lt;br /&gt;
&lt;br /&gt;
     '''while'''( ! txerr )&lt;br /&gt;
     {&lt;br /&gt;
         /* Receiving a mobile process (over a channel) is done into a bound &lt;br /&gt;
          &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; name and not a free name. Therefore, we first receive and switch &lt;br /&gt;
          &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; on a client_id.&lt;br /&gt;
          &amp;lt;nowiki&amp;gt;*/ &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
       sc :&amp;gt; id;&lt;br /&gt;
       '''switch'''( id )&lt;br /&gt;
       {&lt;br /&gt;
         '''case''' CLIENTA :&lt;br /&gt;
         {&lt;br /&gt;
             /* receive mobile process bound name (and its context),&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* bind its input and output channel-endpoints to a local &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* channel, and it is run as a parallel thread &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
              &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
           sc :&amp;gt; txClientA( txaOut, txaIn );&lt;br /&gt;
           miiTransmitFrame( TXD, txaOut );&lt;br /&gt;
             /* send mobile process bound name (and lose its context),&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* unbind its input and output channel-endpoints from local &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* channels, and terminate its thread &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;sc &amp;lt;: txClientA( txaOut, txaIn );&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         }&lt;br /&gt;
         '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
         '''case''' CLIENTB :&lt;br /&gt;
         {&lt;br /&gt;
             /* receive mobile process bound name (and its context),&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* bind its input and output channel-endpoints to a local &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* channel, and it is run as a parallel thread &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
              &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
           sc :&amp;gt; txClientB( txbOut, txbIn );&lt;br /&gt;
           miiTransmitFrame( TXD, txbOut );&lt;br /&gt;
             /* send mobile process bound name (and lose its context),&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* unbind its input and output channel-endpoints from local &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;* channels, and terminate its thread &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
              &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;sc &amp;lt;: txClientB( txbOut, txbIn );&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         }&lt;br /&gt;
         '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     '''while'''( ! rxerr )&lt;br /&gt;
     {&lt;br /&gt;
       '''par'''&lt;br /&gt;
       {&lt;br /&gt;
         miiReceiveFrame( RXD, RXDV, rxc );&lt;br /&gt;
         rxClient( rxc );&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   '''return'''( txerr + rxerr );  &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Mobile channels ===&lt;br /&gt;
 /*&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* PiXC version of Programming XC chapter 6.5 with mobile channels&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* ... rest of header as &amp;lt;/nowiki&amp;gt;''' 5.1.1 '''&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#include&amp;lt;/nowiki&amp;gt;'''&amp;lt;nowiki&amp;gt; &amp;lt;xs1.h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' MORE 0&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' DONE 1&lt;br /&gt;
&lt;br /&gt;
 '''&amp;lt;nowiki&amp;gt;#define&amp;lt;/nowiki&amp;gt;''' mobile  /* _ONLY_ to produce more insightful PiXC compilation reports  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   /* Because mobile processes names are bound on receiving, we use a simple &lt;br /&gt;
    &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; protocol enum to allow a random selection for receipt.&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''typedef''' '''enum'''&lt;br /&gt;
 {&lt;br /&gt;
   ''CLIENTA'' = 0,&lt;br /&gt;
   ''CLIENTB'' = 1&lt;br /&gt;
 } CLIENT_ID;&lt;br /&gt;
&lt;br /&gt;
 ... port definitions as ''' 5.1.1 '''&lt;br /&gt;
 '''... clock definitions as  5.1.1 '''&lt;br /&gt;
&lt;br /&gt;
 '''static''' '''int''' txerr = 0;&lt;br /&gt;
 '''static''' '''int''' rxerr = 0;&lt;br /&gt;
&lt;br /&gt;
 ... '''miiConfigTransmit as  5.1.1 '''&lt;br /&gt;
 ... '''miiConfigReceive as  5.1.1 '''&lt;br /&gt;
 '''... miiConfigRxTx as  5.1.1 '''&lt;br /&gt;
 ... '''miiTransmitFrame as  5.1.1 '''&lt;br /&gt;
 ... '''miiReceiveFrame as  5.1.1 '''&lt;br /&gt;
&lt;br /&gt;
 /* Dummy program follows *************************************&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 /* txClient dummy with fixed channels&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''txClientA'''( '''chanend''' txaOut, '''chanend''' txaIn )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''const''' '''int'''&amp;lt;nowiki&amp;gt; dataOut[ ]={ 'H', 'e', 'l', 'l', 'o', ' ', 'A' };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''static''' '''int''' runCount = 0;  /* mobile process member variable */&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;txaOut &amp;lt;: &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut );&lt;br /&gt;
     '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut ); i++ )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;txaOut &amp;lt;: dataOut[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     runCount++;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* txClient dummy with fixed channels&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''txClientB'''( '''chanend''' txbOut, '''chanend''' txbIn )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''const''' '''int'''&amp;lt;nowiki&amp;gt; dataOut[ ]={ 'H', 'e', 'l', 'l', 'o', ' ', 'B' };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''static''' '''int''' runCount = 0;  /* mobile process member variable */&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;txbOut &amp;lt;: &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut );&lt;br /&gt;
     '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( dataOut ); i++ )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;txbOut &amp;lt;: dataOut[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     runCount++;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* txClient scheduler.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; Randomly selects which transmit client is given access to the ethernet&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  driver .&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  Initially bound to txaIn, txaOut, txbIn, txbOut.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  Send the chosen mobile process (context) to main thread.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt;  Wait for its return.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' txSched( &lt;br /&gt;
   '''chanend''' ch,&lt;br /&gt;
   '''chanend''' mobile:b txaIn,   /* initially bind txaIn endpoint */&lt;br /&gt;
   '''chanend''' mobile:b txaOut,  /* initially bind txaOut endpoint */&lt;br /&gt;
   '''chanend''' mobile:b txbIn,   /* initially bind txbIn endpoint */&lt;br /&gt;
   '''chanend''' mobile:b txbOut   /* initially bind txbOut endpoint */&lt;br /&gt;
   )&lt;br /&gt;
 {&lt;br /&gt;
   '''timer''' t0;  /* timer, used as a random choice */&lt;br /&gt;
   '''int''' t;&lt;br /&gt;
&lt;br /&gt;
   '''for'''( ;; )&lt;br /&gt;
   {&lt;br /&gt;
     t0 :&amp;gt; t;&lt;br /&gt;
     '''if'''( 0x1 &amp;amp; t )&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: CLIENTA;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: txaIn; &amp;lt;/nowiki&amp;gt;     /* send mobile channel (and lose chanend) */&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: txaOut; &amp;lt;/nowiki&amp;gt;    /* send mobile channel (and lose chanend) */&lt;br /&gt;
       ch :&amp;gt; txaIn;      /* receive mobile channel (and collect chanend) */&lt;br /&gt;
       ch :&amp;gt; txaOut;     /* receive mobile channel (and collect chanend) */&lt;br /&gt;
     }&lt;br /&gt;
     '''else'''&lt;br /&gt;
     {&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: CLIENTB;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: txbIn; &amp;lt;/nowiki&amp;gt;     /* send mobile channel (and lose chanend) */&lt;br /&gt;
       &amp;lt;nowiki&amp;gt;ch &amp;lt;: txbOut; &amp;lt;/nowiki&amp;gt;    /* send mobile channel (and lose chanend) */&lt;br /&gt;
       ch :&amp;gt; txbIn;      /* receive mobile channel (and collect chanend) */&lt;br /&gt;
       ch :&amp;gt; txbOut;     /* receive mobile channel (and collect chanend) */&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* rxClient dummy&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''void''' '''rxClient'''( '''chanend''' '''streaming''' c )&lt;br /&gt;
 {&lt;br /&gt;
   '''static''' '''int'''&amp;lt;nowiki&amp;gt; buf[ 1500 ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   '''int''' todo;&lt;br /&gt;
   '''int''' validBits;&lt;br /&gt;
&lt;br /&gt;
   '''for'''( '''int'''&amp;lt;nowiki&amp;gt; i=0; i &amp;lt; &amp;lt;/nowiki&amp;gt;'''sizeof'''( buf ); i++ )&lt;br /&gt;
   {&lt;br /&gt;
     c :&amp;gt; todo;&lt;br /&gt;
     '''switch'''( todo )&lt;br /&gt;
     {&lt;br /&gt;
       '''case''' MORE :&lt;br /&gt;
       {&lt;br /&gt;
         &amp;lt;nowiki&amp;gt;c :&amp;gt; buf[ i ];&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''case''' DONE :&lt;br /&gt;
       {&lt;br /&gt;
         c :&amp;gt; validBits;&lt;br /&gt;
         i = '''sizeof'''( buf );  /* exit loop */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       '''default''' :&lt;br /&gt;
       {&lt;br /&gt;
           /* protocol breakdown */&lt;br /&gt;
         i = '''sizeof'''( buf );  /* exit loop */&lt;br /&gt;
       }&lt;br /&gt;
       '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   '''if'''( DONE != todo )&lt;br /&gt;
   {&lt;br /&gt;
     /* protocol failure, or ran out of buffer space */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /* Run the drivers and dummy mobile process client threads in parallel&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;*/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''int''' '''main'''( '''void''' )&lt;br /&gt;
 {&lt;br /&gt;
   '''chan''' sc;&lt;br /&gt;
   '''chan''' '''streaming''' rxc;&lt;br /&gt;
   CLIENT_ID id;&lt;br /&gt;
   '''chan''' mobile txaIn;  /* mobile chanend un-bound */&lt;br /&gt;
   '''chan''' mobile txaOut; /* mobile chanend un-bound */&lt;br /&gt;
   '''chan''' mobile txbIn;  /* mobile chanend un-bound */&lt;br /&gt;
   '''chan''' mobile txbOut; /* mobile chanend un-bound */&lt;br /&gt;
&lt;br /&gt;
     miiConfigRxTx( );&lt;br /&gt;
&lt;br /&gt;
   '''par'''&lt;br /&gt;
   {&lt;br /&gt;
     txClientA( txaOut, txaIn );  /* mobile chanend fixed in definition */&lt;br /&gt;
&lt;br /&gt;
     txClientB( txbOut, txbIn );  /* mobile chanend fixed in definition */&lt;br /&gt;
&lt;br /&gt;
       /* mobile chanends initially bound in definition of txSched */&lt;br /&gt;
     txSched( sc, txaIn, txaOut, txbIn, txbOut );  &lt;br /&gt;
&lt;br /&gt;
     '''while'''( ! txerr )&lt;br /&gt;
     {&lt;br /&gt;
         /* Receiving a mobile process (over a channel) is done into a bound &lt;br /&gt;
          &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; name and not a free name. Therefore, we first receive and switch &lt;br /&gt;
          &amp;lt;nowiki&amp;gt;* &amp;lt;/nowiki&amp;gt; on a client_id.&lt;br /&gt;
          &amp;lt;nowiki&amp;gt;*/ &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
       sc :&amp;gt; id;&lt;br /&gt;
       '''switch'''( id )&lt;br /&gt;
       {&lt;br /&gt;
         '''case''' CLIENTA :&lt;br /&gt;
         {&lt;br /&gt;
           sc :&amp;gt; txaIn;      /* receive mobile chanend (and bind context) */&lt;br /&gt;
           sc :&amp;gt; txaOut;     /* receive mobile chanend (and bind context) */&lt;br /&gt;
&lt;br /&gt;
           miiTransmitFrame( TXD, txaOut );&lt;br /&gt;
&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;sc &amp;lt;: txaIn; &amp;lt;/nowiki&amp;gt;     /* send mobile chanend (and unbind context) */&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;sc &amp;lt;: txaOut; &amp;lt;/nowiki&amp;gt;    /* send mobile chanend (and unbind context) */&lt;br /&gt;
         }&lt;br /&gt;
         '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
         '''case''' CLIENTB :&lt;br /&gt;
         {&lt;br /&gt;
           sc :&amp;gt; txbIn;      /* receive mobile chanend (and bind context) */&lt;br /&gt;
           sc :&amp;gt; txbOut;     /* receive mobile chanend (and bind context) */&lt;br /&gt;
&lt;br /&gt;
           miiTransmitFrame( TXD, txbOut );&lt;br /&gt;
&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;sc &amp;lt;: txbIn; &amp;lt;/nowiki&amp;gt;     /* send mobile chanend (and unbind context) */&lt;br /&gt;
           &amp;lt;nowiki&amp;gt;sc &amp;lt;: txbOut; &amp;lt;/nowiki&amp;gt;    /* send mobile chanend (and unbind context) */&lt;br /&gt;
         }&lt;br /&gt;
         '''break'''&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     '''while'''( ! rxerr )&lt;br /&gt;
     {&lt;br /&gt;
       '''par'''&lt;br /&gt;
       {&lt;br /&gt;
         miiReceiveFrame( RXD, RXDV, rxc );&lt;br /&gt;
         rxClient( rxc );&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   '''return'''( txerr + rxerr );  &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Extensions =&lt;br /&gt;
The mobile process extensions could be further extended in several ways. &lt;br /&gt;
&lt;br /&gt;
== Mobile context ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;The file-scope static declaration which serves as the mobile context for process member variables and process member functions could be relaxed if the compiler/linker will search through a collection of source files and check for reference calls [hard]. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or mobile contexts could be incorporated with namespaces. Alternatively and perhaps less pleasingly (as the base language is XC and not XC++), programmers could write fully qualified names for process member variables and functions, along the lines outlined in the previous sections: p0::x&amp;lt;nowiki&amp;gt; [easier]. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assignment ==&lt;br /&gt;
Mobile channel endpoints are declared in the definition of a containing function; this is for consistency with XC. They extend endpoints with a variable-like semantics. And values are assigned (to a mobile endpoint) as the variable component of a channel input expression. &lt;br /&gt;
&lt;br /&gt;
If chanend was made a proper data type, an equivalent variable-like semantics for mobile chanend binding could be provided through assignment. &lt;br /&gt;
&lt;br /&gt;
 void swapchan( chanend control, chanend mobile d1, chanend mobile d2 )&lt;br /&gt;
 {&lt;br /&gt;
     chanend mobile c;        // a local variable of type chanend, unbound&lt;br /&gt;
     control :&amp;gt; d1;        // bind d1 endpoint by input (constructor)&lt;br /&gt;
     control :&amp;gt; d2;        // bind d2 endpoint by input (constructor)&lt;br /&gt;
     c = d2;            // temporary, bind c by assignment&lt;br /&gt;
     d2 = d1;            // re-bind d2 by assignment&lt;br /&gt;
     d1 = c;            // re-bind d1 by assignment&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is safe provided all channel bindings were input to the function through a communication expression. &lt;br /&gt;
&lt;br /&gt;
== Process arrays ==&lt;br /&gt;
If the mobile process defines a proper data type then arrays of processes could be declared, sharing a single definition. For example,&lt;br /&gt;
&lt;br /&gt;
 mobile&amp;lt;nowiki&amp;gt; void p[8]( chanend out, chanend in );&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This provides an array of alike mobile processes, each with independent (member variables) state including local bindable channels, able to roam the processor network looking for work assignment. &lt;br /&gt;
&lt;br /&gt;
== Channel arrays ==&lt;br /&gt;
With the introduction of protocols, channel arrays become meaningful. It is not yet clear exactly how they may prove useful, however. &lt;br /&gt;
&lt;br /&gt;
== Heterogenous networks ==&lt;br /&gt;
By sending process member variables only, and not code, the mobile model extends to heterogenous processor networks (in which a distinct compiled unit exists for each processor type, e.g. XS-1, ARM7). The requirement for operating in heterogenous processor networks is to transmit the data in a uniform layout, for which XML could be used. &lt;br /&gt;
&lt;br /&gt;
== Mobile algorithms ==&lt;br /&gt;
As a general purpose programming language, PiXC can be used to express mobile algorithms; the design patterns given are such an example. The dynamic communication of mobile channels and mobile processes through channels enables the function and data control flow to evolve in response to run-time events. This opens up a sub-branch of computer science research. &lt;br /&gt;
&lt;br /&gt;
= Conclusions =&lt;br /&gt;
PiXC is a proposal to extend XC with mobility and to formalise (extensions to) a compiler for PiXC that targets XMOS processors. Syntax and a meaning for mobile processes and mobile channels is given. Certain syntax and semantics are omitted (and others are probably waiting discovery), and those given could yet change in future drafts. &lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;1] [http://www.xmos.com/published/xs1_en XMOS XS1 Architecture], May D., 2008&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;2] [http://www.xmos.com/published/xc_en Programming XC on XMOS devices], Watt D., 2009&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;3] [http://portal.acm.org/citation.cfm?id=359576.359585#abstract Communicating Sequential Processes], Hoare C.A.R., C.ACM 21(8) pp:666-677, 1978. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4] [http://en.wikipedia.org/wiki/Communicating_sequential_processes Communicating Sequential Processes], Hoare C.A.R., Prentice Hall, 1985. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;5] [http://en.wikipedia.org/wiki/Occam_(programming_language) Occam Programming Manual]&amp;lt;nowiki&amp;gt;, INMOS Limited, Prentice Hall, 1984. [See also &amp;lt;/nowiki&amp;gt;[http://wotug.org/occam/ Occam2], 1988]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;6] [http://books.google.co.uk/books?id=rT05AAAAIAAJ&amp;amp;pg=PA343&amp;amp;lpg=PA343&amp;amp;dq=transputer+transistor+computer&amp;amp;source=bl&amp;amp;ots=7T5oM1avV9&amp;amp;sig=Od6ckIjVgQBH8T2OaBvvA2ihNlY&amp;amp;hl=en&amp;amp;ei=caIRSq2CNJnNjAe31dnkCA&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=7#v=onepage&amp;amp;q=transputer%20transistor%20computer&amp;amp;f=false The Transputer], Barron I., 1978.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;7] [http://en.wikipedia.org/wiki/Transputer Transputer Reference Manual], INMOS Limited, Prentice Hall, 1988.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;8] [http://www.cs.kent.ac.uk/projects/ofa/kroc/ Kent Relocatable Occam Compiler], [http://www.cs.kent.ac.uk/research/groups/sys/kroc.html University of Kent]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;9] [https://www.cs.kent.ac.uk/research/groups/plas/wiki/OccamPiReference/ Occam-pi], [http://www.cs.kent.ac.uk/pubs/2003/1721/content.ps RmoX], [http://frmb.org/pubs/qm-occampi-rmox.pdf Occam-pi and RMoX], [http://www.cs.kent.ac.uk/research/groups/sys/kroc.html University of Kent]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;10] [http://www.cs.kent.ac.uk/pubs/2004/1969/content.pdf Communicating Mobile Processes], [http://www.cs.kent.ac.uk/projects/ofa/kroc/csp-model-cpa2008.pdf Communicating Mobile Channels], [http://www.cs.kent.ac.uk/research/groups/sys/kroc.html University of Kent]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;11] [http://en.wikipedia.org/wiki/Calculus_of_communicating_systems Communication and Concurrency], Milner R., [http://www.pearsoned.co.uk/Student/detail.asp?item=100000000010554 Prentice Hall]&amp;lt;nowiki&amp;gt;, 1989. [see also Calculus of Communicating Systems, Milner A.J.R., Springer Verlag LNCS 92, 1980.] &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;12] [http://en.wikipedia.org/wiki/Pi_calculus pi-Calculus], Milner R., [http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=9780521658690 Cambridge], 1999.&lt;/div&gt;</description>
			<pubDate>Sat, 26 Jun 2010 14:37:46 GMT</pubDate>			<dc:creator>Jhrose</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:PiXC</comments>		</item>
		<item>
			<title>XOSIG IoI</title>
			<link>http://www.xcore.com/wiki/index.php/XOSIG_IoI</link>
			<description>&lt;p&gt;Jhrose:&amp;#32;XOSIG Index Of Ideas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= XOSIG Index of Ideas =&lt;br /&gt;
Copyright © XMOSlinkers jhrose, 2009-2010. Version 0.3.1. These notes are distributed with the [http://www.gnu.org/copyleft/fdl.html FSF Free Documentation License version 1.3] as a community work. &lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
XOSIG provides a forum covering all theoretical and practical aspects of operating systems relating to XMOS technology.&lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
These notes aim to outline substantive ideas within XOSIG, providing a first port-of-call to locate projects and those involved with them. Each may be expanded upon in related projects and their references. &lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;XMOS processors such as the XS-1 core [&amp;lt;/nowiki&amp;gt;4.1&amp;lt;nowiki&amp;gt;] equip system designers with process-oriented hardware and software building blocks, not unlike the INMOS Transputer cores which predated them. An XMOS XS-1 is a multi-core processor, each core with its own memory and i/o links [&amp;lt;/nowiki&amp;gt;4.1&amp;lt;nowiki&amp;gt;]. The cores embed support for a number of services commonly provided by an operating system on general purpose processors, including multi-threading, communication, general purpose i/o, and timers. And like INMOS with Occam, XMOS provide a parallel programming language in XC [&amp;lt;/nowiki&amp;gt;4.2] which can be considered the Operating System Language of XS-1 processors. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using XC, an operating system is not a necessity in an system of homogenous XS-1 processors. However, there are a number of Operating System technologies that could be applied to extend the services provided by XS-1 and XC, and those that could be applied to network with heterogenous systems. &lt;br /&gt;
&lt;br /&gt;
== Table of Content ==&lt;br /&gt;
Each idea is listed in the table below and linked to a later section of these notes. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
| Project&lt;br /&gt;
| Summary&lt;br /&gt;
| Status&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|  2 XOSS&lt;br /&gt;
| XS-1 Operating System Services to extend services provided by XS-1 and XC and to network with heterogenous systems. &lt;br /&gt;
| Just an idea&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|  3 HyperviXor&lt;br /&gt;
| XS-1 as a Hypervisor servicing a number of Concurrent Operating Systems. &lt;br /&gt;
| Abandoned&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|  4 PiXC&lt;br /&gt;
| To use the pi-calculus as a model to extend XC with mobile processes and mobile channels.&lt;br /&gt;
| Just an idea&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|  5 PiXOS&lt;br /&gt;
| To use the pi-calculus as a model and PiXC to implement a Dynamic Operating System for XMOS processors.&lt;br /&gt;
| Just an idea&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|  6 FreeRTOS&lt;br /&gt;
| A port of FreeRTOS to the XS-1.&lt;br /&gt;
| Project&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|  7 Next idea...&lt;br /&gt;
| Next idea...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
= XOSS =&lt;br /&gt;
Proposal for XS-1 Operating System Services to extend those services provided by XS-1 and XC, and in particular a form of paged memory management. To provide hardware that enables networking with mainstream host processors running Operating Systems like VxWorks or Linux.&lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
The aim of XOSS is twofold:&lt;br /&gt;
&lt;br /&gt;
* to expand the operating system services provided by XS-1 cores and the XC language,&lt;br /&gt;
* to integrate with multi-processor Operating Systems and extend application parallelism. &lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
! Identity&lt;br /&gt;
! Contact&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| jhrose&lt;br /&gt;
| Via XMOS Exchange&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
The XS-1 processor does not provide an External Memory Interface (EMIF), which could introduce non-determinism between threads. And we are taught to program for limited xcore memory using data shared through channels, rather than writing large monolithic algorithms. Still, there are occasions when access to secondary memory would prove beneficial. &lt;br /&gt;
&lt;br /&gt;
There are common operating system services which the XS-1 core does not embed, such as memory caching which would allow use of both a secondary cache and an external main memory, and services which XC does not support, such as a service registry which would allow a set of distributed services to be run across heterogenous processor networks. And the scope for parallel applications can be extended to run not just on multi-cores but also over multi-processors. &lt;br /&gt;
&lt;br /&gt;
== Project ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;To provide hardware for secondary memory, to extend PAR in XC to mark caching points, and to provide methods for communication with a host processor including virtual channels. The project is more fully described in [&amp;lt;/nowiki&amp;gt;2.3]. &lt;br /&gt;
&lt;br /&gt;
=== Secondary memory ===&lt;br /&gt;
The XS-1 provides no memory objects beneath the L1 Cache, and the processor has no ability to address external memory. To provide the next level multi-cycle Level-2 Cache and lowest Main Memory necessitates both a system design and either toolchain support for XC. &lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
A proposed Level-2 Cache and Main Memory system design is proposed, using an FPGA to provide a cache and to interface an external 400MHz DDR SDRAM. And with some development the same hardware is proposed as an interface to a Host Processor Node, through Dual-Port Memory and an Xlink connection. Caching requires an extension to XC (or a custom library), and has a real-time performance overhead. &lt;br /&gt;
&lt;br /&gt;
=== Extended PAR ===&lt;br /&gt;
Cache-misses would stall the processor for a large number of cycles, so facilitating them at known scheduling points is desirable. The XC programming language includes just such a known scheduling point in the PAR statement, where the programmer spawns threads. Consider the following proposed extended PAR, in which the set of threads is named and declared with proposed new keywords:&lt;br /&gt;
&lt;br /&gt;
 PAR set_of_abc IS PAGED&lt;br /&gt;
 {&lt;br /&gt;
 a( );&lt;br /&gt;
 b( );&lt;br /&gt;
 c( );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
in which ''set_of_abc'' is a name like a variable name, and ''IS PAGED'' is an attribute. This works similarly for replicated PAR, for example:&lt;br /&gt;
&lt;br /&gt;
 PAR&amp;lt;nowiki&amp;gt;( int i=0; i&amp;lt;4; i++ ) array&amp;lt;/nowiki&amp;gt;_of_a IS PAGED&lt;br /&gt;
 {&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;a[ i ]( );&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Virtual Channels ===&lt;br /&gt;
As each XS-1 core has a finite set of channel resources, XOSS could provide a library of Virtual Channels (VCH). A large number of VCHs could be multiplexed over a few physical channels. And exposing XOSS VCHs over the Host Processor Node Xlink interface as a Linux device would allow a direct exchange of data between XOSS/XS-1 and Linux threads.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;2.1] [http://www.xmos.com/published/xs1_en XMOS XS1 Architecture], May D., 2008&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;2.2] [http://www.xmos.com/published/xc_en Programming XC on XMOS devices], Watt D., 2009&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;2.3] [http://www.xcore.com/forum/download/file.php?id=16 XOSS Proposal], jhrose, 2009.&lt;br /&gt;
&lt;br /&gt;
= HyperviXor =&lt;br /&gt;
XS-1 hardware as a Hypervisor servicing a number of Concurrent Operating Systems. &lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
* To use XS-1 threads and resources to virtualise Concurrently running Operating Systems&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
! Identity&lt;br /&gt;
! Contact&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| jhrose&lt;br /&gt;
| Via XMOS Exchange&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
A Hypervisor provides a low-level service to Operating Systems, much as operating systems themselves virtualise resources to software applications. In systems with multiply different real-time and concurrent requirements, benefit can be had in dividing the application among different Operating Systems with differing characteristics and services. &lt;br /&gt;
&lt;br /&gt;
== Project ==&lt;br /&gt;
Abandoned because it will be cheaper just to use another processor for each sub-system OS. &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
= PiXC =&lt;br /&gt;
To use the pi-calculus as a model to extend the XC programming language with mobile processes and mobile channels.&lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
The aims of PiXC are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;To use the pi-calculus [&amp;lt;/nowiki&amp;gt;4.5&amp;lt;nowiki&amp;gt;] as a model to extend XC [&amp;lt;/nowiki&amp;gt;4.2] with mobility&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;To formalise (extensions to) a compiler for PiXC that targets XMOS processors [&amp;lt;/nowiki&amp;gt;4.1]&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
! Identity&lt;br /&gt;
! Contact&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| jhrose&lt;br /&gt;
| Via XMOS Exchange&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;As Milner begins the introduction [&amp;lt;/nowiki&amp;gt;4.5&amp;lt;nowiki&amp;gt;], &amp;quot;[pi is]...a calculus for analysing properties of concurrent communicating proceses, which may grow and shrink and move about&amp;quot;. This fluidity takes the pi-Calculus to a level not reached by CCS, CSP or classical automata. In the broadest nutshell, pi is an extension to CCS that allows the very channels used for inter-process communication to be passed as communication elements. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PiXC makes programming with the Pi-calculus accessible and familiar, by modestly extending the XC programming language. These extensions allow mobile processes and channels to be declared and have a language semantics. Extensions to input and output statements allow mobile processes to be communicated along channels, so the mobile context leaves the sender process and arrives at the receiving process where it runs in parallel. The sender and receiver process can reside on different processors. The state (or context) of a mobile process is preserved over its migration, so that its lifetime persists for the duration of the whole program. &lt;br /&gt;
&lt;br /&gt;
== Project ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;To extend XC with mobile processes and mobile channels. The project is more fully described in [&amp;lt;/nowiki&amp;gt;4.6]. &lt;br /&gt;
&lt;br /&gt;
=== Fluid architecture ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;In addition to modelling internets [&amp;lt;/nowiki&amp;gt;4.5], we assert Pi is also well-suited for general purpose programming and expressing algorithms. &amp;lt;nowiki&amp;gt;The dynamic communication of mobile channels and mobile processes through channels enables the function and data control flow to evolve in response to run-time events [&amp;lt;/nowiki&amp;gt;4.4]. &lt;br /&gt;
&lt;br /&gt;
=== Mobile Processes ===&lt;br /&gt;
Mobile processes are those which migrate, to run at different locations at different times. To be mobile, rather than just invoked in the accepted way, a process has to preserve some state and provide various function entry points, which suggests a ''mobile-context'' structure operating entirely within the process. And to be safe, a process has to be sent through a channel to a new location. &lt;br /&gt;
&lt;br /&gt;
=== Mobile Channels ===&lt;br /&gt;
Mobile channels are those which migrate, to bind with different endpoints at different times. To be mobile, rather than just used in the accepted way, a channel has first to be emptied so that it is state-less before migrating. And to be safe, a channel has to be sent from a source process through a channel, possibly itself, to a destination process. Once sent, the source process can no longer access the migrated channel; and counterwise the destination process can only access the migrated channel once received. &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4.1] [http://www.xmos.com/published/xs1_en XMOS XS1 Architecture], May D., 2008&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4.2] [http://www.xmos.com/published/xc_en Programming XC on XMOS devices], Watt D., 2009&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4.3] [https://www.cs.kent.ac.uk/research/groups/plas/wiki/OccamPiReference/ Occam-pi], [http://www.cs.kent.ac.uk/pubs/2003/1721/content.ps RmoX], [http://frmb.org/pubs/qm-occampi-rmox.pdf Occam-pi and RMoX], [http://www.cs.kent.ac.uk/research/groups/sys/kroc.html University of Kent]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4.4] [http://www.cs.kent.ac.uk/pubs/2004/1969/content.pdf Communicating Mobile Processes], [http://www.cs.kent.ac.uk/projects/ofa/kroc/csp-model-cpa2008.pdf Communicating Mobile Channels], [http://www.cs.kent.ac.uk/research/groups/sys/kroc.html University of Kent]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4.5] [http://en.wikipedia.org/wiki/Pi_calculus pi-Calculus], Milner R., [http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=9780521658690 Cambridge], 1999. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;4.6] PiXC proposal, jhrose, 2009-10. &lt;br /&gt;
&lt;br /&gt;
= PiXOS =&lt;br /&gt;
To use the Pi-calculus to model and PiXC to develop a Dynamic Operating System for XMOS processors. &lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
The aims of PiXOS are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;To use the pi-calculus [&amp;lt;/nowiki&amp;gt;4.5] as a paradigm for a Dynamic Operating System&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;To use PiXC [&amp;lt;/nowiki&amp;gt;4.6&amp;lt;nowiki&amp;gt;] to develop an Operating System for XMOS processors [&amp;lt;/nowiki&amp;gt;4.1]&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
! Identity&lt;br /&gt;
! Contact&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| jhrose&lt;br /&gt;
| Via XMOS Exchange&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
In traditional operating systems, especially those targetting embedded systems, the executable unit is commonly statically linked so that the set of possible services is fixed during compilation, and resources like memory and CPU are shared among processes through virtualisation. In systems with an interface, libraries may be dynamically link-loaded at runtime to extend the set of kernel modules or device drivers. However, the concept of operation, the way people view and program for operating systems, largely remains fixed on a rigid architecture which is not at all fluid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;As Milner begins the introduction [&amp;lt;/nowiki&amp;gt;4.5&amp;lt;nowiki&amp;gt;], &amp;quot;[pi is]...a calculus for analysing properties of concurrent communicating proceses, which may grow and shrink and move about&amp;quot;. In the broadest nutshell, pi is an extension to CCS that allows the very channels used for inter-process communication to be passed as communication elements. In communicating a channel, the effect is a dynamic re-mapping of the architecture. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Project ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;To develop PiXC-language libraries that implement a Dynamic Operating System Architecture. The project is more fully described in [&amp;lt;/nowiki&amp;gt;5.3]. &lt;br /&gt;
&lt;br /&gt;
=== Fluid architecture ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;In addition to modelling internets [&amp;lt;/nowiki&amp;gt;4.5], we assert Pi is also well-suited for modelling a dynamic operating system, whose very architecture changes dynamically to fulfil the state transitions of its processes. &amp;lt;nowiki&amp;gt;The communication of mobile channels and mobile processes through channels enables network topology to evolve in response to run-time events [&amp;lt;/nowiki&amp;gt;4.4]. &lt;br /&gt;
&lt;br /&gt;
=== Mobile Services ===&lt;br /&gt;
A dynamic operating system can publicise a set of mobile processes, which migrate to run at different locations at different times. Each mobile process can implement an Operating System Service (including Interrupt Service Routines). When not in use a Mobile Service (MS) resides dormant in a registry; and when needed an MS is claimed by a process, to which it migrates and runs in parallel. &lt;br /&gt;
&lt;br /&gt;
=== Device Drivers ===&lt;br /&gt;
A dynamic operating system can publicise a set of static device drivers through mobile channels, whose endpoints migrate to bind with different processes at different times. A static driver controls a fixed-location hardware capability, such as an i/o port. When not in use a Mobile Endpoint (ME) resides dormant in a registry; and when needed an ME is claimed by a process, to which it migrates.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[5&amp;lt;/nowiki&amp;gt;.1] [http://www.xmos.com/published/xs1_en XMOS XS1 Architecture], May D., 2008&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[5&amp;lt;/nowiki&amp;gt;.2] [http://en.wikipedia.org/wiki/Pi_calculus pi-Calculus], Milner R., [http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=9780521658690 Cambridge], 1999. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;5.3] PiXOS proposal, jhrose, 2010. &lt;br /&gt;
&lt;br /&gt;
= FreeRTOS =&lt;br /&gt;
A port of FreeRTOS to the XS-1. &lt;br /&gt;
&lt;br /&gt;
== Aims ==&lt;br /&gt;
FreeRTOS aims to provide:&lt;br /&gt;
&lt;br /&gt;
* a portable, Open Source, royalty free, mini Real Time Kernel&lt;br /&gt;
* tasks, co-routines, and inter-task communication&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
! Identity&lt;br /&gt;
! Contact&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| bianco&lt;br /&gt;
| Via XMOS Exchange&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
* preemptive, cooperative and hybrid scheduling &lt;br /&gt;
&lt;br /&gt;
* support for over 23 distinct architectures &lt;br /&gt;
&lt;br /&gt;
* designed to be small; typically a kernel binary image will be in the region of 4K to 9K bytes&lt;br /&gt;
&lt;br /&gt;
* portable code structure predominantly written in C&lt;br /&gt;
&lt;br /&gt;
* supports both [http://www.freertos.org/taskandcr.html tasks and co-routines]&lt;br /&gt;
&lt;br /&gt;
* [http://www.freertos.org/Stacks-and-stack-overflow-checking.html stack overflow detection] options&lt;br /&gt;
&lt;br /&gt;
* no software restriction on the number of tasks that can be created&lt;br /&gt;
&lt;br /&gt;
* no software restriction on the number of priorities that can be used&lt;br /&gt;
&lt;br /&gt;
* no restrictions imposed on priority assignment - more than one task can be assigned the same priority&lt;br /&gt;
&lt;br /&gt;
* [http://www.freertos.org/Inter-Task-Communication.html queues, binary semaphores, counting semaphores, recursive semaphores and mutexes] for communication and synchronisation between tasks, or between tasks and interrupts&lt;br /&gt;
&lt;br /&gt;
* [http://www.freertos.org/Inter-Task-Communication.html#Mutexes mutexes] with priority inheritance&lt;br /&gt;
&lt;br /&gt;
* Free embedded software source code&lt;br /&gt;
&lt;br /&gt;
* royalty free&lt;br /&gt;
&lt;br /&gt;
== Project ==&lt;br /&gt;
To port FreeRTOS to the XS-1 architecture.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
The FreeRTOS kernel source is spread over 4 source files and 10 header files written in standard C, which are compiled using the XCC toolchain. Then there is a portable subdirectory, within which architecture-specific source files in C and assembler reside. A new portable sub-directory for XCC is created, and a target sub-directory for XMOS_XS1 containing C and XC source files. &lt;br /&gt;
&lt;br /&gt;
=== XS-1 port ===&lt;br /&gt;
The port_xc.c source declares a timer resource, used to provide the FreeRTOS kernel timer. The kernel is run each time the timer expires, to perform a context switch. The portmacro.h file defines basic types, constants and macros, including atomic functions to enable and disable interrupts. A macro is provided to make a kernel call entry point, though the only kernel function implemented so far is a context switch. The port.c file supports scheduler functions. The port_asm.S file implements task context save and restore functions, the tick ISR, and functions to initialise each task stack and the kernel on startup. Memory allocation is provided using the XCC built-in heap library. &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[6&amp;lt;/nowiki&amp;gt;.1] [http://www.freertos.org/ http://www.freertos.org/]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[6.2] &amp;lt;/nowiki&amp;gt;[http://www.xcore.com/projects/freertos-port http://www.xcore.com/projects/freertos-port]&lt;br /&gt;
&lt;br /&gt;
= Next idea... =&lt;br /&gt;
== Aims ==&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot;&lt;br /&gt;
! Identity&lt;br /&gt;
! Contact&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
== Summary ==&lt;br /&gt;
== Project ==&lt;br /&gt;
== References ==&lt;/div&gt;</description>
			<pubDate>Sat, 26 Jun 2010 14:30:02 GMT</pubDate>			<dc:creator>Jhrose</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XOSIG_IoI</comments>		</item>
		<item>
			<title>XMOS Operating System Interest Group (XOSIG)</title>
			<link>http://www.xcore.com/wiki/index.php/XMOS_Operating_System_Interest_Group_(XOSIG)</link>
			<description>&lt;p&gt;Jhrose:&amp;#32;/* PiXC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XOSIG provides a forum covering all theoretical and practical aspects of operating systems relating to XMOS technology.&lt;br /&gt;
We have our group at [http://www.xcore.com/groups/xmos-operating-system-interest-group-xosig] where members are encouraged to propose ideas. Or group members are active within xcore and make various contributions to the forum, for example [http://www.xcore.com/forum/viewtopic.php?f=17&amp;amp;t=83].&lt;br /&gt;
&lt;br /&gt;
== Index Of Ideas ==&lt;br /&gt;
An XOSIG Index Of Ideas is maintained. Its aim is to outline substantive ideas within XOSIG, providing a first port-of-call to locate projects and those involved with them. The current source can be found at [[XOSIG IoI]], and a PDF of version 0.3.1 can be found at [http://www.xcore.com/forum/download/file.php?id=118]. Other ideas have been proposed in group postings.&lt;br /&gt;
&lt;br /&gt;
== FreeRTOS ==&lt;br /&gt;
XOSIG group member Bianco has provided a port of FreeRTOS for the XS-1 processor. This is a traditional virtualising kernel that runs multiple tasks on a single XS-1 core thread. The project is maintained at [http://www.xcore.com/projects/freertos-port].&lt;br /&gt;
&lt;br /&gt;
== PiXC ==&lt;br /&gt;
PiXC is a proposal to extend the XC programming language with mobile processes and mobile channels, loosely based on ideas from the Pi-calculus. One of its aims is to break away from the traditional &amp;quot;virtualisation&amp;quot; mechanism to create a new &amp;quot;processisation&amp;quot; paradigm for Operating Systems. The current specification can be found at [[PiXC]] and a PDF of version 0.3 is at [http://www.xcore.com/forum/download/file.php?id=118]. There has been recent discussion on version 0.3 protocol component at [http://www.xcore.com/forum/viewtopic.php?f=17&amp;amp;t=83&amp;amp;start=30].&lt;/div&gt;</description>
			<pubDate>Sat, 26 Jun 2010 13:56:01 GMT</pubDate>			<dc:creator>Jhrose</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XMOS_Operating_System_Interest_Group_(XOSIG)</comments>		</item>
		<item>
			<title>SPI spec files for use with xflash and flashlib</title>
			<link>http://www.xcore.com/wiki/index.php/SPI_spec_files_for_use_with_xflash_and_flashlib</link>
			<description>&lt;p&gt;Larry:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;On this page you can find the SPI specification files which provide the parameters needed to use XFlash and FlashLib.&lt;br /&gt;
&lt;br /&gt;
'''Current files for download:'''&lt;br /&gt;
&lt;br /&gt;
* [http://xcore.com/wiki/index.php/File:A25L40PT.txt Atmel A25L40PT]&lt;br /&gt;
* [http://xcore.com/wiki/index.php/File:EON_EN25F20.txt EON EN25F20]&lt;/div&gt;</description>
			<pubDate>Fri, 25 Jun 2010 13:15:26 GMT</pubDate>			<dc:creator>Jason</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:SPI_spec_files_for_use_with_xflash_and_flashlib</comments>		</item>
		<item>
			<title>Innovation and entrepreneurship</title>
			<link>http://www.xcore.com/wiki/index.php/Innovation_and_entrepreneurship</link>
			<description>&lt;p&gt;Jason:&amp;#32;/* Innovation and Entrepreneurship */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XMOS technology contains all the key ingredients of a great technology platform to start companies - a general technology with many applications, a receptive and in some cases rather desperate market and a helpful community for support.&lt;br /&gt;
&lt;br /&gt;
As with anything, there are hurdles that need to be overcome. &lt;br /&gt;
&lt;br /&gt;
This guide is intended as a guide for engineers with an interest in entrepreneurship - to try to explain how to overcome some of the basic hurdles and answer some common questions when you start up.&lt;br /&gt;
&lt;br /&gt;
It goes without saying on a Wiki that you take the advice at your own risk and potential peril. Those writing it have only your best interests at heart.&lt;br /&gt;
&lt;br /&gt;
== I have an idea. Now what? ==&lt;br /&gt;
&lt;br /&gt;
Right. Well the first thing is to have a good think about it from a number of basic angles. Here are the questions that are easiest to throw at it to see if it can meet some basic acid tests:&lt;br /&gt;
&lt;br /&gt;
* How long will it take to build this? How many people need to be involved? What skills do you need? Do you need extra technology, licenses or hardware?&lt;br /&gt;
* How well do you know your market? Do you know any direct customers?&lt;br /&gt;
* Is this an idea that relies on secrecy in one form or another (patents, etc)? If so, would you consider your idea worthy of a patent?&lt;br /&gt;
* What happens if someone copies you?&lt;br /&gt;
* Do you love your idea?&lt;br /&gt;
&lt;br /&gt;
The reason for the first question is obvious. If you can't answer these, you need to go and do some work - these are the basics. &lt;br /&gt;
&lt;br /&gt;
The second question is so you can go and talk to people. If you don't know anyone who wants to buy your stuff, why not? Go find them. You have no idea if you have anything useful until you have talked to potential customers. Find someone who wants to buy it...!&lt;br /&gt;
&lt;br /&gt;
The third question is getting a bit more subtle. Ideas that are based mostly on patents - and protection of some form - are often quite vulnerable, because patents are expensive and can rarely be used by a startup against anyone other than another startup. This is generic advice - your startup is a stronger proposition if it doesn't really need patents to protect itself - and instead uses its ability to get there first and keep innovating and building expertise. This ties into a point I want to make later.&lt;br /&gt;
&lt;br /&gt;
What happens if someone copies you? Well - you have to know the answer. Back to basics. What can you do? If the answer is &amp;quot;sue them&amp;quot;, give up now. Look for pricing solutions, look for product superiority. Market advantage. Etc. Work out what the barriers are to entry are, whether they make sense, how you can respond to new entrants. &lt;br /&gt;
&lt;br /&gt;
Finally, if you don't love your idea it really isn't worth it. You have to. You're going to have people far less intelligent than you telling you it's crap for a long time. Get used to it. &lt;br /&gt;
&lt;br /&gt;
So here's the final point. Ideas are not startups. Startups are not ideas. Gone are the days when one moment of ingenuity was enough to start a successful company. Ideas, models, products are too easy to copy. Streams of ideas, streams of innovation, streams of creativity are not. Try to find yourself a niche in which you can be the best in the world at something. And then keep innovating to make sure you never lose that position. &lt;br /&gt;
&lt;br /&gt;
== More Coming Soon ==&lt;/div&gt;</description>
			<pubDate>Thu, 24 Jun 2010 22:52:36 GMT</pubDate>			<dc:creator>Jonathan</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Innovation_and_entrepreneurship</comments>		</item>
		<item>
			<title>XMP-64 Group</title>
			<link>http://www.xcore.com/wiki/index.php/XMP-64_Group</link>
			<description>&lt;p&gt;Jamie:&amp;#32;added some example code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the XMP-64 group page. The aim is to gather or link to any useful related information here such as example code, guides or general tips.&lt;br /&gt;
&lt;br /&gt;
== What is the XMP-64? ==&lt;br /&gt;
&lt;br /&gt;
The XMP-64 is an experimental 64-core device. It features 16 XS1-G4 chips connected together in a hypercube topology. For more information check the offical XMOS [https://www.xmos.com/products/development-kits/xmp-64 page].&lt;br /&gt;
&lt;br /&gt;
== Performance experiments ==&lt;br /&gt;
&lt;br /&gt;
Available through the XMOS website is a '[http://www.xmos.com/published/xmp64measurements performance measurements]' document. This gives details of a number of experiments performed with the device to gain some insight into some of its characteristics, such as the time taken to deliver messages in a congested network.&lt;br /&gt;
&lt;br /&gt;
The [http://www.xcore.com/projects/xmp-64-performance-experiments source code] of the experiments is available, and is a good place to start if writing XMP-64 software for the first time.&lt;br /&gt;
&lt;br /&gt;
== Example program ==&lt;br /&gt;
&lt;br /&gt;
Here is a complete example XC program which runs one process on each of the 64 cores, 16 of which switch on an led attached to the core.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;platform.h&amp;gt;&lt;br /&gt;
#include &amp;lt;xs1.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define NUM_CORES 64&lt;br /&gt;
#define STEP      4&lt;br /&gt;
&lt;br /&gt;
out port leds[] = {&lt;br /&gt;
    on stdcore[0] : XS1_PORT_1E,&lt;br /&gt;
    on stdcore[4] : XS1_PORT_1E,&lt;br /&gt;
    on stdcore[8] : XS1_PORT_1E,&lt;br /&gt;
    on stdcore[12]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[16]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[20]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[24]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[28]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[32]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[36]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[40]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[44]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[48]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[52]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[56]: XS1_PORT_1E,&lt;br /&gt;
    on stdcore[60]: XS1_PORT_1E&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void foo(int number, out port led) {&lt;br /&gt;
    led &amp;lt;: 1;&lt;br /&gt;
    while(1) {}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void bar(int number) {&lt;br /&gt;
    while(1) {}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(char args[]) {&lt;br /&gt;
    chan c[NUM_CORES];&lt;br /&gt;
    par {&lt;br /&gt;
        par (int i=0; i&amp;lt;NUM_CORES; i+=STEP) {&lt;br /&gt;
            on stdcore[i] : foo(i, leds[i/STEP]);&lt;br /&gt;
            par (int j=1; j&amp;lt;STEP; j++)&lt;br /&gt;
                on stdcore[i+j] : bar(i+j);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 16 Jun 2010 14:36:22 GMT</pubDate>			<dc:creator>Jamie</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XMP-64_Group</comments>		</item>
		<item>
			<title>XMOS Cookbook by russf, Berni</title>
			<link>http://www.xcore.com/wiki/index.php/XMOS_Cookbook_by_russf,_Berni</link>
			<description>&lt;p&gt;Russf:&amp;#32;XMOS Cookbook overview&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is the general wiki page for XMOS Cookbook. A place to gather general information on how to get started, and how to organize modules.&lt;br /&gt;
&lt;br /&gt;
The first bundle of XMOS Cookbook code is a [http://github.com/XMOSCookbook/xmos_network_modules repackaging of XMOS's tcp/ip stack, version 1v3].  By removing version suffixes in the module names, the rebundling makes it easier to integrate those modules into other code, and then update the modules to newer versions with minimal code changes.&lt;br /&gt;
&lt;br /&gt;
It should be possible to create new GIT superprojects that compose these and other modules, to create new projects.&lt;/div&gt;</description>
			<pubDate>Wed, 09 Jun 2010 23:21:30 GMT</pubDate>			<dc:creator>Russf</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XMOS_Cookbook_by_russf,_Berni</comments>		</item>
		<item>
			<title>Fixes to Common Deprecation Warnings</title>
			<link>http://www.xcore.com/wiki/index.php/Fixes_to_Common_Deprecation_Warnings</link>
			<description>&lt;p&gt;Russf:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Release 10.04 ==&lt;br /&gt;
&lt;br /&gt;
=== Language token '''clock''' deprecated ===&lt;br /&gt;
&lt;br /&gt;
==== Example warning: ====&lt;br /&gt;
&lt;br /&gt;
 smi.h:60:15: warning: language type `clock' is deprecated&lt;br /&gt;
 smi.h:60:15: warning: clock type is now defined in xs1.h&lt;br /&gt;
&lt;br /&gt;
This occurs when clock is found, but xs1.h has not been included.&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;xs1.h&amp;quot; &lt;br /&gt;
&lt;br /&gt;
above the first occurrence of '''clock''' in a file, to prevent this warning.&lt;br /&gt;
&lt;br /&gt;
=== Use of stdcore array without -target option deprecated ===&lt;br /&gt;
&lt;br /&gt;
==== Example warning: ====&lt;br /&gt;
&lt;br /&gt;
  .././../module_ethernet/src/server/getmac.xc:52:1: warning: stdcore array used with no -target option specified.&lt;br /&gt;
&lt;br /&gt;
Suggestion&lt;br /&gt;
&lt;br /&gt;
 Suggestion here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Report switch changes - '''--show-report''' deprecated ===&lt;br /&gt;
&lt;br /&gt;
 xcc: warning: --show-report is deprecated, use -report instead&lt;br /&gt;
&lt;br /&gt;
Edit your Makefile(s) by replacing '''--show-report''' with '''-report'''&lt;/div&gt;</description>
			<pubDate>Wed, 09 Jun 2010 02:06:16 GMT</pubDate>			<dc:creator>Russf</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Fixes_to_Common_Deprecation_Warnings</comments>		</item>
		<item>
			<title>XC-1</title>
			<link>http://www.xcore.com/wiki/index.php/XC-1</link>
			<description>&lt;p&gt;Andy:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The XC-1 Development Kit was the first low-cost prototyping board from XMOS, based on the four-core XS1-G4 chip. It has been replaced by the XC-1A and is no longer sold.&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
&lt;br /&gt;
* XS1-G4 four-core 400MHz device: 1600 MIPS, 256KB RAM, 32KB OTP&lt;br /&gt;
* USB power and host debugger connection&lt;br /&gt;
* Four pushbutton and LED pairs&lt;br /&gt;
* 12 bi-colour LEDs&lt;br /&gt;
* Integrated speaker&lt;br /&gt;
* 60 pins user I/O expansion from two cores&lt;br /&gt;
* 0.1” pitch through-hole prototyping area&lt;br /&gt;
* Credit card sized (85 x 54 mm)&lt;br /&gt;
&lt;br /&gt;
== User Programming and Demo Mode ==&lt;br /&gt;
&lt;br /&gt;
When you first connect the XC-1 to the USB port on your computer, it boots from internal OTP and runs the demonstration code. To use the XC-1 in programming mode disconnect the card from the USB cable and reconnect it while holding down Button A.&lt;br /&gt;
&lt;br /&gt;
The LEDs around the buttons flash three times to indicate that the card is in&lt;br /&gt;
programming mode. The card stays in program mode until you disconnect it from the USB cable, when the XC-1 is automatically reset to its default demo state.&lt;/div&gt;</description>
			<pubDate>Thu, 03 Jun 2010 20:10:26 GMT</pubDate>			<dc:creator>Andy</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XC-1</comments>		</item>
		<item>
			<title>Using Channels in XC</title>
			<link>http://www.xcore.com/wiki/index.php/Using_Channels_in_XC</link>
			<description>&lt;p&gt;Folknology:&amp;#32;/* Channels Enable Modularisation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview of channels ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Today we are going to learn the basics about channels in the XC programming language.&lt;br /&gt;
&lt;br /&gt;
When dealing with concurrency common problems arrive with sharing data, how does one guarantee that two concurrent processes don't try to make changes to the same data at the same time. Thus if this kind of data sharing can be bypassed one of the major pitfalls of concurrent programming can be avoided. Channels represent a way for different concurrent processes to send messages to each other on a controlled fashion. Because messages are passed by value the data sharing problem does not exist. We know by simply using channels we are communicating data safely between processes. &lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The method of passing messages by channels in XC is based on the formal language [http://en.wikipedia.org/wiki/Communicating_sequential_processes Communicating Sequential Processes (CSP)]. CSP was highly influential in the design of the [http://en.wikipedia.org/wiki/Occam_(programming_language) occam programming language], which was the programming language for the INMOS [http://en.wikipedia.org/wiki/Transputer Transputer].&lt;br /&gt;
&lt;br /&gt;
== Basic Channel Usage ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Processes in XC running on Xmos are represented by threads either on the same core or on different cores, they are a universal mechanism to safely exchange data between threads. What is more the XC language has event based language constructs to enable efficient use of channels within program flow. Just like XS1 cores allow program flow based on input pin states and events, XC also enables you to alter the flow of your program based on arrival of messages or data over channels. If this were not so each thread would have to block its flow permanently until channel messages arrived. The key to the is feature of XC is the select construct when combined with an infinite loop such as While(1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
while(1){&lt;br /&gt;
select&lt;br /&gt;
  {&lt;br /&gt;
  case wait for x to happen:&lt;br /&gt;
    process(x);&lt;br /&gt;
    break;&lt;br /&gt;
  case wait for y to happen :&lt;br /&gt;
    process(y);&lt;br /&gt;
    break;&lt;br /&gt;
  default :&lt;br /&gt;
    if neither X or Y happened do this by default&lt;br /&gt;
    do_default();&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this select runs, 3 things can happen :&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;X happens and process(x) is called&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Y happens and process(y) is called&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Neither X or Y happens and thus do_default() is called&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So select means select the program flow from these possible cases depending on external events, select waits concurrently (because of the controlling while loop) for one of them to happen on a first come first served basis. Such events may be results of timers reaching values, port inputs or even channel inputs and these can be combined to create the event flow required for your solution.&lt;br /&gt;
&lt;br /&gt;
But there are some basic rules channels, ports and timers may only appear in any one case, if your case depends on the state of input from a channel, timer or port and has multiple possibilities or states, these have to be catered for in the flow of that case. This can often be achieved by adding a switch statement or if/else conditions in the flow for example here is the select statement married with a switch in order to create a light switch controller:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;platform.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#define DELAY 1000000000&lt;br /&gt;
#define ON 1&lt;br /&gt;
#define OFF 0&lt;br /&gt;
&lt;br /&gt;
port lamp = XS1_PORT_1K;&lt;br /&gt;
&lt;br /&gt;
void lamp_control_mod(chanend c, port lamp){&lt;br /&gt;
unsigned int time = 0;&lt;br /&gt;
timer t;&lt;br /&gt;
while(1){&lt;br /&gt;
select&lt;br /&gt;
  {&lt;br /&gt;
  case c :&amp;gt; msg :&lt;br /&gt;
    switch (msg) &lt;br /&gt;
      {&lt;br /&gt;
       case ON:&lt;br /&gt;
        lamp &amp;lt;: 1;&lt;br /&gt;
        t :&amp;gt; time ;&lt;br /&gt;
        time += DELAY;&lt;br /&gt;
        break;&lt;br /&gt;
       case OFF :&lt;br /&gt;
        lamp &amp;lt;: 0;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
  case when timeafter(time) : // lets save energy, someone left the light on&lt;br /&gt;
    lamp &amp;lt;: 0;&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main(void){&lt;br /&gt;
  chan c;&lt;br /&gt;
  par {&lt;br /&gt;
    test_lc_mod(c);&lt;br /&gt;
    lamp_control_mod(c,lamp);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control of the lamp's state is initially determined by messages send over channel c from a remote concurrent processes (thread) which could be on the same core or another core. The function listens to that channel for its instructions and activates or deactivates the lamp accordingly. In addition because we are environmentally friendly bunch at XCore we decided to add this neat energy saving light timer to switch the lamp off after a predetermined delay. If the light control had other responsibilities to tend to when light switching or energy saving was being actioned, we could add a default section to do such housekeeping. here an exercise to explore selects further :&lt;br /&gt;
&lt;br /&gt;
1) Our lamp controller moonlights as a an energy meter, as do all of our appliance controllers, thus when it is not busy doing its job it estimates power used. In this case the lamp is a small low powered 10 Watt LED type. add the code required so that when the controller is queried over channel c about its energy used since it started it prints out the accumulated value using a printf() statement.&lt;br /&gt;
&lt;br /&gt;
== Channels Enable Modularisation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We are assuming the test_lc_mod(c) understands the operation of lamp_control_mod and sends the relevant ON's and OFF's. By this we are asserting a contract between the 2 modules test_lc_mod and lamp_control_mod. This is an important feature of contract programming (or contracting to an interface or documented command set). It may see trivial to design a lamp controller in this way but it actually has advantages. lets replace test_lc_mod with toggle_mod and close the channel loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void toggle_switch_mod(chanend c,port button){&lt;br /&gt;
  int state = OFF;&lt;br /&gt;
  while(1){&lt;br /&gt;
    select&lt;br /&gt;
     {&lt;br /&gt;
     case button :&amp;gt; void :&lt;br /&gt;
       state = !state;&lt;br /&gt;
       c &amp;lt;: state;&lt;br /&gt;
       break;&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main(void){&lt;br /&gt;
  chan c;&lt;br /&gt;
  par {&lt;br /&gt;
    toggle_switch__mod(c,button);&lt;br /&gt;
    lamp_control_mod(c,lamp);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An because we are programming by contract and using channels the toggle switch could be on any core or thread. What's more we can interchange other standard switch modules that speak &amp;quot;lamp_control&amp;quot;, perhaps we want a factory like control switch with an on and off button, well that's simple and we don't have to touch our lamp_controller_mod:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void factory_switch_mod(chanend c,port onButton, port offButton){&lt;br /&gt;
  while(1){&lt;br /&gt;
    select&lt;br /&gt;
     {&lt;br /&gt;
     case onButton :&amp;gt; void :&lt;br /&gt;
       c &amp;lt;: ON;&lt;br /&gt;
       break;&lt;br /&gt;
     case offButton :&amp;gt; void :&lt;br /&gt;
       c &amp;lt;: OFF;&lt;br /&gt;
       break;&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
main(void){&lt;br /&gt;
  chan c;&lt;br /&gt;
  par {&lt;br /&gt;
    factory_switch__mod(c,onButton,offButton);&lt;br /&gt;
    lamp_control(c,lamp);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus we can separate concerns of our design in a modular fashion not just to distribute work across teams but also to allow reuse of modules. The channels enable these modules to operate not only on different threads but also different cores or even chips connected via Xmos Links thus.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
main(void){&lt;br /&gt;
  chan c;&lt;br /&gt;
  par {&lt;br /&gt;
    on stdcore[0] : factory_switch__mod(c,onButton,offButton);&lt;br /&gt;
    on stdcore[1] : lamp_control(c,lamp);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) We have been asked to create a new kind of automated switch module, that uses a buffered active low phototransistor and emitter pair to detect a beam of light across the doorway so that the lamp can be turned on automatically when someone walks into the room. Develop a module that speaks &amp;quot;lamp&amp;quot; to the following prototype:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto_switch_mod(chanend c, port phtoDetector, port photoEmitter){..}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) After adding the automated light switch we have been asked to improve our lamp controller by adding some intelligence to further save energy, in testing we found the lamp being switched on even in clear daylight, which of course wastes energy. Adapt the lamp controller to receive a second port in its prototype to include the output of a buffered photo transistor. When the photo transistor detects light its output is taken low, when no light is detected it is taken high. remember that the photo transistor is sensitive enough to detect the light from the lamp.&lt;br /&gt;
&lt;br /&gt;
== Dynamic Channel Usage ==&lt;br /&gt;
&lt;br /&gt;
Ok if you have got this far and completed the exercises you will have a good understanding of channel basics well done, you are now ready to get some more value from these essential features of XC. So having worked so hard to get here I think you have earned enough brownie points to play a game. But as usual we are going to play a game with channels thrown in for good measure, so lets play table tennis.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;platform.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#define END -1&lt;br /&gt;
#define PING 0&lt;br /&gt;
#define PONG 1&lt;br /&gt;
#define PINGS 5&lt;br /&gt;
&lt;br /&gt;
void ping(chanend c){&lt;br /&gt;
  int reply;&lt;br /&gt;
  c &amp;lt;: PING;&lt;br /&gt;
  for(int i = 0; i &amp;lt; PINGS; i++){&lt;br /&gt;
  select&lt;br /&gt;
    {&lt;br /&gt;
    case c :&amp;gt; reply :&lt;br /&gt;
      switch(reply)&lt;br /&gt;
	{&lt;br /&gt;
	case PONG :&lt;br /&gt;
	  printf(&amp;quot;Ping received Pong\n&amp;quot;);&lt;br /&gt;
	  c &amp;lt;: PING;&lt;br /&gt;
	  break;&lt;br /&gt;
	default :&lt;br /&gt;
	  printf(&amp;quot;Ping received unknown reply\n&amp;quot;);&lt;br /&gt;
	  break;&lt;br /&gt;
	}&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  c :&amp;gt; reply;&lt;br /&gt;
  printf(&amp;quot;Goodbye cruel Pong\n&amp;quot;);&lt;br /&gt;
  c &amp;lt;: END;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void pong(chanend c){&lt;br /&gt;
  int msg;&lt;br /&gt;
  while(1){&lt;br /&gt;
  select &lt;br /&gt;
    {&lt;br /&gt;
    case c :&amp;gt; msg :&lt;br /&gt;
      switch(msg)&lt;br /&gt;
	{&lt;br /&gt;
	case PING :&lt;br /&gt;
	  printf(&amp;quot;Pong received Ping\n&amp;quot;);&lt;br /&gt;
	  c &amp;lt;: PONG;&lt;br /&gt;
	  break;&lt;br /&gt;
	case END :&lt;br /&gt;
	  return;&lt;br /&gt;
	default :&lt;br /&gt;
	  printf(&amp;quot;Pong received unknown message\n&amp;quot;);&lt;br /&gt;
	  break;&lt;br /&gt;
      } &lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
main(void){&lt;br /&gt;
  chan c;&lt;br /&gt;
  par {&lt;br /&gt;
    pong(c);&lt;br /&gt;
    ping(c);&lt;br /&gt;
  }&lt;br /&gt;
  printf(&amp;quot;End of all Pings\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this game of table tennis we have two players Ping and Pong, Ping starts by pinging Pong and Pong responds by ponging Ping is that clear ;-)&lt;br /&gt;
&lt;br /&gt;
Both ping and pong use printc() to acknowledge that they have received ball (in the form of a message) from the other player. When you run this you should get the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pong received Ping&lt;br /&gt;
Ping received Pong&lt;br /&gt;
Pong received Ping&lt;br /&gt;
Ping received Pong&lt;br /&gt;
Pong received Ping&lt;br /&gt;
Ping received Pong&lt;br /&gt;
Pong received Ping&lt;br /&gt;
Ping received Pong&lt;br /&gt;
Pong received Ping&lt;br /&gt;
Ping received Pong&lt;br /&gt;
Pong received Ping&lt;br /&gt;
Goodbye cruel Pong&lt;br /&gt;
End of all Pings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What this shows is the use of channels in a dynamic fashion. In our previous example channels were used in the same direction; the switch always sent over the channel, the lamp always received over the channel. Well it doesn't have to work in this manner channels can be used bi-directionally, but we must take care about using them in both directions, we must keep track of which thread is sending and which thread is receiving, otherwise things go very wrong! Channels require symmetric input and output, that is for every input there must be an input, if this isn't observed it will crash the program. You can see the effects by removing the &amp;quot;c :&amp;gt; reply;&amp;quot; line recompiling and re-running, notice the resource errors you get when trying to run the program with this channel fault. There are a number of other more subtle gotchas that can happen with this dynamic channel usage try moving the first &amp;quot;c &amp;lt;PING&amp;quot; to after the for statement and see what happens. See if you can guess what is going on here.&lt;br /&gt;
&lt;br /&gt;
4) Because our xmos chip will be used in a very battery powered situation, power consumption is paramount and other devices may have a greater priority for power than lighting.  We have therefore been instructed that the switches must be power conscious and may be allocated quotas, if those quotas are reached the lamp switching should be disabled until the system is restarted to allow power to be routed to more critical devices. Thus Armed with our new dynamic channel techniques rewrite the lamp_control_module to return the power usage (over the same channel) after receiving a channel message READ (an integer value different from ON or OFF say 3). When the lamp_control module receives this it should respond to the switch_mod with the reading of power consumptionsince last READ query, rather than using printf(). Also modify the switch modules to disable the lamp usage when the consumption reaches a passed in quota. The READ requested should be generated by a timer running in the switch modules and should be polled at least once every second. Once quota is met and lamp disabled the switch module needs to printf() its status and then complete its thread along with the lamp control thread. Remember in this case the switch is in charge, it is the supervisor so things must be orchestrated with that in mind.&lt;/div&gt;</description>
			<pubDate>Thu, 03 Jun 2010 15:10:44 GMT</pubDate>			<dc:creator>Folknology</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Using_Channels_in_XC</comments>		</item>
		<item>
			<title>XMOS devices</title>
			<link>http://www.xcore.com/wiki/index.php/XMOS_devices</link>
			<description>&lt;p&gt;Russf:&amp;#32;/* G series */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XMOS devices&lt;br /&gt;
&lt;br /&gt;
== L series ==&lt;br /&gt;
* XS1-L1 - Low power 1 core processor&lt;br /&gt;
** [http://www.xmos.com/products/xs1-l-family/l1lq64 64LQFP]&lt;br /&gt;
** [http://www.xmos.com/products/xs1-l-family/l1lq128 128TQFP]&lt;br /&gt;
* XS1-L2 - Low power 2 core processor&lt;br /&gt;
** [http://www.xmos.com/products/xs1-l-family/l2qn124 124QFN]&lt;br /&gt;
&lt;br /&gt;
== G series ==&lt;br /&gt;
* XS1-G4 - 4 core processor&lt;br /&gt;
** [http://www.xmos.com/products/xs1-g-family/xs1-g4-144bga-package 144BGA]&lt;br /&gt;
** [http://www.xmos.com/products/xs1-g-family/xs1-g4-512bga-package 512BGA]&lt;br /&gt;
* XS1-G2 - 2 core processor&lt;br /&gt;
** [http://www.xmos.com/products/xs1-g-family/xs1-g2-144bga-package 144BGA]&lt;/div&gt;</description>
			<pubDate>Tue, 01 Jun 2010 15:43:39 GMT</pubDate>			<dc:creator>Otitov</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XMOS_devices</comments>		</item>
		<item>
			<title>Xtag Xtag2 and kits on Ubuntu</title>
			<link>http://www.xcore.com/wiki/index.php/Xtag_Xtag2_and_kits_on_Ubuntu</link>
			<description>&lt;p&gt;XMatt:&amp;#32;/* USB Support on other Linux distributions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ubuntu USB Support =&lt;br /&gt;
&lt;br /&gt;
This page assumes you have installed the latest version of the XMOS Development Tools (https://www.xmos.com/technology/design-tools) version 10.4 or greater. &lt;br /&gt;
&lt;br /&gt;
In order to use an XMOS development kit, XTAG or XTAG-2 based product on Ubuntu you may have to go through additional USB configuration steps in order to connect to the boards.&lt;br /&gt;
&lt;br /&gt;
Open a terminal, change directory to your tools path and run the following:&lt;br /&gt;
    source SetEnv&lt;br /&gt;
This configures your environment for the XMOS tools.&lt;br /&gt;
To detect the boards run: &lt;br /&gt;
    xrun -l&lt;br /&gt;
this will list boards recognised by the XMOS tools (10.4) connected to the USB bus.&lt;br /&gt;
&lt;br /&gt;
If you cannot see your board listed (no devices) you may need the additional steps below.&lt;br /&gt;
&lt;br /&gt;
== USB Native Driver Support ==&lt;br /&gt;
&lt;br /&gt;
USB driver support is provided natively on Linux. The method required to enable the driver, however, depends on the distribution you are using and the kernel version.&lt;br /&gt;
&lt;br /&gt;
Get your kernel versions by running:&lt;br /&gt;
    uname -r&lt;br /&gt;
You will need this information to see what kernel support for USB you have.&lt;br /&gt;
&lt;br /&gt;
=== With USBFS Support ===&lt;br /&gt;
&lt;br /&gt;
If your distribution provides usbfs support (e.g. pre kernel 2.6.31-20), follow these steps:&lt;br /&gt;
&lt;br /&gt;
1. Edit the fstab file to add usb mounting details&lt;br /&gt;
    sudo nano /etc/fstab &lt;br /&gt;
&lt;br /&gt;
Add the following lines to the end of the file:&lt;br /&gt;
&lt;br /&gt;
    none /proc/bus/usb usbfs defaults,devmode=0666 0 0&lt;br /&gt;
    none /dev/bus/usb usbfs defaults,devmode=0666 0 0&lt;br /&gt;
&lt;br /&gt;
2. Press CTRL+O to write the changes, then CTRL+X to exit&lt;br /&gt;
&lt;br /&gt;
3. Unmount the USB file systems with the following commands:&lt;br /&gt;
&lt;br /&gt;
    sudo umount /proc/bus/usb&lt;br /&gt;
    sudo umount /dev/bus/usb&lt;br /&gt;
&lt;br /&gt;
4. Remount the USB file systems with the following commands:&lt;br /&gt;
&lt;br /&gt;
    sudo mount /proc/bus/usb&lt;br /&gt;
    sudo mount /dev/bus/usb&lt;br /&gt;
&lt;br /&gt;
You should be ready to go. Use xrun as above to find your devices. If you still do not see your devices, disconnect and reconnect your devices. If you get complaints about usbfs being unsupported, or no /proc/bus/usb whilst completing the above commands you may need further steps - see the next section.&lt;br /&gt;
&lt;br /&gt;
A useful command for linux usb detective work (not XMOS-specific) is issuing the following:&lt;br /&gt;
    sudo lsusb&lt;br /&gt;
This will list all of the USB devices Linux knows are connected. By issuing this command when the device is plugged in and then repeating when it is unplugged you can see if the device is picked up or not by detecting the differences in its results.&lt;br /&gt;
&lt;br /&gt;
=== Without USBFS Support ===&lt;br /&gt;
&lt;br /&gt;
If your distribution does not support usbfs (for example Ubuntu 9.10 kernel 2.6.31-20), you need to set permissions using a udev rule. The procedure depends on the type of debug adapter you are using.&lt;br /&gt;
&lt;br /&gt;
==== External Debug Adapter (XTAG-2) ====&lt;br /&gt;
&lt;br /&gt;
Example kits are XK1, SparkFun XMOS development board and NetStamp.&lt;br /&gt;
&lt;br /&gt;
If your development board uses an external XTAG-2 debug adapter, create a file &amp;quot;/etc/udev/rules.d/99-xmos.rules&amp;quot; using your favourite editor.&lt;br /&gt;
&lt;br /&gt;
    sudo nano /etc/udev/rules.d/99-xmos.rules&lt;br /&gt;
&lt;br /&gt;
Add these lines to it:&lt;br /&gt;
&lt;br /&gt;
    SUBSYSTEM!=&amp;quot;usb|usb_device&amp;quot;, GOTO=&amp;quot;xmos_rules_end&amp;quot;&lt;br /&gt;
    ACTION!=&amp;quot;add&amp;quot;, GOTO=&amp;quot;xmos_rules_end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # 20b1:f7d1 for xmos xtag2&lt;br /&gt;
    ATTRS{idVendor}==&amp;quot;20b1&amp;quot;, ATTRS{idProduct}==&amp;quot;f7d1&amp;quot;, MODE=&amp;quot;0666&amp;quot;,&lt;br /&gt;
    SYMLINK+=&amp;quot;xtag2-%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LABEL=&amp;quot;xmos_rules_end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Use CTRL+O to write changes and CTRL+X to quit.&lt;br /&gt;
&lt;br /&gt;
To get the device to recognise the new rule, restart the udev service. This varies by distribution but for Ubuntu, you can restart udev by running:&lt;br /&gt;
&lt;br /&gt;
    sudo restart udev&lt;br /&gt;
&lt;br /&gt;
When you have restarted the udev service, disconnect and reconnect your debug adapter/board, or alternatively reboot your system. In the latter case the device will automatically pick up the revised udev rule so you do not need to unplug your device. You should now be able to see your XTAG-2 device listed by using xrun.&lt;br /&gt;
&lt;br /&gt;
==== Integrated Debug Adapter (FTDI/XTAG) ====&lt;br /&gt;
&lt;br /&gt;
Example kits include XC-2, XC-3, XC1/1A, XC5.&lt;br /&gt;
&lt;br /&gt;
If your development board uses an integrated debug adapter or an XTAG(-1), you may be able to enable the driver by adding the following to &amp;quot;/etc/udev/rules.d/98-xmos.rules&amp;quot; &lt;br /&gt;
&lt;br /&gt;
    SUBSYSTEM!=&amp;quot;usb|usb_device&amp;quot;, GOTO=&amp;quot;xmos_rules_end&amp;quot;&lt;br /&gt;
    ACTION!=&amp;quot;add&amp;quot;, GOTO=&amp;quot;xmos_rules_end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # 20b1:f7d1 for xmos xtag2&lt;br /&gt;
    ATTRS{idVendor}==&amp;quot;20b1&amp;quot;, ATTRS{idProduct}==&amp;quot;f7d1&amp;quot;, MODE=&amp;quot;0666&amp;quot;,&lt;br /&gt;
    SYMLINK+=&amp;quot;xtag2-%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # 0403:6010 for XC-1 with FTDI dual-uart chip&lt;br /&gt;
    ATTRS{idVendor}==&amp;quot;0403&amp;quot;, ATTRS{idProduct}==&amp;quot;6010&amp;quot;, MODE=&amp;quot;0666&amp;quot;,&lt;br /&gt;
    SYMLINK+=&amp;quot;xc1-%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LABEL=&amp;quot;xmos_rules_end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Providing the distribution includes the /proc/bus/usb directory, you can then bind the /dev/bus/usb directory onto /proc/bus/usb:&lt;br /&gt;
&lt;br /&gt;
    mount --bind /dev/bus/usb /proc/bus/usb&lt;br /&gt;
&lt;br /&gt;
''NOTE this step may not work, particularly if you do not have /proc/bus/usb. in which case you will also likely need the FTDI patch for the tools see below.''&lt;br /&gt;
&lt;br /&gt;
Then restart the udev service or reboot your system - see External Debug Adapter section above.&lt;br /&gt;
&lt;br /&gt;
''NOTE: The FTDI/XTAG issue (see Integrated Debug Adapater section) has been reported to FTDI Support by XMOS and we are waiting for an official release that resolves the problem, this will be included in a later tools release. In the meantime XMOS has an unofficial patched version of the device library that works on Ubuntu 9.10 kernel 2.6.31-20. If you would like a copy of the library please send a support ticket via the official XMOS support site https://www.xmos.com/support/contact that includes &amp;quot;Linux FTDI Library Request&amp;quot; in the Subject field.''&lt;br /&gt;
&lt;br /&gt;
= USB Support on other Linux distributions =&lt;br /&gt;
&lt;br /&gt;
Please visit the official XMOS knowledge base for information on development kits for Linux distributions other than Ubuntu.&lt;br /&gt;
&lt;br /&gt;
http://www.xmos.com/kbase/index.php?View=entry&amp;amp;EntryID=27&lt;/div&gt;</description>
			<pubDate>Thu, 20 May 2010 16:27:41 GMT</pubDate>			<dc:creator>Folknology</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Xtag_Xtag2_and_kits_on_Ubuntu</comments>		</item>
		<item>
			<title>Development Tools Setup Tips</title>
			<link>http://www.xcore.com/wiki/index.php/Development_Tools_Setup_Tips</link>
			<description>&lt;p&gt;Paul:&amp;#32;Created page with '== XCC Fails on Ubuntu x64? == On clean ubuntu x64_64 installs you may encounter an error similar to the following: &amp;lt;pre&amp;gt; $ xcc bash: xcc: command not found &amp;lt;/pre&amp;gt;  This is due t…'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== XCC Fails on Ubuntu x64? ==&lt;br /&gt;
On clean ubuntu x64_64 installs you may encounter an error similar to the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ xcc&lt;br /&gt;
bash: xcc: command not found&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is due to certain 32bit libraries that are required by the XMOS tools not being installed. To fix this run:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo apt-get install ia32-libs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Sun, 16 May 2010 00:05:05 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Development_Tools_Setup_Tips</comments>		</item>
		<item>
			<title>Inline Assembly</title>
			<link>http://www.xcore.com/wiki/index.php/Inline_Assembly</link>
			<description>&lt;p&gt;Paul:&amp;#32;Created page with '== Example of Streaming Channel Inline Assembly functions == This is an example of a header (.h) file that allows interaction with streaming channels.  '''NOTE:''' The reason it …'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Example of Streaming Channel Inline Assembly functions ==&lt;br /&gt;
This is an example of a header (.h) file that allows interaction with streaming channels.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The reason it is in a header file is that the compiler will not inline the function if it is used across modules. Putting it in a .h file gives the compiler every chance inline it! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef STREAMING_CHANS_H_&lt;br /&gt;
#define STREAMING_CHANS_H_&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;xs1.h&amp;gt;&lt;br /&gt;
#include &amp;lt;xccompat.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef __XC__&lt;br /&gt;
inline static unsigned streaming_chan_inuint(streaming chanend c)&lt;br /&gt;
#else&lt;br /&gt;
inline static unsigned streaming_chan_inuint(chanend c)&lt;br /&gt;
#endif&lt;br /&gt;
{&lt;br /&gt;
  unsigned value;&lt;br /&gt;
  __asm__ __volatile__ (&lt;br /&gt;
    &amp;quot;in %0, res[%1]&amp;quot; :&lt;br /&gt;
    &amp;quot;=r&amp;quot;(value) :&lt;br /&gt;
    &amp;quot;r&amp;quot;(c)&lt;br /&gt;
  );&lt;br /&gt;
  return value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#ifdef __XC__&lt;br /&gt;
inline static void streaming_chan_outuint(streaming chanend c, unsigned value)&lt;br /&gt;
#else&lt;br /&gt;
inline static void streaming_chan_outuint(chanend c, unsigned value)&lt;br /&gt;
#endif&lt;br /&gt;
{&lt;br /&gt;
  __asm__ __volatile__ (&lt;br /&gt;
    &amp;quot;out res[%0], %1&amp;quot; :&lt;br /&gt;
    /* no outputs */ :&lt;br /&gt;
    &amp;quot;r&amp;quot;(c), &amp;quot;r&amp;quot;(value)&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#ifdef __XC__&lt;br /&gt;
inline static unsigned char streaming_chan_inuchar(streaming chanend c)&lt;br /&gt;
#else&lt;br /&gt;
inline static unsigned char streaming_chan_inuchar(chanend c)&lt;br /&gt;
#endif&lt;br /&gt;
{&lt;br /&gt;
  unsigned value;&lt;br /&gt;
  __asm__ __volatile__ (&lt;br /&gt;
    &amp;quot;int %0, res[%1]&amp;quot; :&lt;br /&gt;
    &amp;quot;=r&amp;quot;(value) :&lt;br /&gt;
    &amp;quot;r&amp;quot;(c)&lt;br /&gt;
  );&lt;br /&gt;
  return value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#ifdef __XC__&lt;br /&gt;
inline static void streaming_chan_outuchar(streaming chanend c, unsigned char value)&lt;br /&gt;
#else&lt;br /&gt;
inline static void streaming_chan_outuchar(chanend c, unsigned char value)&lt;br /&gt;
#endif&lt;br /&gt;
{&lt;br /&gt;
  __asm__ __volatile__ (&lt;br /&gt;
    &amp;quot;outt res[%0], %1&amp;quot; :&lt;br /&gt;
    /* no outputs */ :&lt;br /&gt;
    &amp;quot;r&amp;quot;(c), &amp;quot;r&amp;quot;(value)&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif /*STREAMING_CHANS_H_*/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Sun, 16 May 2010 00:00:58 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Inline_Assembly</comments>		</item>
		<item>
			<title>XCore Soft Reset</title>
			<link>http://www.xcore.com/wiki/index.php/XCore_Soft_Reset</link>
			<description>&lt;p&gt;Andy:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes how to reset an XCore chip utilising software.&lt;br /&gt;
&lt;br /&gt;
Any writes to the PLL Control Register (register 6 on the L and G series) cause the chip to reset and reboot, even if the value is unchanged.  Access functions are provided in the xs1.h header file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;xs1.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void chipReset(void)&lt;br /&gt;
{&lt;br /&gt;
  unsigned x;&lt;br /&gt;
  &lt;br /&gt;
  read_sswitch_reg(get_core_id(), 6, x);&lt;br /&gt;
  write_sswitch_reg(get_core_id(), 6, x);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: This method will not cause the [[XC-1]] Development Kit to fully reset. The program must still be reset from the XDE.&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 23:54:26 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:XCore_Soft_Reset</comments>		</item>
		<item>
			<title>Programming Ports in XC</title>
			<link>http://www.xcore.com/wiki/index.php/Programming_Ports_in_XC</link>
			<description>&lt;p&gt;Paul:&amp;#32;Created page with 'This page describes how to utilise ports and their features in XC along with simple worked examples.  == Basic Port Use ==  == Configuring Clocked Ports ==  == Configuring Ports …'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes how to utilise ports and their features in XC along with simple worked examples.&lt;br /&gt;
&lt;br /&gt;
== Basic Port Use ==&lt;br /&gt;
&lt;br /&gt;
== Configuring Clocked Ports ==&lt;br /&gt;
&lt;br /&gt;
== Configuring Ports with Handshaking ==&lt;br /&gt;
&lt;br /&gt;
== Unorthodox port usage ==&lt;br /&gt;
This section handles things that are possible with ports that might be considered 'unorthodox'.&lt;br /&gt;
&lt;br /&gt;
=== Outputting the inverted output of another 1 bit port ===&lt;br /&gt;
By utilising a clock block a developer is able to output the inverse of a 1 bit port on another 1 bit port without needing to write to the port (NOTE: this only works with 1 bit ports and will use 1 clock block).&lt;br /&gt;
&lt;br /&gt;
This can be configured using the following code block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void setup_inverted_port( out port p, out port p_inv, clock c )&lt;br /&gt;
{&lt;br /&gt;
   // set port p as the source for clock block c&lt;br /&gt;
   set_clock_src (c, p); &lt;br /&gt;
&lt;br /&gt;
   // set port p_inv to be attached to the clock block c&lt;br /&gt;
   set_port_clock (p_inv, c);&lt;br /&gt;
&lt;br /&gt;
   // set port p_inv to output the clock block c&lt;br /&gt;
   set_port_mode_clock (p_inv);&lt;br /&gt;
&lt;br /&gt;
   // start the clock block and therefore the inverted output&lt;br /&gt;
   start_clock( c );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 23:35:25 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Programming_Ports_in_XC</comments>		</item>
		<item>
			<title>Programming in XC</title>
			<link>http://www.xcore.com/wiki/index.php/Programming_in_XC</link>
			<description>&lt;p&gt;Paul:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XC is a C like language developed by XMOS that has a feature set to allow easy access to many of the XMOS architecture's novel aspects.&lt;br /&gt;
&lt;br /&gt;
As part of this feature set XC has syntax for the direct use of channels, ports, timers without the need for calling complex (and ugly!) API functions.&lt;br /&gt;
&lt;br /&gt;
XC is designed to be a 'safe' language to help the developer avoid many of the potential pitfalls associated with more 'less safe' languages such as C. Some of the safeguards include automatic array bounds checking and not allowing the use of pointers or shared memory within XC.&lt;br /&gt;
&lt;br /&gt;
For a user's first interaction with XC XMOS recommends the tutorials that are part of the XMOS development environment (XDE) and for a more comprehensive look at the XC language XMOS have published ''Programming XC on XMOS Devices'' which is available for free download [http://www.xmos.com/system/files/xcuser_en.pdf] or for purchase as a printed book [http://www.xmos.com/products/documentation/programming-xc-xmos-devices].&lt;br /&gt;
&lt;br /&gt;
* [[Programming Ports in XC]]&lt;br /&gt;
* [[Using Channels in XC]]&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 23:23:38 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Programming_in_XC</comments>		</item>
		<item>
			<title>Calling functions that have pointer arguments</title>
			<link>http://www.xcore.com/wiki/index.php/Calling_functions_that_have_pointer_arguments</link>
			<description>&lt;p&gt;Paul:&amp;#32;Created page with 'If you have a C function that requires a pointer (such as one that access an array) you may want to call it from XC. As XC does not support pointers, some minor modifications wil…'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have a C function that requires a pointer (such as one that access an array) you may want to call it from XC. As XC does not support pointers, some minor modifications will be needed for your header files.&lt;br /&gt;
&lt;br /&gt;
An example function such as the one below needs to be called from XC:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo( char *bar, unsigned *n )&lt;br /&gt;
{&lt;br /&gt;
  /*... access array */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following declaration should be made in the appropriate header file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef __XC__&lt;br /&gt;
void foo( char bar[], unsigned &amp;amp;n );&lt;br /&gt;
#else&lt;br /&gt;
void foo( char *bar, unsigned *n );&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will then allow you to pass a char array and integer by reference.&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 23:11:05 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Calling_functions_that_have_pointer_arguments</comments>		</item>
		<item>
			<title>Programming in C</title>
			<link>http://www.xcore.com/wiki/index.php/Programming_in_C</link>
			<description>&lt;p&gt;Paul:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Programming in C for an XMOS device is very much like programming for any other platform. The main difference is that access to ports, channels and such like is not via the memory map. Accessing these resources requires calling custom XC functions or implementing custom inline assembly.&lt;br /&gt;
&lt;br /&gt;
C/C++ and XC can be mixed. This can be useful when porting existing code or when you want to utilise pointers or such like.&lt;br /&gt;
&lt;br /&gt;
For more information see:&lt;br /&gt;
&lt;br /&gt;
[[Using channels and ports in C/C++]]&lt;br /&gt;
&lt;br /&gt;
[[Calling functions that have pointer arguments]]&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 23:02:09 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Programming_in_C</comments>		</item>
		<item>
			<title>Development Tools</title>
			<link>http://www.xcore.com/wiki/index.php/Development_Tools</link>
			<description>&lt;p&gt;Kris:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is the main portal for information about the XMOS development tools and their use.&lt;br /&gt;
&lt;br /&gt;
The current XMOS development tools can be downloaded here [https://www.xmos.com/technology/design-tools]&lt;br /&gt;
&lt;br /&gt;
The main XMOS documents covering use of the tools can be found here [http://www.xmos.com/support/documentation]&lt;br /&gt;
&lt;br /&gt;
The source for open parts of the XMOS tool chain is available from [https://www.xmos.com/technology/design-tools-source]&lt;br /&gt;
&lt;br /&gt;
* [[Programming in XC]]&lt;br /&gt;
** [[Programming Ports in XC]]&lt;br /&gt;
** [[Using Channels in XC]]&lt;br /&gt;
** [[Fixes to Common Deprecation Warnings]]&lt;br /&gt;
&lt;br /&gt;
* [[Programming in C]]&lt;br /&gt;
** [[C Compiler]]&lt;br /&gt;
** [[Using channels and ports in C/C++]]&lt;br /&gt;
** [[Calling functions that have pointer arguments]]&lt;br /&gt;
* [[Programming in Assembly]]&lt;br /&gt;
** [[Inline Assembly]]&lt;br /&gt;
* [[Development Tools Setup Tips]]&lt;br /&gt;
** [[Xtag Xtag2 and kits on Ubuntu]]&lt;br /&gt;
* Useful Techniques and Examples&lt;br /&gt;
** [[Active Energy Conservation (AEC)]]&lt;br /&gt;
** [[XCore Soft Reset]]&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 23:01:51 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Development_Tools</comments>		</item>
		<item>
			<title>Using channels and ports in C/C++</title>
			<link>http://www.xcore.com/wiki/index.php/Using_channels_and_ports_in_C/C%2B%2B</link>
			<description>&lt;p&gt;Jamie:&amp;#32;Added name mangling section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Currently ports and channel interaction in C or C++ has to be achieved by the user writing their own XC functions that can handle the various operations they require. These XC functions can then be called from C or C++ when needed.&lt;br /&gt;
&lt;br /&gt;
== Channel and Port Types in C/C++ ==&lt;br /&gt;
&lt;br /&gt;
You can have a channel as an argument to a C function by using the 'xccompat.h' include. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;xccompat.h&amp;gt;&lt;br /&gt;
#include &amp;quot;channel_funcs.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void c_func( chanend c )&lt;br /&gt;
{&lt;br /&gt;
    unsigned v;&lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
        xc_channel_out(c, v);&lt;br /&gt;
        v = xc_channel_in( c );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where the channel interaction functions would be defined in 'channel_funcs.xc' such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void xc_channel_out(chanend c, unsigned v)&lt;br /&gt;
{&lt;br /&gt;
    c &amp;lt;: v;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Name mangling===&lt;br /&gt;
&lt;br /&gt;
To avoid name mangling with C++, you need to give the C++ functions called from XC, C linkage. For example, the header 'channel_funcs.h', for the C++ file channel_funcs.ccp would be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
extern &amp;quot;C&amp;quot; {&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void cpp_func(chanend c);&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For more information on mixing C and C++ see [http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html].&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 22:56:58 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:Using_channels_and_ports_in_C/C%2B%2B</comments>		</item>
		<item>
			<title>C Compiler</title>
			<link>http://www.xcore.com/wiki/index.php/C_Compiler</link>
			<description>&lt;p&gt;Paul:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We have a C/C++ compiler based on LLVM, [http://llvm.org], [http://en.wikipedia.org/wiki/Llvm]&lt;br /&gt;
&lt;br /&gt;
The C compiler comes as part of the XMOS tool chain and the source for LLVM based tool set is available from XMOS [https://www.xmos.com/technology/design-tools-source].&lt;br /&gt;
&lt;br /&gt;
The C compiler has available to it the standard C libaries such as stdlib, stdio etc.&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 22:49:42 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:C_Compiler</comments>		</item>
		<item>
			<title>AEC</title>
			<link>http://www.xcore.com/wiki/index.php/AEC</link>
			<description>&lt;p&gt;Paul:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When all of the active threads on an XCore are paused your XCore is idle. Active Energy Conservation (AEC) reduces the clock rate when this occurs and can save 80% of the dynamic power when enabled. AEC is simple to enable during an application's initialization routine and is completely automatic once enabled.&lt;br /&gt;
&lt;br /&gt;
Read the AEC app note for more details [http://www.xmos.com/system/files/xs1lengconserve.pdf]&lt;/div&gt;</description>
			<pubDate>Sat, 15 May 2010 22:45:19 GMT</pubDate>			<dc:creator>Paul</dc:creator>			<comments>http://www.xcore.com/wiki/index.php/Talk:AEC</comments>		</item>
	</channel>
</rss>