<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://rtime.felk.cvut.cz/hw/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hamacl1</id>
	<title>HW wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://rtime.felk.cvut.cz/hw/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hamacl1"/>
	<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php/Special:Contributions/Hamacl1"/>
	<updated>2026-05-24T08:08:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3124</id>
		<title>Boa5200 HOWTO</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3124"/>
		<updated>2007-11-04T15:53:18Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* SDO and PDO example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This document describes how to install and setup Linux and development environment for BOA5200  board. &lt;br /&gt;
Assume that you have a development machine (your PC) that you use for development and building your applications which you consequently want to get running and test on BOA5200.&lt;br /&gt;
&lt;br /&gt;
==Serial line setting==&lt;br /&gt;
The easiest way to communicate with the board ,when there is no OS and remote shell running on it, is over serial line. Recommended serial communication program is minicom. Setup minicom as follows:&lt;br /&gt;
&lt;br /&gt;
Baud Rate – 38400&lt;br /&gt;
&lt;br /&gt;
Bits - 8&lt;br /&gt;
&lt;br /&gt;
Parity – N&lt;br /&gt;
&lt;br /&gt;
Stop Bits - 1&lt;br /&gt;
&lt;br /&gt;
Hardware Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
Software Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
After the setup you will see Redboot&amp;gt; command prompt. Here you can enter Redboot`s commands.&lt;br /&gt;
Redboot is a simple boot manager bulit upon eCos real-time OS. For more details , see http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html.&lt;br /&gt;
&lt;br /&gt;
==DHCP server setup==&lt;br /&gt;
Redboot supports BOOTP protocol which means that it is able to get network information(IP,netmask,gateway IP address,etc.) from DHCP server(provides BOOTP besides DHCP protocol). Install dhcp server (on debian: apt-get install dhcpd) on your development machine. Example of my dhcp configuration file /etc/dhcpd.conf:&lt;br /&gt;
 # I have two ethernet interfaces: &lt;br /&gt;
 # eth0 - Internet&lt;br /&gt;
 # eth1 - connection to BOA5200 (IP= 192.168.10.1)&lt;br /&gt;
 # I do not want to progate infos to 147.32.0.0 subnetwork&lt;br /&gt;
 subnet 147.32.0.0 netmask 255.255.0.0 {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 # private subnetwork&lt;br /&gt;
 subnet 192.168.10.0 netmask 255.255.255.0 {&lt;br /&gt;
  option broadcast-address 192.168.10.255;&lt;br /&gt;
  option routers 192.168.10.1;&lt;br /&gt;
  option subnet-mask 255.255.255.0;&lt;br /&gt;
  default-lease-time 600;&lt;br /&gt;
  max-lease-time 7200;&lt;br /&gt;
 &lt;br /&gt;
 # settings for BOA5200&lt;br /&gt;
  host BOA5200 {&lt;br /&gt;
   hardware ethernet 00:08:f1:11:22:33;&lt;br /&gt;
   fixed-address 192.168.10.2;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dhcp server and reboot the board. After booting it has assigned IP, netmask and gateway address:&lt;br /&gt;
 +PHY0: AMD AM79C874&lt;br /&gt;
 FEC eth0: 100Mb/Full Duplex&lt;br /&gt;
 Ethernet eth0: MAC address 00:08:f1:11:22:33&lt;br /&gt;
 IP: 192.168.10.2/255.255.255.0, Gateway: 192.168.10.1&lt;br /&gt;
 Default server: 192.168.10.1&lt;br /&gt;
&lt;br /&gt;
==TFTP server setup==&lt;br /&gt;
Redboot is able to load file from remote tftp server into memory. Tftp server is lanuched by inetd daemon when a new &lt;br /&gt;
connection comes. &lt;br /&gt;
Therefore add the following line into /etc/inetd.conf :&lt;br /&gt;
 tftp            dgram   udp     wait    nobody  /usr/sbin/tcpd  /usr/sbin/in.tftpd&lt;br /&gt;
&lt;br /&gt;
Default tftp root directory is /tftpboot. You can change it by calling in.tftpd with specified directory as a parameter.&lt;br /&gt;
&lt;br /&gt;
===Alternative way for Ubuntu based distro===&lt;br /&gt;
&lt;br /&gt;
1. Install tftpd and related packages.&lt;br /&gt;
 sudo apt-get install xinetd tftpd tftp&lt;br /&gt;
&lt;br /&gt;
2. Create /etc/xinetd.d/tftp and put this entry:&lt;br /&gt;
&lt;br /&gt;
 service tftp&lt;br /&gt;
 {&lt;br /&gt;
 protocol        = udp&lt;br /&gt;
 port            = 69&lt;br /&gt;
 socket_type     = dgram&lt;br /&gt;
 wait            = yes&lt;br /&gt;
 user            = nobody&lt;br /&gt;
 server          = /usr/sbin/in.tftpd&lt;br /&gt;
 server_args     = /tftpboot&lt;br /&gt;
 disable         = no&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
3. Make /tftpboot directory&lt;br /&gt;
&lt;br /&gt;
 sudo mkdir /tftpboot&lt;br /&gt;
 sudo chmod -R 777 /tftpboot&lt;br /&gt;
 sudo chown -R nobody /tftpboot&lt;br /&gt;
&lt;br /&gt;
4. Start tftpd through xinetd&lt;br /&gt;
&lt;br /&gt;
 sudo /etc/init.d/xinetd start&lt;br /&gt;
&lt;br /&gt;
see [[http://www.example.com Installing and setting TFTPD in Ubuntu]]&lt;br /&gt;
&lt;br /&gt;
==Tool chain==&lt;br /&gt;
Toolchain(gcc, ld, ...) for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Unpack the archive:&lt;br /&gt;
&lt;br /&gt;
 cd /&lt;br /&gt;
 tar xvzf gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
&lt;br /&gt;
You can also create a debian package from archive and then install the package:&lt;br /&gt;
 alien --to-deb gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Note: If you are not root, use fakeroot to run the command.&lt;br /&gt;
&lt;br /&gt;
==Applying kernel patches==&lt;br /&gt;
It is recommended to use [http://linux.die.net/man/1/quilt quilt] tool to manage series of patches.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mini-Howto:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Assuming kernel sources are in directory /usr/src/linux.&lt;br /&gt;
&lt;br /&gt;
1. cd /usr/src/linux&lt;br /&gt;
&lt;br /&gt;
2. mkdir patches&lt;br /&gt;
&lt;br /&gt;
3. Copy all patches you want to apply to &#039;&#039;patches&#039;&#039; subdirectory&lt;br /&gt;
&lt;br /&gt;
4. Create &#039;&#039;series&#039;&#039; file in &#039;&#039;patches&#039;&#039; subdirectory and write names of patch files each on separate line. The order &lt;br /&gt;
the patches are stated in the file is significant!! The patch on the first line will be applied first followed by others.&lt;br /&gt;
&lt;br /&gt;
4. &#039;&#039;quilt push&#039;&#039; (&#039;&#039;quilt pop&#039;&#039;)  - applies (unapplies) all patches in &#039;&#039;series&#039;&#039; file&lt;br /&gt;
&lt;br /&gt;
==Building kernel==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.4 kernel sources&#039;&#039;&#039; for MPC5200 can be found in &#039;&#039;eCos_Linux_boa5200/tgz&#039;&#039; directory on BOARD DOCUMENTATION CD or from ftp://rtime.felk.cvut.cz/MPC5200/kernel_2.4/linuxppc-2.4-boa5200-release_2006_05_10.tgz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.6 Kernel sources&#039;&#039;&#039; for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/linuxppc-2.6.18-1_AM.tar.gz.&lt;br /&gt;
Default kernel configuration file is ftp://rtime.felk.cvut.cz/MPC5200/config-2.6.18-1_AM.&lt;br /&gt;
Do not forget to set ARCH and CROSS_COMPILE variables to this values in Makefile:&lt;br /&gt;
 ARCH=ppc&lt;br /&gt;
 CROSS_COMPILE=powerpc-603e-linux-gnu-&lt;br /&gt;
&lt;br /&gt;
After compilation a built image is placed into arch/ppc/boot/image directory.&lt;br /&gt;
&lt;br /&gt;
The following commnad will install modules into &#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039;/lib/modules/...&lt;br /&gt;
 make INSTALL_MOD_PATH=&#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039; modules_install   &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Make the building directory linuxppc-2.6.18-1_AM_build, where object files will be placed, outside the origin source directory linuxppc-2.6.18-1_AM&lt;br /&gt;
&lt;br /&gt;
 mkdir linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
2. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM &lt;br /&gt;
linuxppc-2.6.18-1_AM directory must be clean i.e. no make, make menuconfig executed from this directory&lt;br /&gt;
before!&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
 make O=../linuxppc-2.6.18-1_AM_build menuconfig  &lt;br /&gt;
kernel config file (.config) will be created in   linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
Next time, always run make menuconfig always from the building directory, i.e. linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
4. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
5. &lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/GNUmakefile&lt;br /&gt;
&lt;br /&gt;
6. &lt;br /&gt;
Edit GNUmakefile and change paths in KERNELSRC and KERNELOUTPUT variables&lt;br /&gt;
&lt;br /&gt;
7. &lt;br /&gt;
 make &amp;amp;&amp;amp; make modules_install&lt;br /&gt;
&lt;br /&gt;
== Loading kernel ==&lt;br /&gt;
&lt;br /&gt;
You can test your new image on the board as follows:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
   RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 &lt;br /&gt;
 # execute image; root directory (/) is on flash memory&lt;br /&gt;
   RedBoot&amp;gt; exec&lt;br /&gt;
If you want to load the kernel from different TFTP server than the one provided by DHCP, you can use the following command to set the IP address of your server:&lt;br /&gt;
   RedBoot&amp;gt; ip_address -h 147.32.86.&amp;lt;xxx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CAUTION:&#039;&#039;&#039; you must boot the kernel by  RedBoot release at least 2007_02_01 otherwise it will not run! So you must load into RAM and then run the appropriate RedBoot image (or replace/update its image on flash with the new one - see  &lt;br /&gt;
the next section) and after then you can execute kernel image.&lt;br /&gt;
&lt;br /&gt;
==Updating RedBoot==&lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/MPC5200-2007.02.01-redbootROMRAM.srec &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # load RedBoot image from tftp server into memory at the address 0x100000&lt;br /&gt;
 RedBoot&amp;gt;lo -b 0x100000 MPC5200-2007.02.01-redbootROMRAM.srec&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # write image in flash memory&lt;br /&gt;
 RedBoot&amp;gt;fi cr RedBoot&lt;br /&gt;
 RedBoot&amp;gt;reset&lt;br /&gt;
&lt;br /&gt;
If upgrade fails you can fallback to ROM Redboot image by typing &#039;A&amp;amp;M:&#039;&lt;br /&gt;
&lt;br /&gt;
If image of ROMRAM version of RedBoot with name &amp;quot;RedBoot&amp;quot; (case sensitive!!) is not found in FLASH minimal version of ROM RedBoot is started. This version does not support many services like TFTP protocol and FLASH management. To download ROMRAM version of RedBoot to FLASH it is necessary to follow these steps:&lt;br /&gt;
&lt;br /&gt;
Load RAM version of RedBoot to BOA using xmodem (the image file MPC5200-2006.05.10-redbootRAM.srec is placed on BOA original CD):&lt;br /&gt;
 RedBoot&amp;gt; lo -m xmodem&lt;br /&gt;
&lt;br /&gt;
When finished RedBoot should answer with something like that:&lt;br /&gt;
&lt;br /&gt;
 CEntry point: 0x00080100, address range: 0x00080000-0x000bea04&lt;br /&gt;
 xyzModem - CRC mode, 5763(SOH)/0(STX)/0(CAN) packets, 1 retries&lt;br /&gt;
&lt;br /&gt;
Then start the RedBoot:&lt;br /&gt;
 RedBoot&amp;gt; go&lt;br /&gt;
&lt;br /&gt;
RAM RedBoot should start now. Download the new version of ROMRAM RedBoot to FLASH according to the steps above.&lt;br /&gt;
&lt;br /&gt;
==NFS-root setup==&lt;br /&gt;
&lt;br /&gt;
During the development phase of application it must be tested many times. However, it is annoying to copy several application files to flash memory every time.  The practical solution is to mount via NFS working directory or whole root directory from the point of OS running on the board.&lt;br /&gt;
&lt;br /&gt;
You can download already prepared root directory from ftp://rtime.felk.cvut.cz/MPC5200/MPC5200_root_070321.tar.gz&lt;br /&gt;
&lt;br /&gt;
To export /var/MPC5200_root directory via NFS add the following line to /etc/exports:&lt;br /&gt;
&lt;br /&gt;
 /var/MPC5200_root 192.168.10.0/255.255.255.0(rw,sync,no_root_squash)&lt;br /&gt;
&lt;br /&gt;
Then run command &#039;exportfs -ra&#039; so that the change take an effect.&lt;br /&gt;
&lt;br /&gt;
If you want MPC5200 to be mount as root directory instead of that one in flash memory:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
  RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 # execute kernel image with information where to &lt;br /&gt;
 # find root directory in parameter string&lt;br /&gt;
  RedBoot&amp;gt; ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.10.1:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: exportfs is a part of knfs package for debian systems (ubuntu,...)&lt;br /&gt;
&lt;br /&gt;
== Login with telnet ==&lt;br /&gt;
 telnet &amp;lt;ip address of boa&amp;gt;&lt;br /&gt;
Log in as root, ask me for the password. --[[User:Sojka|Sojka]] 20:42, 21 March 2007 (CET)&lt;br /&gt;
==Setting up BOA5200==&lt;br /&gt;
&lt;br /&gt;
Use &#039;fconfig&#039; command (see http://ecos.sourceware.org/ecos/docs-latest/redboot/persistent-state-flash.html manual) to set up BOA5200 configuration. Recommended configuration:&lt;br /&gt;
&lt;br /&gt;
 Run script at boot: true&lt;br /&gt;
 Boot script:&lt;br /&gt;
  load zImage.elf&lt;br /&gt;
  ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.123.254:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
 Boot script timeout (1000ms resolution): 10 &lt;br /&gt;
 Use BOOTP for network configuration: true&lt;br /&gt;
 Default server IP address: IP address of your computer&lt;br /&gt;
 FEC Network hardware address [MAC]: choose MAC address of the unit (example: 0x00:0x00:0x00:0x00:0x00:0x02)&lt;br /&gt;
 GDB connection port: 9000&lt;br /&gt;
 Force console for special debug messages: false&lt;br /&gt;
 Network debug at boot time: false&lt;br /&gt;
 Update RedBoot non-volatile configuration - continue (y/n)? y&lt;br /&gt;
&lt;br /&gt;
==Socketcan==&lt;br /&gt;
&lt;br /&gt;
Prior to compiling linux kernel with socketcan driver, it is necessary to [http://rtime.felk.cvut.cz/hw/index.php/HOWTO#Applying_kernel_patches  apply kernel patches] , which can be found in [http://rtime.felk.cvut.cz/repos/boa5200-linux/patches/ DARCS repository]&lt;br /&gt;
&lt;br /&gt;
To set up can interface, it is necessary to configure the communication speed first and then bring the interface up. Communication speed can be set up using following command (for can0 interface):&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
&lt;br /&gt;
The constant 660000 was found experimentally, driver seems to calculate the transmission speed improperly. To bring up the can network interface, use the same command as with any other network interface, i.e.&lt;br /&gt;
&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
&lt;br /&gt;
The most comfortable way of setting up both can interfaces upon startup of system is to place following script to /etc/init.d/ (name it &#039;can&#039;, for example)&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can1/can_baudrate&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
 ifconfig can1 up&lt;br /&gt;
&lt;br /&gt;
==CanFestival==&lt;br /&gt;
&lt;br /&gt;
===Obtaining and building CanFestival===&lt;br /&gt;
&lt;br /&gt;
CanFestival driver source can be downloaded from. The primary way how to do it is to check out the source directory from CanFestival CVS by these steps:&lt;br /&gt;
 cvs -d:pserver:anonymous@lolitech.dyndns.org:/canfestival login&lt;br /&gt;
 (type return, without entering a password)&lt;br /&gt;
The system will respond:&lt;br /&gt;
 Logging in to :pserver:anonymous@lolitech.dyndns.org:2401/canfestival&lt;br /&gt;
Then, enter:&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@lolitech.dyndns.org:/canfestival co -P CanFestival-3&lt;br /&gt;
Then insert CanFestival folder and run this commands:&lt;br /&gt;
 ./configure --timers=unix --can=socket --cc=powerpc-603e-linux-gnu-gcc --arch=ppc --os=linux --target=unix &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
Building of CanFestival will produce some libraries and copy them to /usr/powerpc-603e-linux-gnu/lib folder.&lt;br /&gt;
&lt;br /&gt;
===Setting up local CANopen node===&lt;br /&gt;
&lt;br /&gt;
CanFestival source includes tool called &#039;&#039;objdictedit&#039;&#039;. This program has graphical user interface and serves to creating configuration of the CANopen node of application we develop. It is started by command &#039;&#039;objdictedit&#039;&#039;. Using this program you can create the object dictionary for the CanFestival. Mainly it is necessary to set up all SDO and PDO, the node has to send and receive. To each PDO you have to define more things - PDO receive or transmit, variable to be mapped and variable mapping. The variable will then be used in application code to exchange data between CanFestival driver and application. If you set up PDOs here they will be sent and received automatically and the values will be stored into mapped variable. Setting up SDO means that you can use it in your application, but if you want to send it, it has to be done in code.&lt;br /&gt;
After creating this basic configuration you have to build the dictionary which results into to files with extensions .h and .c. You have to link these files with your application.&lt;br /&gt;
&lt;br /&gt;
===Initializing and starting CanFestival===&lt;br /&gt;
&lt;br /&gt;
To explain how to use CanFestival I include some code examples. It supposes node configuration generated by &#039;&#039;objdictedit&#039;&#039; which name is &#039;&#039;canopen&#039;&#039;. It is then used as prefix of automatically generated functions and variables (&#039;&#039;canopen_Data&#039;&#039; is for example object dictionary used by CanFestival). &lt;br /&gt;
Header &#039;&#039;canfestival.h&#039;&#039; has to be included. For start using CanFestival it is necessary to load dynamic library with CAN bus driver API created while compiling CanFestival source. In the example SocketCan driver is used to access CAN bus. &lt;br /&gt;
 if(!LoadCanDriver(&amp;quot;libcanfestival_can_socket.so&amp;quot;)) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
Then you have to open CAN device. Parameters of the communication have to be prepared in structure of type &#039;&#039;s_Board&#039;&#039;. In this case CAN is set to use device &#039;&#039;can1&#039;&#039; and baudrate 1Mbps. Handler of the bus is then stored to variable of type &#039;&#039;CAN_HANDLE&#039;&#039;.&lt;br /&gt;
 /**&lt;br /&gt;
  * CAN board definition.&lt;br /&gt;
  * Device name can1, baudrate 1M&lt;br /&gt;
  */&lt;br /&gt;
 s_BOARD canopen_board = {&amp;quot;1&amp;quot;, &amp;quot;1000&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
 CAN_HANDLE canopen_handle;&lt;br /&gt;
 &lt;br /&gt;
 if(!(canopen_handle = canOpen(&amp;amp;canopen_board, &amp;amp;canopen_Data))) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
CanFestival implements callbacks to some events like change of state or message reception. There are pointers to callback functions in &#039;&#039;canopen_Data&#039;&#039; structure. You can assign your own functions to these pointers or leave them unused.&lt;br /&gt;
 canopen_Data.initialisation = canopen_initialisation;&lt;br /&gt;
 canopen_Data.preOperational = canopen_preOperational; &lt;br /&gt;
 canopen_Data.operational = canopen_operational; &lt;br /&gt;
 canopen_Data.post_sync = canopen_post_sync; &lt;br /&gt;
 canopen_Data.post_TPDO = canopen_post_TPDO; &lt;br /&gt;
 canopen_Data.stopped = canopen_stopped; &lt;br /&gt;
After setting up these few things you have to call function &#039;&#039;StartTimerLoop&#039;&#039; which initializes CanFestival timers. As an argument you have to insert pointer to the first function you want to proceed after starting the timers. &lt;br /&gt;
 StartTimerLoop(&amp;amp;initNode); &lt;br /&gt;
Here is an example of such a function. It sets local node ID to 1 and bring the node to operation state. Callback functions are called after changing state if used.&lt;br /&gt;
 void initNode(CO_Data * d, UNS32 id)&lt;br /&gt;
 {&lt;br /&gt;
 	setNodeId(&amp;amp;canopen_Data, 0x01);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Initialisation);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Operational);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Stopping CanFestival===&lt;br /&gt;
&lt;br /&gt;
After finishing work with CANopen it is good to stop the communication and timers and close the device. It is done by these few functions.&lt;br /&gt;
 setState(&amp;amp;canopen_Data, Stopped);&lt;br /&gt;
 StopTimerLoop();&lt;br /&gt;
 canClose(&amp;amp;canopen_Data);&lt;br /&gt;
 canopen_handle = NULL;&lt;br /&gt;
&lt;br /&gt;
===Writing to Object dictionary===&lt;br /&gt;
&lt;br /&gt;
CANopen devices and all network services of each node are configured by writing to device object dictionary (OD). It is different while writing to local OD or OD of some network device.&lt;br /&gt;
====Writing to local OD====&lt;br /&gt;
Function &#039;&#039;WriteLocalDict&#039;&#039; is used for writing to OD of local node managed by CanFestival.&lt;br /&gt;
 UNS32 writeLocalDict( CO_Data* d, &lt;br /&gt;
 UNS16 wIndex, &lt;br /&gt;
 UNS8 bSubindex, &lt;br /&gt;
 void * pSourceData, &lt;br /&gt;
 UNS8 * pExpectedSize, &lt;br /&gt;
 UNS8 checkAccess);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;wIndex&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;bSubindex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this   index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;pbSourceData&#039;&#039;&#039; - pointer to the variable that holds the value that should be copied into the object dictionary&lt;br /&gt;
 &#039;&#039;&#039;pExpectedSize&#039;&#039;&#039; - pointer to variable with size of the data to be written&lt;br /&gt;
 &#039;&#039;&#039;CheckAccess&#039;&#039;&#039; - if other than 0, do not read if the data is Read Only or Constant&lt;br /&gt;
&lt;br /&gt;
====Writing to network OD====&lt;br /&gt;
&lt;br /&gt;
It is necessary to use SDO service for writing data to OD of some network device. Each CANopen device has at least one SDO server. It means that it is able to receive SDOs with one ID and answer by SDOs with another ID. It is usual that the server listen for SDOs with ID 0x600 + ID of the node and transmits SDOs of ID 0x580 + node ID. Each SDO we want to use has to be defined while creating node configuration by &#039;&#039;objdictedit&#039;&#039;. Then the SDO is sent by calling appropriate function. The best is to use function &#039;&#039;writeNetworkDictCallBack&#039;&#039; which syntax is shown below.&lt;br /&gt;
 UNS8 writeNetworkDictCallBack (CO_Data* d, &lt;br /&gt;
 UNS8 nodeId, &lt;br /&gt;
 UNS16 index,&lt;br /&gt;
 UNS8 subIndex, &lt;br /&gt;
 UNS8 count, &lt;br /&gt;
 UNS8 dataType, &lt;br /&gt;
 void *data, &lt;br /&gt;
 SDOCallback_t Callback);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we want to send SDO&lt;br /&gt;
 &#039;&#039;&#039;index&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;subIndex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;count&#039;&#039;&#039; - number of bytes to be written&lt;br /&gt;
 &#039;&#039;&#039;dataType&#039;&#039;&#039; - type of the data, use 0 for integers, real numbers and other values&lt;br /&gt;
 &#039;&#039;&#039;data&#039;&#039;&#039; - pointer to the data&lt;br /&gt;
 &#039;&#039;&#039;Callback&#039;&#039;&#039; - pointer to a function which is called after finishing the transfer&lt;br /&gt;
The SDO service is by definition confirmed. It means that SDO server sends response with result of the transfer after each SDO reception. This response has to be read by client to be sure that the data were written correctly. The result should be read in your function which pointer is given to the function &#039;&#039;writeNetworkDictCallBack&#039;&#039; as parameter &#039;&#039;callback&#039;&#039;. The result of SDO transfer in such a function is read by CanFestival function &#039;&#039;getWriteResultNetworkDict&#039;&#039;. This function has to be called after each SDO transmission because it releases line used to transfer. Header of this function is:&lt;br /&gt;
 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we have sent SDO&lt;br /&gt;
 &#039;&#039;&#039;abortCode&#039;&#039;&#039; - pointer to the variable where error code is written in case of error&lt;br /&gt;
The function can return one of these values according to the SDO transfer state:&lt;br /&gt;
 &#039;&#039;&#039;SDO_FINISHED&#039;&#039;&#039; - data is available&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_RCV&#039;&#039;&#039; - Transfer failed. (abort SDO received)&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_INTERNAL&#039;&#039;&#039; - Transfer failed. Internal abort.&lt;br /&gt;
 &#039;&#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;&#039; - Data not yet available&lt;br /&gt;
The function can be used in cycle waiting while return value is &#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;. But the better solution is calling it in callback function from &#039;&#039;writeNetworkDictCallBack&#039;&#039;. The callback is call after finishing the transfer.&lt;br /&gt;
&lt;br /&gt;
===Using PDO service===&lt;br /&gt;
&lt;br /&gt;
Using PDO service for data exchange is very easy in CanFestival. The most usual transmission type of PDOs is that they are transmitted after SYNC message. In this case it just has to be set up in objdictedit configuration and then it works, reads and stores values into mapped variables. After each PDO reception or transmission &#039;&#039;post_TPDO&#039;&#039; callback is called if used. &lt;br /&gt;
Sometimes it is necessary to send PDO from code without SYNC message reception. This is done by calling the function &#039;&#039;sendPDOevent&#039;&#039; with this syntax:&lt;br /&gt;
 UNS8 sendPDOevent(CO_Data* d);&lt;br /&gt;
where &#039;&#039;d&#039;&#039; is the pointer to local object dictionary structure. This function sends all PDOs defined by &#039;&#039;objdictedit&#039;&#039; and transmission type &#039;&#039;after event&#039;&#039; (0x255).&lt;br /&gt;
&lt;br /&gt;
===Generating SYNC message===&lt;br /&gt;
&lt;br /&gt;
If you want to set up local node to become the SYNC server you have to write some information to local OD. Here is an example of function which set up the SYNC messages generation:&lt;br /&gt;
 /**&lt;br /&gt;
  * This function initializes local canopen node to send SYNC message&lt;br /&gt;
  * with given period. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param period - period of the SYNC message in us&lt;br /&gt;
  */&lt;br /&gt;
 void synchro_setup(CO_Data *d, unsigned long period)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 SYNC_COBID = 0x40000080;&lt;br /&gt;
 	UNS32 SYNC_INTER = period;&lt;br /&gt;
 	UNS8 size = sizeof(UNS32); &lt;br /&gt;
 	writeLocalDict(d, 0x1006, 0x0, &amp;amp;SYNC_INTER, &amp;amp;size, RW);&lt;br /&gt;
 	writeLocalDict(d, 0x1005, 0x0, &amp;amp;SYNC_COBID, &amp;amp;size, RW);&lt;br /&gt;
 }&lt;br /&gt;
According to CANopen specification ID of the SYNC message is 0x80.&lt;br /&gt;
After the setup it can be started by command &#039;&#039;startSYNC(CO_Data *d)&#039;&#039; and stopped by command &#039;&#039;stopSYNC(CO_Data *d)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===SDO and PDO example===&lt;br /&gt;
&lt;br /&gt;
At the end I attach example of a function (&#039;&#039;cpd_start()&#039;&#039;) which starts some device communicating by CANopen. The ID of the device is given by the parameter. The other function (&#039;&#039;cpd_checkSDO_start()&#039;&#039;) is callback used to handle SDO transfer result. It is necessary to wait until one SDO transfer is finished before starting some other. Global variable &#039;&#039;cpd_init_step&#039;&#039; is used for counting actual step of SDO transfer. If some SDO transfer fails it is set to -1 and the startup process is terminated. &lt;br /&gt;
 /**&lt;br /&gt;
  * This function is given to the writeNetworkDict function as a callback.&lt;br /&gt;
  * It checks the result of SDO transmition and after finishing the transmition&lt;br /&gt;
  * it closes the transfer.&lt;br /&gt;
  * @param d - local object disctionary&lt;br /&gt;
  * @param nodeID - ID of the node which the local node is communicating with&lt;br /&gt;
  */ &lt;br /&gt;
 void cpd_checkSDO_start(CO_Data* d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 abortCode;	&lt;br /&gt;
 	if(getWriteResultNetworkDict (d, nodeId, &amp;amp;abortCode) != SDO_FINISHED) {&lt;br /&gt;
 		cpd_init_step = -1;&lt;br /&gt;
 	}&lt;br /&gt;
 	closeSDOtransfer(&amp;amp;canopen_Data, nodeId, SDO_CLIENT);&lt;br /&gt;
 	cpd_start(&amp;amp;canopen_Data, nodeId);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /**&lt;br /&gt;
  * This function switch canopen device into operational state. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param nodeId - ID of the device&lt;br /&gt;
  * return 0 - ok, -1 - failed&lt;br /&gt;
  */&lt;br /&gt;
 int cpd_start(CO_Data *d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS8 data8;&lt;br /&gt;
 	UNS16 data16;&lt;br /&gt;
 	UNS32 data32;&lt;br /&gt;
 	switch(cpd_init_step++) {&lt;br /&gt;
 		case 0:&lt;br /&gt;
 			masterSendNMTstateChange(d, nodeId, NMT_Start_Node);&lt;br /&gt;
 			cpd_controlword = 0;&lt;br /&gt;
                        sendPDOevent(d);&lt;br /&gt;
 			cpd_controlword = 6;&lt;br /&gt;
                        sendPDOevent(d);&lt;br /&gt;
 			cpd_controlword = 0x0F;&lt;br /&gt;
                        sendPDOevent(d);&lt;br /&gt;
 &lt;br /&gt;
 			// Start operational mode&lt;br /&gt;
 			data8 = 0xFC;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x6060, 0x00, 1, 0, &amp;amp;data8, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 1:&lt;br /&gt;
 			// Check operation status&lt;br /&gt;
 			readNetworkDictCallback(d, nodeId, 0x6061, 0x00, 0, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 2:&lt;br /&gt;
 			// Setpoint specification&lt;br /&gt;
 			data16 = 0x0002;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x301B, 0x11, 2, 0, &amp;amp;data16, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 3:&lt;br /&gt;
 			canopen_init_result = 0;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case -1:&lt;br /&gt;
 			canopen_init_result = -1;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Emergency message===&lt;br /&gt;
&lt;br /&gt;
New version of CanFestival is extended by EMCY messages support. There is callback added which can be set to point to your own EMCY message handler.This handler has to be a function with three parameters defined in this way:&lt;br /&gt;
 void my_post_emcy(UNS8 nodeID, UNS16 errCode, UNS8 errReg)&lt;br /&gt;
After reception of an EMCY message this callback is called. The parameters keep information about node ID of the EMCY producer, error code and content of the error register.&lt;br /&gt;
To register your handler you have to set the callback in CanFestival initialization.&lt;br /&gt;
 my_Data.post_emcy = my_post_emcy;&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3123</id>
		<title>Boa5200 HOWTO</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3123"/>
		<updated>2007-11-04T15:50:20Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* Using PDO service */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This document describes how to install and setup Linux and development environment for BOA5200  board. &lt;br /&gt;
Assume that you have a development machine (your PC) that you use for development and building your applications which you consequently want to get running and test on BOA5200.&lt;br /&gt;
&lt;br /&gt;
==Serial line setting==&lt;br /&gt;
The easiest way to communicate with the board ,when there is no OS and remote shell running on it, is over serial line. Recommended serial communication program is minicom. Setup minicom as follows:&lt;br /&gt;
&lt;br /&gt;
Baud Rate – 38400&lt;br /&gt;
&lt;br /&gt;
Bits - 8&lt;br /&gt;
&lt;br /&gt;
Parity – N&lt;br /&gt;
&lt;br /&gt;
Stop Bits - 1&lt;br /&gt;
&lt;br /&gt;
Hardware Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
Software Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
After the setup you will see Redboot&amp;gt; command prompt. Here you can enter Redboot`s commands.&lt;br /&gt;
Redboot is a simple boot manager bulit upon eCos real-time OS. For more details , see http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html.&lt;br /&gt;
&lt;br /&gt;
==DHCP server setup==&lt;br /&gt;
Redboot supports BOOTP protocol which means that it is able to get network information(IP,netmask,gateway IP address,etc.) from DHCP server(provides BOOTP besides DHCP protocol). Install dhcp server (on debian: apt-get install dhcpd) on your development machine. Example of my dhcp configuration file /etc/dhcpd.conf:&lt;br /&gt;
 # I have two ethernet interfaces: &lt;br /&gt;
 # eth0 - Internet&lt;br /&gt;
 # eth1 - connection to BOA5200 (IP= 192.168.10.1)&lt;br /&gt;
 # I do not want to progate infos to 147.32.0.0 subnetwork&lt;br /&gt;
 subnet 147.32.0.0 netmask 255.255.0.0 {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 # private subnetwork&lt;br /&gt;
 subnet 192.168.10.0 netmask 255.255.255.0 {&lt;br /&gt;
  option broadcast-address 192.168.10.255;&lt;br /&gt;
  option routers 192.168.10.1;&lt;br /&gt;
  option subnet-mask 255.255.255.0;&lt;br /&gt;
  default-lease-time 600;&lt;br /&gt;
  max-lease-time 7200;&lt;br /&gt;
 &lt;br /&gt;
 # settings for BOA5200&lt;br /&gt;
  host BOA5200 {&lt;br /&gt;
   hardware ethernet 00:08:f1:11:22:33;&lt;br /&gt;
   fixed-address 192.168.10.2;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dhcp server and reboot the board. After booting it has assigned IP, netmask and gateway address:&lt;br /&gt;
 +PHY0: AMD AM79C874&lt;br /&gt;
 FEC eth0: 100Mb/Full Duplex&lt;br /&gt;
 Ethernet eth0: MAC address 00:08:f1:11:22:33&lt;br /&gt;
 IP: 192.168.10.2/255.255.255.0, Gateway: 192.168.10.1&lt;br /&gt;
 Default server: 192.168.10.1&lt;br /&gt;
&lt;br /&gt;
==TFTP server setup==&lt;br /&gt;
Redboot is able to load file from remote tftp server into memory. Tftp server is lanuched by inetd daemon when a new &lt;br /&gt;
connection comes. &lt;br /&gt;
Therefore add the following line into /etc/inetd.conf :&lt;br /&gt;
 tftp            dgram   udp     wait    nobody  /usr/sbin/tcpd  /usr/sbin/in.tftpd&lt;br /&gt;
&lt;br /&gt;
Default tftp root directory is /tftpboot. You can change it by calling in.tftpd with specified directory as a parameter.&lt;br /&gt;
&lt;br /&gt;
===Alternative way for Ubuntu based distro===&lt;br /&gt;
&lt;br /&gt;
1. Install tftpd and related packages.&lt;br /&gt;
 sudo apt-get install xinetd tftpd tftp&lt;br /&gt;
&lt;br /&gt;
2. Create /etc/xinetd.d/tftp and put this entry:&lt;br /&gt;
&lt;br /&gt;
 service tftp&lt;br /&gt;
 {&lt;br /&gt;
 protocol        = udp&lt;br /&gt;
 port            = 69&lt;br /&gt;
 socket_type     = dgram&lt;br /&gt;
 wait            = yes&lt;br /&gt;
 user            = nobody&lt;br /&gt;
 server          = /usr/sbin/in.tftpd&lt;br /&gt;
 server_args     = /tftpboot&lt;br /&gt;
 disable         = no&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
3. Make /tftpboot directory&lt;br /&gt;
&lt;br /&gt;
 sudo mkdir /tftpboot&lt;br /&gt;
 sudo chmod -R 777 /tftpboot&lt;br /&gt;
 sudo chown -R nobody /tftpboot&lt;br /&gt;
&lt;br /&gt;
4. Start tftpd through xinetd&lt;br /&gt;
&lt;br /&gt;
 sudo /etc/init.d/xinetd start&lt;br /&gt;
&lt;br /&gt;
see [[http://www.example.com Installing and setting TFTPD in Ubuntu]]&lt;br /&gt;
&lt;br /&gt;
==Tool chain==&lt;br /&gt;
Toolchain(gcc, ld, ...) for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Unpack the archive:&lt;br /&gt;
&lt;br /&gt;
 cd /&lt;br /&gt;
 tar xvzf gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
&lt;br /&gt;
You can also create a debian package from archive and then install the package:&lt;br /&gt;
 alien --to-deb gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Note: If you are not root, use fakeroot to run the command.&lt;br /&gt;
&lt;br /&gt;
==Applying kernel patches==&lt;br /&gt;
It is recommended to use [http://linux.die.net/man/1/quilt quilt] tool to manage series of patches.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mini-Howto:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Assuming kernel sources are in directory /usr/src/linux.&lt;br /&gt;
&lt;br /&gt;
1. cd /usr/src/linux&lt;br /&gt;
&lt;br /&gt;
2. mkdir patches&lt;br /&gt;
&lt;br /&gt;
3. Copy all patches you want to apply to &#039;&#039;patches&#039;&#039; subdirectory&lt;br /&gt;
&lt;br /&gt;
4. Create &#039;&#039;series&#039;&#039; file in &#039;&#039;patches&#039;&#039; subdirectory and write names of patch files each on separate line. The order &lt;br /&gt;
the patches are stated in the file is significant!! The patch on the first line will be applied first followed by others.&lt;br /&gt;
&lt;br /&gt;
4. &#039;&#039;quilt push&#039;&#039; (&#039;&#039;quilt pop&#039;&#039;)  - applies (unapplies) all patches in &#039;&#039;series&#039;&#039; file&lt;br /&gt;
&lt;br /&gt;
==Building kernel==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.4 kernel sources&#039;&#039;&#039; for MPC5200 can be found in &#039;&#039;eCos_Linux_boa5200/tgz&#039;&#039; directory on BOARD DOCUMENTATION CD or from ftp://rtime.felk.cvut.cz/MPC5200/kernel_2.4/linuxppc-2.4-boa5200-release_2006_05_10.tgz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.6 Kernel sources&#039;&#039;&#039; for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/linuxppc-2.6.18-1_AM.tar.gz.&lt;br /&gt;
Default kernel configuration file is ftp://rtime.felk.cvut.cz/MPC5200/config-2.6.18-1_AM.&lt;br /&gt;
Do not forget to set ARCH and CROSS_COMPILE variables to this values in Makefile:&lt;br /&gt;
 ARCH=ppc&lt;br /&gt;
 CROSS_COMPILE=powerpc-603e-linux-gnu-&lt;br /&gt;
&lt;br /&gt;
After compilation a built image is placed into arch/ppc/boot/image directory.&lt;br /&gt;
&lt;br /&gt;
The following commnad will install modules into &#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039;/lib/modules/...&lt;br /&gt;
 make INSTALL_MOD_PATH=&#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039; modules_install   &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Make the building directory linuxppc-2.6.18-1_AM_build, where object files will be placed, outside the origin source directory linuxppc-2.6.18-1_AM&lt;br /&gt;
&lt;br /&gt;
 mkdir linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
2. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM &lt;br /&gt;
linuxppc-2.6.18-1_AM directory must be clean i.e. no make, make menuconfig executed from this directory&lt;br /&gt;
before!&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
 make O=../linuxppc-2.6.18-1_AM_build menuconfig  &lt;br /&gt;
kernel config file (.config) will be created in   linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
Next time, always run make menuconfig always from the building directory, i.e. linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
4. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
5. &lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/GNUmakefile&lt;br /&gt;
&lt;br /&gt;
6. &lt;br /&gt;
Edit GNUmakefile and change paths in KERNELSRC and KERNELOUTPUT variables&lt;br /&gt;
&lt;br /&gt;
7. &lt;br /&gt;
 make &amp;amp;&amp;amp; make modules_install&lt;br /&gt;
&lt;br /&gt;
== Loading kernel ==&lt;br /&gt;
&lt;br /&gt;
You can test your new image on the board as follows:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
   RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 &lt;br /&gt;
 # execute image; root directory (/) is on flash memory&lt;br /&gt;
   RedBoot&amp;gt; exec&lt;br /&gt;
If you want to load the kernel from different TFTP server than the one provided by DHCP, you can use the following command to set the IP address of your server:&lt;br /&gt;
   RedBoot&amp;gt; ip_address -h 147.32.86.&amp;lt;xxx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CAUTION:&#039;&#039;&#039; you must boot the kernel by  RedBoot release at least 2007_02_01 otherwise it will not run! So you must load into RAM and then run the appropriate RedBoot image (or replace/update its image on flash with the new one - see  &lt;br /&gt;
the next section) and after then you can execute kernel image.&lt;br /&gt;
&lt;br /&gt;
==Updating RedBoot==&lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/MPC5200-2007.02.01-redbootROMRAM.srec &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # load RedBoot image from tftp server into memory at the address 0x100000&lt;br /&gt;
 RedBoot&amp;gt;lo -b 0x100000 MPC5200-2007.02.01-redbootROMRAM.srec&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # write image in flash memory&lt;br /&gt;
 RedBoot&amp;gt;fi cr RedBoot&lt;br /&gt;
 RedBoot&amp;gt;reset&lt;br /&gt;
&lt;br /&gt;
If upgrade fails you can fallback to ROM Redboot image by typing &#039;A&amp;amp;M:&#039;&lt;br /&gt;
&lt;br /&gt;
If image of ROMRAM version of RedBoot with name &amp;quot;RedBoot&amp;quot; (case sensitive!!) is not found in FLASH minimal version of ROM RedBoot is started. This version does not support many services like TFTP protocol and FLASH management. To download ROMRAM version of RedBoot to FLASH it is necessary to follow these steps:&lt;br /&gt;
&lt;br /&gt;
Load RAM version of RedBoot to BOA using xmodem (the image file MPC5200-2006.05.10-redbootRAM.srec is placed on BOA original CD):&lt;br /&gt;
 RedBoot&amp;gt; lo -m xmodem&lt;br /&gt;
&lt;br /&gt;
When finished RedBoot should answer with something like that:&lt;br /&gt;
&lt;br /&gt;
 CEntry point: 0x00080100, address range: 0x00080000-0x000bea04&lt;br /&gt;
 xyzModem - CRC mode, 5763(SOH)/0(STX)/0(CAN) packets, 1 retries&lt;br /&gt;
&lt;br /&gt;
Then start the RedBoot:&lt;br /&gt;
 RedBoot&amp;gt; go&lt;br /&gt;
&lt;br /&gt;
RAM RedBoot should start now. Download the new version of ROMRAM RedBoot to FLASH according to the steps above.&lt;br /&gt;
&lt;br /&gt;
==NFS-root setup==&lt;br /&gt;
&lt;br /&gt;
During the development phase of application it must be tested many times. However, it is annoying to copy several application files to flash memory every time.  The practical solution is to mount via NFS working directory or whole root directory from the point of OS running on the board.&lt;br /&gt;
&lt;br /&gt;
You can download already prepared root directory from ftp://rtime.felk.cvut.cz/MPC5200/MPC5200_root_070321.tar.gz&lt;br /&gt;
&lt;br /&gt;
To export /var/MPC5200_root directory via NFS add the following line to /etc/exports:&lt;br /&gt;
&lt;br /&gt;
 /var/MPC5200_root 192.168.10.0/255.255.255.0(rw,sync,no_root_squash)&lt;br /&gt;
&lt;br /&gt;
Then run command &#039;exportfs -ra&#039; so that the change take an effect.&lt;br /&gt;
&lt;br /&gt;
If you want MPC5200 to be mount as root directory instead of that one in flash memory:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
  RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 # execute kernel image with information where to &lt;br /&gt;
 # find root directory in parameter string&lt;br /&gt;
  RedBoot&amp;gt; ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.10.1:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: exportfs is a part of knfs package for debian systems (ubuntu,...)&lt;br /&gt;
&lt;br /&gt;
== Login with telnet ==&lt;br /&gt;
 telnet &amp;lt;ip address of boa&amp;gt;&lt;br /&gt;
Log in as root, ask me for the password. --[[User:Sojka|Sojka]] 20:42, 21 March 2007 (CET)&lt;br /&gt;
==Setting up BOA5200==&lt;br /&gt;
&lt;br /&gt;
Use &#039;fconfig&#039; command (see http://ecos.sourceware.org/ecos/docs-latest/redboot/persistent-state-flash.html manual) to set up BOA5200 configuration. Recommended configuration:&lt;br /&gt;
&lt;br /&gt;
 Run script at boot: true&lt;br /&gt;
 Boot script:&lt;br /&gt;
  load zImage.elf&lt;br /&gt;
  ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.123.254:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
 Boot script timeout (1000ms resolution): 10 &lt;br /&gt;
 Use BOOTP for network configuration: true&lt;br /&gt;
 Default server IP address: IP address of your computer&lt;br /&gt;
 FEC Network hardware address [MAC]: choose MAC address of the unit (example: 0x00:0x00:0x00:0x00:0x00:0x02)&lt;br /&gt;
 GDB connection port: 9000&lt;br /&gt;
 Force console for special debug messages: false&lt;br /&gt;
 Network debug at boot time: false&lt;br /&gt;
 Update RedBoot non-volatile configuration - continue (y/n)? y&lt;br /&gt;
&lt;br /&gt;
==Socketcan==&lt;br /&gt;
&lt;br /&gt;
Prior to compiling linux kernel with socketcan driver, it is necessary to [http://rtime.felk.cvut.cz/hw/index.php/HOWTO#Applying_kernel_patches  apply kernel patches] , which can be found in [http://rtime.felk.cvut.cz/repos/boa5200-linux/patches/ DARCS repository]&lt;br /&gt;
&lt;br /&gt;
To set up can interface, it is necessary to configure the communication speed first and then bring the interface up. Communication speed can be set up using following command (for can0 interface):&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
&lt;br /&gt;
The constant 660000 was found experimentally, driver seems to calculate the transmission speed improperly. To bring up the can network interface, use the same command as with any other network interface, i.e.&lt;br /&gt;
&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
&lt;br /&gt;
The most comfortable way of setting up both can interfaces upon startup of system is to place following script to /etc/init.d/ (name it &#039;can&#039;, for example)&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can1/can_baudrate&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
 ifconfig can1 up&lt;br /&gt;
&lt;br /&gt;
==CanFestival==&lt;br /&gt;
&lt;br /&gt;
===Obtaining and building CanFestival===&lt;br /&gt;
&lt;br /&gt;
CanFestival driver source can be downloaded from. The primary way how to do it is to check out the source directory from CanFestival CVS by these steps:&lt;br /&gt;
 cvs -d:pserver:anonymous@lolitech.dyndns.org:/canfestival login&lt;br /&gt;
 (type return, without entering a password)&lt;br /&gt;
The system will respond:&lt;br /&gt;
 Logging in to :pserver:anonymous@lolitech.dyndns.org:2401/canfestival&lt;br /&gt;
Then, enter:&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@lolitech.dyndns.org:/canfestival co -P CanFestival-3&lt;br /&gt;
Then insert CanFestival folder and run this commands:&lt;br /&gt;
 ./configure --timers=unix --can=socket --cc=powerpc-603e-linux-gnu-gcc --arch=ppc --os=linux --target=unix &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
Building of CanFestival will produce some libraries and copy them to /usr/powerpc-603e-linux-gnu/lib folder.&lt;br /&gt;
&lt;br /&gt;
===Setting up local CANopen node===&lt;br /&gt;
&lt;br /&gt;
CanFestival source includes tool called &#039;&#039;objdictedit&#039;&#039;. This program has graphical user interface and serves to creating configuration of the CANopen node of application we develop. It is started by command &#039;&#039;objdictedit&#039;&#039;. Using this program you can create the object dictionary for the CanFestival. Mainly it is necessary to set up all SDO and PDO, the node has to send and receive. To each PDO you have to define more things - PDO receive or transmit, variable to be mapped and variable mapping. The variable will then be used in application code to exchange data between CanFestival driver and application. If you set up PDOs here they will be sent and received automatically and the values will be stored into mapped variable. Setting up SDO means that you can use it in your application, but if you want to send it, it has to be done in code.&lt;br /&gt;
After creating this basic configuration you have to build the dictionary which results into to files with extensions .h and .c. You have to link these files with your application.&lt;br /&gt;
&lt;br /&gt;
===Initializing and starting CanFestival===&lt;br /&gt;
&lt;br /&gt;
To explain how to use CanFestival I include some code examples. It supposes node configuration generated by &#039;&#039;objdictedit&#039;&#039; which name is &#039;&#039;canopen&#039;&#039;. It is then used as prefix of automatically generated functions and variables (&#039;&#039;canopen_Data&#039;&#039; is for example object dictionary used by CanFestival). &lt;br /&gt;
Header &#039;&#039;canfestival.h&#039;&#039; has to be included. For start using CanFestival it is necessary to load dynamic library with CAN bus driver API created while compiling CanFestival source. In the example SocketCan driver is used to access CAN bus. &lt;br /&gt;
 if(!LoadCanDriver(&amp;quot;libcanfestival_can_socket.so&amp;quot;)) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
Then you have to open CAN device. Parameters of the communication have to be prepared in structure of type &#039;&#039;s_Board&#039;&#039;. In this case CAN is set to use device &#039;&#039;can1&#039;&#039; and baudrate 1Mbps. Handler of the bus is then stored to variable of type &#039;&#039;CAN_HANDLE&#039;&#039;.&lt;br /&gt;
 /**&lt;br /&gt;
  * CAN board definition.&lt;br /&gt;
  * Device name can1, baudrate 1M&lt;br /&gt;
  */&lt;br /&gt;
 s_BOARD canopen_board = {&amp;quot;1&amp;quot;, &amp;quot;1000&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
 CAN_HANDLE canopen_handle;&lt;br /&gt;
 &lt;br /&gt;
 if(!(canopen_handle = canOpen(&amp;amp;canopen_board, &amp;amp;canopen_Data))) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
CanFestival implements callbacks to some events like change of state or message reception. There are pointers to callback functions in &#039;&#039;canopen_Data&#039;&#039; structure. You can assign your own functions to these pointers or leave them unused.&lt;br /&gt;
 canopen_Data.initialisation = canopen_initialisation;&lt;br /&gt;
 canopen_Data.preOperational = canopen_preOperational; &lt;br /&gt;
 canopen_Data.operational = canopen_operational; &lt;br /&gt;
 canopen_Data.post_sync = canopen_post_sync; &lt;br /&gt;
 canopen_Data.post_TPDO = canopen_post_TPDO; &lt;br /&gt;
 canopen_Data.stopped = canopen_stopped; &lt;br /&gt;
After setting up these few things you have to call function &#039;&#039;StartTimerLoop&#039;&#039; which initializes CanFestival timers. As an argument you have to insert pointer to the first function you want to proceed after starting the timers. &lt;br /&gt;
 StartTimerLoop(&amp;amp;initNode); &lt;br /&gt;
Here is an example of such a function. It sets local node ID to 1 and bring the node to operation state. Callback functions are called after changing state if used.&lt;br /&gt;
 void initNode(CO_Data * d, UNS32 id)&lt;br /&gt;
 {&lt;br /&gt;
 	setNodeId(&amp;amp;canopen_Data, 0x01);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Initialisation);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Operational);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Stopping CanFestival===&lt;br /&gt;
&lt;br /&gt;
After finishing work with CANopen it is good to stop the communication and timers and close the device. It is done by these few functions.&lt;br /&gt;
 setState(&amp;amp;canopen_Data, Stopped);&lt;br /&gt;
 StopTimerLoop();&lt;br /&gt;
 canClose(&amp;amp;canopen_Data);&lt;br /&gt;
 canopen_handle = NULL;&lt;br /&gt;
&lt;br /&gt;
===Writing to Object dictionary===&lt;br /&gt;
&lt;br /&gt;
CANopen devices and all network services of each node are configured by writing to device object dictionary (OD). It is different while writing to local OD or OD of some network device.&lt;br /&gt;
====Writing to local OD====&lt;br /&gt;
Function &#039;&#039;WriteLocalDict&#039;&#039; is used for writing to OD of local node managed by CanFestival.&lt;br /&gt;
 UNS32 writeLocalDict( CO_Data* d, &lt;br /&gt;
 UNS16 wIndex, &lt;br /&gt;
 UNS8 bSubindex, &lt;br /&gt;
 void * pSourceData, &lt;br /&gt;
 UNS8 * pExpectedSize, &lt;br /&gt;
 UNS8 checkAccess);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;wIndex&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;bSubindex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this   index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;pbSourceData&#039;&#039;&#039; - pointer to the variable that holds the value that should be copied into the object dictionary&lt;br /&gt;
 &#039;&#039;&#039;pExpectedSize&#039;&#039;&#039; - pointer to variable with size of the data to be written&lt;br /&gt;
 &#039;&#039;&#039;CheckAccess&#039;&#039;&#039; - if other than 0, do not read if the data is Read Only or Constant&lt;br /&gt;
&lt;br /&gt;
====Writing to network OD====&lt;br /&gt;
&lt;br /&gt;
It is necessary to use SDO service for writing data to OD of some network device. Each CANopen device has at least one SDO server. It means that it is able to receive SDOs with one ID and answer by SDOs with another ID. It is usual that the server listen for SDOs with ID 0x600 + ID of the node and transmits SDOs of ID 0x580 + node ID. Each SDO we want to use has to be defined while creating node configuration by &#039;&#039;objdictedit&#039;&#039;. Then the SDO is sent by calling appropriate function. The best is to use function &#039;&#039;writeNetworkDictCallBack&#039;&#039; which syntax is shown below.&lt;br /&gt;
 UNS8 writeNetworkDictCallBack (CO_Data* d, &lt;br /&gt;
 UNS8 nodeId, &lt;br /&gt;
 UNS16 index,&lt;br /&gt;
 UNS8 subIndex, &lt;br /&gt;
 UNS8 count, &lt;br /&gt;
 UNS8 dataType, &lt;br /&gt;
 void *data, &lt;br /&gt;
 SDOCallback_t Callback);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we want to send SDO&lt;br /&gt;
 &#039;&#039;&#039;index&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;subIndex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;count&#039;&#039;&#039; - number of bytes to be written&lt;br /&gt;
 &#039;&#039;&#039;dataType&#039;&#039;&#039; - type of the data, use 0 for integers, real numbers and other values&lt;br /&gt;
 &#039;&#039;&#039;data&#039;&#039;&#039; - pointer to the data&lt;br /&gt;
 &#039;&#039;&#039;Callback&#039;&#039;&#039; - pointer to a function which is called after finishing the transfer&lt;br /&gt;
The SDO service is by definition confirmed. It means that SDO server sends response with result of the transfer after each SDO reception. This response has to be read by client to be sure that the data were written correctly. The result should be read in your function which pointer is given to the function &#039;&#039;writeNetworkDictCallBack&#039;&#039; as parameter &#039;&#039;callback&#039;&#039;. The result of SDO transfer in such a function is read by CanFestival function &#039;&#039;getWriteResultNetworkDict&#039;&#039;. This function has to be called after each SDO transmission because it releases line used to transfer. Header of this function is:&lt;br /&gt;
 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we have sent SDO&lt;br /&gt;
 &#039;&#039;&#039;abortCode&#039;&#039;&#039; - pointer to the variable where error code is written in case of error&lt;br /&gt;
The function can return one of these values according to the SDO transfer state:&lt;br /&gt;
 &#039;&#039;&#039;SDO_FINISHED&#039;&#039;&#039; - data is available&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_RCV&#039;&#039;&#039; - Transfer failed. (abort SDO received)&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_INTERNAL&#039;&#039;&#039; - Transfer failed. Internal abort.&lt;br /&gt;
 &#039;&#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;&#039; - Data not yet available&lt;br /&gt;
The function can be used in cycle waiting while return value is &#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;. But the better solution is calling it in callback function from &#039;&#039;writeNetworkDictCallBack&#039;&#039;. The callback is call after finishing the transfer.&lt;br /&gt;
&lt;br /&gt;
===Using PDO service===&lt;br /&gt;
&lt;br /&gt;
Using PDO service for data exchange is very easy in CanFestival. The most usual transmission type of PDOs is that they are transmitted after SYNC message. In this case it just has to be set up in objdictedit configuration and then it works, reads and stores values into mapped variables. After each PDO reception or transmission &#039;&#039;post_TPDO&#039;&#039; callback is called if used. &lt;br /&gt;
Sometimes it is necessary to send PDO from code without SYNC message reception. This is done by calling the function &#039;&#039;sendPDOevent&#039;&#039; with this syntax:&lt;br /&gt;
 UNS8 sendPDOevent(CO_Data* d);&lt;br /&gt;
where &#039;&#039;d&#039;&#039; is the pointer to local object dictionary structure. This function sends all PDOs defined by &#039;&#039;objdictedit&#039;&#039; and transmission type &#039;&#039;after event&#039;&#039; (0x255).&lt;br /&gt;
&lt;br /&gt;
===Generating SYNC message===&lt;br /&gt;
&lt;br /&gt;
If you want to set up local node to become the SYNC server you have to write some information to local OD. Here is an example of function which set up the SYNC messages generation:&lt;br /&gt;
 /**&lt;br /&gt;
  * This function initializes local canopen node to send SYNC message&lt;br /&gt;
  * with given period. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param period - period of the SYNC message in us&lt;br /&gt;
  */&lt;br /&gt;
 void synchro_setup(CO_Data *d, unsigned long period)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 SYNC_COBID = 0x40000080;&lt;br /&gt;
 	UNS32 SYNC_INTER = period;&lt;br /&gt;
 	UNS8 size = sizeof(UNS32); &lt;br /&gt;
 	writeLocalDict(d, 0x1006, 0x0, &amp;amp;SYNC_INTER, &amp;amp;size, RW);&lt;br /&gt;
 	writeLocalDict(d, 0x1005, 0x0, &amp;amp;SYNC_COBID, &amp;amp;size, RW);&lt;br /&gt;
 }&lt;br /&gt;
According to CANopen specification ID of the SYNC message is 0x80.&lt;br /&gt;
After the setup it can be started by command &#039;&#039;startSYNC(CO_Data *d)&#039;&#039; and stopped by command &#039;&#039;stopSYNC(CO_Data *d)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===SDO and PDO example===&lt;br /&gt;
&lt;br /&gt;
At the end I attach example of a function (&#039;&#039;cpd_start()&#039;&#039;) which starts some device communicating by CANopen. The ID of the device is given by the parameter. The other function (&#039;&#039;cpd_checkSDO_start()&#039;&#039;) is callback used to handle SDO transfer result. It is necessary to wait until one SDO transfer is finished before starting some other. Global variable &#039;&#039;cpd_init_step&#039;&#039; is used for counting actual step of SDO transfer. If some SDO transfer fails it is set to -1 and the startup process is terminated. &lt;br /&gt;
 /**&lt;br /&gt;
  * This function is given to the writeNetworkDict function as a callback.&lt;br /&gt;
  * It checks the result of SDO transmition and after finishing the transmition&lt;br /&gt;
  * it closes the transfer.&lt;br /&gt;
  * @param d - local object disctionary&lt;br /&gt;
  * @param nodeID - ID of the node which the local node is communicating with&lt;br /&gt;
  */ &lt;br /&gt;
 void cpd_checkSDO_start(CO_Data* d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 abortCode;	&lt;br /&gt;
 	if(getWriteResultNetworkDict (d, nodeId, &amp;amp;abortCode) != SDO_FINISHED) {&lt;br /&gt;
 		cpd_init_step = -1;&lt;br /&gt;
 	}&lt;br /&gt;
 	closeSDOtransfer(&amp;amp;canopen_Data, nodeId, SDO_CLIENT);&lt;br /&gt;
 	cpd_start(&amp;amp;canopen_Data, nodeId);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /**&lt;br /&gt;
  * This function switch canopen device into operational state. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param nodeId - ID of the device&lt;br /&gt;
  * return 0 - ok, -1 - failed&lt;br /&gt;
  */&lt;br /&gt;
 int cpd_start(CO_Data *d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS8 data8;&lt;br /&gt;
 	UNS16 data16;&lt;br /&gt;
 	UNS32 data32;&lt;br /&gt;
 	switch(cpd_init_step++) {&lt;br /&gt;
 		case 0:&lt;br /&gt;
 			masterSendNMTstateChange(d, nodeId, NMT_Start_Node);&lt;br /&gt;
 			s_PDO pdo;&lt;br /&gt;
 			cpd_controlword = 0;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			int i = 0;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 6;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 7;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 0x0F;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0xF;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 &lt;br /&gt;
 			// Start operational mode&lt;br /&gt;
 			data8 = 0xFC;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x6060, 0x00, 1, 0, &amp;amp;data8, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 1:&lt;br /&gt;
 			// Check operation status&lt;br /&gt;
 			readNetworkDictCallback(d, nodeId, 0x6061, 0x00, 0, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 2:&lt;br /&gt;
 			// Setpoint specification&lt;br /&gt;
 			data16 = 0x0002;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x301B, 0x11, 2, 0, &amp;amp;data16, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 3:&lt;br /&gt;
 			canopen_init_result = 0;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case -1:&lt;br /&gt;
 			canopen_init_result = -1;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 } &lt;br /&gt;
&lt;br /&gt;
===Emergency message===&lt;br /&gt;
&lt;br /&gt;
New version of CanFestival is extended by EMCY messages support. There is callback added which can be set to point to your own EMCY message handler.This handler has to be a function with three parameters defined in this way:&lt;br /&gt;
 void my_post_emcy(UNS8 nodeID, UNS16 errCode, UNS8 errReg)&lt;br /&gt;
After reception of an EMCY message this callback is called. The parameters keep information about node ID of the EMCY producer, error code and content of the error register.&lt;br /&gt;
To register your handler you have to set the callback in CanFestival initialization.&lt;br /&gt;
 my_Data.post_emcy = my_post_emcy;&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3122</id>
		<title>Boa5200 HOWTO</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3122"/>
		<updated>2007-11-04T15:49:25Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* Using PDO service */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This document describes how to install and setup Linux and development environment for BOA5200  board. &lt;br /&gt;
Assume that you have a development machine (your PC) that you use for development and building your applications which you consequently want to get running and test on BOA5200.&lt;br /&gt;
&lt;br /&gt;
==Serial line setting==&lt;br /&gt;
The easiest way to communicate with the board ,when there is no OS and remote shell running on it, is over serial line. Recommended serial communication program is minicom. Setup minicom as follows:&lt;br /&gt;
&lt;br /&gt;
Baud Rate – 38400&lt;br /&gt;
&lt;br /&gt;
Bits - 8&lt;br /&gt;
&lt;br /&gt;
Parity – N&lt;br /&gt;
&lt;br /&gt;
Stop Bits - 1&lt;br /&gt;
&lt;br /&gt;
Hardware Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
Software Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
After the setup you will see Redboot&amp;gt; command prompt. Here you can enter Redboot`s commands.&lt;br /&gt;
Redboot is a simple boot manager bulit upon eCos real-time OS. For more details , see http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html.&lt;br /&gt;
&lt;br /&gt;
==DHCP server setup==&lt;br /&gt;
Redboot supports BOOTP protocol which means that it is able to get network information(IP,netmask,gateway IP address,etc.) from DHCP server(provides BOOTP besides DHCP protocol). Install dhcp server (on debian: apt-get install dhcpd) on your development machine. Example of my dhcp configuration file /etc/dhcpd.conf:&lt;br /&gt;
 # I have two ethernet interfaces: &lt;br /&gt;
 # eth0 - Internet&lt;br /&gt;
 # eth1 - connection to BOA5200 (IP= 192.168.10.1)&lt;br /&gt;
 # I do not want to progate infos to 147.32.0.0 subnetwork&lt;br /&gt;
 subnet 147.32.0.0 netmask 255.255.0.0 {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 # private subnetwork&lt;br /&gt;
 subnet 192.168.10.0 netmask 255.255.255.0 {&lt;br /&gt;
  option broadcast-address 192.168.10.255;&lt;br /&gt;
  option routers 192.168.10.1;&lt;br /&gt;
  option subnet-mask 255.255.255.0;&lt;br /&gt;
  default-lease-time 600;&lt;br /&gt;
  max-lease-time 7200;&lt;br /&gt;
 &lt;br /&gt;
 # settings for BOA5200&lt;br /&gt;
  host BOA5200 {&lt;br /&gt;
   hardware ethernet 00:08:f1:11:22:33;&lt;br /&gt;
   fixed-address 192.168.10.2;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dhcp server and reboot the board. After booting it has assigned IP, netmask and gateway address:&lt;br /&gt;
 +PHY0: AMD AM79C874&lt;br /&gt;
 FEC eth0: 100Mb/Full Duplex&lt;br /&gt;
 Ethernet eth0: MAC address 00:08:f1:11:22:33&lt;br /&gt;
 IP: 192.168.10.2/255.255.255.0, Gateway: 192.168.10.1&lt;br /&gt;
 Default server: 192.168.10.1&lt;br /&gt;
&lt;br /&gt;
==TFTP server setup==&lt;br /&gt;
Redboot is able to load file from remote tftp server into memory. Tftp server is lanuched by inetd daemon when a new &lt;br /&gt;
connection comes. &lt;br /&gt;
Therefore add the following line into /etc/inetd.conf :&lt;br /&gt;
 tftp            dgram   udp     wait    nobody  /usr/sbin/tcpd  /usr/sbin/in.tftpd&lt;br /&gt;
&lt;br /&gt;
Default tftp root directory is /tftpboot. You can change it by calling in.tftpd with specified directory as a parameter.&lt;br /&gt;
&lt;br /&gt;
===Alternative way for Ubuntu based distro===&lt;br /&gt;
&lt;br /&gt;
1. Install tftpd and related packages.&lt;br /&gt;
 sudo apt-get install xinetd tftpd tftp&lt;br /&gt;
&lt;br /&gt;
2. Create /etc/xinetd.d/tftp and put this entry:&lt;br /&gt;
&lt;br /&gt;
 service tftp&lt;br /&gt;
 {&lt;br /&gt;
 protocol        = udp&lt;br /&gt;
 port            = 69&lt;br /&gt;
 socket_type     = dgram&lt;br /&gt;
 wait            = yes&lt;br /&gt;
 user            = nobody&lt;br /&gt;
 server          = /usr/sbin/in.tftpd&lt;br /&gt;
 server_args     = /tftpboot&lt;br /&gt;
 disable         = no&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
3. Make /tftpboot directory&lt;br /&gt;
&lt;br /&gt;
 sudo mkdir /tftpboot&lt;br /&gt;
 sudo chmod -R 777 /tftpboot&lt;br /&gt;
 sudo chown -R nobody /tftpboot&lt;br /&gt;
&lt;br /&gt;
4. Start tftpd through xinetd&lt;br /&gt;
&lt;br /&gt;
 sudo /etc/init.d/xinetd start&lt;br /&gt;
&lt;br /&gt;
see [[http://www.example.com Installing and setting TFTPD in Ubuntu]]&lt;br /&gt;
&lt;br /&gt;
==Tool chain==&lt;br /&gt;
Toolchain(gcc, ld, ...) for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Unpack the archive:&lt;br /&gt;
&lt;br /&gt;
 cd /&lt;br /&gt;
 tar xvzf gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
&lt;br /&gt;
You can also create a debian package from archive and then install the package:&lt;br /&gt;
 alien --to-deb gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Note: If you are not root, use fakeroot to run the command.&lt;br /&gt;
&lt;br /&gt;
==Applying kernel patches==&lt;br /&gt;
It is recommended to use [http://linux.die.net/man/1/quilt quilt] tool to manage series of patches.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mini-Howto:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Assuming kernel sources are in directory /usr/src/linux.&lt;br /&gt;
&lt;br /&gt;
1. cd /usr/src/linux&lt;br /&gt;
&lt;br /&gt;
2. mkdir patches&lt;br /&gt;
&lt;br /&gt;
3. Copy all patches you want to apply to &#039;&#039;patches&#039;&#039; subdirectory&lt;br /&gt;
&lt;br /&gt;
4. Create &#039;&#039;series&#039;&#039; file in &#039;&#039;patches&#039;&#039; subdirectory and write names of patch files each on separate line. The order &lt;br /&gt;
the patches are stated in the file is significant!! The patch on the first line will be applied first followed by others.&lt;br /&gt;
&lt;br /&gt;
4. &#039;&#039;quilt push&#039;&#039; (&#039;&#039;quilt pop&#039;&#039;)  - applies (unapplies) all patches in &#039;&#039;series&#039;&#039; file&lt;br /&gt;
&lt;br /&gt;
==Building kernel==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.4 kernel sources&#039;&#039;&#039; for MPC5200 can be found in &#039;&#039;eCos_Linux_boa5200/tgz&#039;&#039; directory on BOARD DOCUMENTATION CD or from ftp://rtime.felk.cvut.cz/MPC5200/kernel_2.4/linuxppc-2.4-boa5200-release_2006_05_10.tgz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.6 Kernel sources&#039;&#039;&#039; for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/linuxppc-2.6.18-1_AM.tar.gz.&lt;br /&gt;
Default kernel configuration file is ftp://rtime.felk.cvut.cz/MPC5200/config-2.6.18-1_AM.&lt;br /&gt;
Do not forget to set ARCH and CROSS_COMPILE variables to this values in Makefile:&lt;br /&gt;
 ARCH=ppc&lt;br /&gt;
 CROSS_COMPILE=powerpc-603e-linux-gnu-&lt;br /&gt;
&lt;br /&gt;
After compilation a built image is placed into arch/ppc/boot/image directory.&lt;br /&gt;
&lt;br /&gt;
The following commnad will install modules into &#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039;/lib/modules/...&lt;br /&gt;
 make INSTALL_MOD_PATH=&#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039; modules_install   &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Make the building directory linuxppc-2.6.18-1_AM_build, where object files will be placed, outside the origin source directory linuxppc-2.6.18-1_AM&lt;br /&gt;
&lt;br /&gt;
 mkdir linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
2. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM &lt;br /&gt;
linuxppc-2.6.18-1_AM directory must be clean i.e. no make, make menuconfig executed from this directory&lt;br /&gt;
before!&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
 make O=../linuxppc-2.6.18-1_AM_build menuconfig  &lt;br /&gt;
kernel config file (.config) will be created in   linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
Next time, always run make menuconfig always from the building directory, i.e. linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
4. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
5. &lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/GNUmakefile&lt;br /&gt;
&lt;br /&gt;
6. &lt;br /&gt;
Edit GNUmakefile and change paths in KERNELSRC and KERNELOUTPUT variables&lt;br /&gt;
&lt;br /&gt;
7. &lt;br /&gt;
 make &amp;amp;&amp;amp; make modules_install&lt;br /&gt;
&lt;br /&gt;
== Loading kernel ==&lt;br /&gt;
&lt;br /&gt;
You can test your new image on the board as follows:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
   RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 &lt;br /&gt;
 # execute image; root directory (/) is on flash memory&lt;br /&gt;
   RedBoot&amp;gt; exec&lt;br /&gt;
If you want to load the kernel from different TFTP server than the one provided by DHCP, you can use the following command to set the IP address of your server:&lt;br /&gt;
   RedBoot&amp;gt; ip_address -h 147.32.86.&amp;lt;xxx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CAUTION:&#039;&#039;&#039; you must boot the kernel by  RedBoot release at least 2007_02_01 otherwise it will not run! So you must load into RAM and then run the appropriate RedBoot image (or replace/update its image on flash with the new one - see  &lt;br /&gt;
the next section) and after then you can execute kernel image.&lt;br /&gt;
&lt;br /&gt;
==Updating RedBoot==&lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/MPC5200-2007.02.01-redbootROMRAM.srec &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # load RedBoot image from tftp server into memory at the address 0x100000&lt;br /&gt;
 RedBoot&amp;gt;lo -b 0x100000 MPC5200-2007.02.01-redbootROMRAM.srec&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # write image in flash memory&lt;br /&gt;
 RedBoot&amp;gt;fi cr RedBoot&lt;br /&gt;
 RedBoot&amp;gt;reset&lt;br /&gt;
&lt;br /&gt;
If upgrade fails you can fallback to ROM Redboot image by typing &#039;A&amp;amp;M:&#039;&lt;br /&gt;
&lt;br /&gt;
If image of ROMRAM version of RedBoot with name &amp;quot;RedBoot&amp;quot; (case sensitive!!) is not found in FLASH minimal version of ROM RedBoot is started. This version does not support many services like TFTP protocol and FLASH management. To download ROMRAM version of RedBoot to FLASH it is necessary to follow these steps:&lt;br /&gt;
&lt;br /&gt;
Load RAM version of RedBoot to BOA using xmodem (the image file MPC5200-2006.05.10-redbootRAM.srec is placed on BOA original CD):&lt;br /&gt;
 RedBoot&amp;gt; lo -m xmodem&lt;br /&gt;
&lt;br /&gt;
When finished RedBoot should answer with something like that:&lt;br /&gt;
&lt;br /&gt;
 CEntry point: 0x00080100, address range: 0x00080000-0x000bea04&lt;br /&gt;
 xyzModem - CRC mode, 5763(SOH)/0(STX)/0(CAN) packets, 1 retries&lt;br /&gt;
&lt;br /&gt;
Then start the RedBoot:&lt;br /&gt;
 RedBoot&amp;gt; go&lt;br /&gt;
&lt;br /&gt;
RAM RedBoot should start now. Download the new version of ROMRAM RedBoot to FLASH according to the steps above.&lt;br /&gt;
&lt;br /&gt;
==NFS-root setup==&lt;br /&gt;
&lt;br /&gt;
During the development phase of application it must be tested many times. However, it is annoying to copy several application files to flash memory every time.  The practical solution is to mount via NFS working directory or whole root directory from the point of OS running on the board.&lt;br /&gt;
&lt;br /&gt;
You can download already prepared root directory from ftp://rtime.felk.cvut.cz/MPC5200/MPC5200_root_070321.tar.gz&lt;br /&gt;
&lt;br /&gt;
To export /var/MPC5200_root directory via NFS add the following line to /etc/exports:&lt;br /&gt;
&lt;br /&gt;
 /var/MPC5200_root 192.168.10.0/255.255.255.0(rw,sync,no_root_squash)&lt;br /&gt;
&lt;br /&gt;
Then run command &#039;exportfs -ra&#039; so that the change take an effect.&lt;br /&gt;
&lt;br /&gt;
If you want MPC5200 to be mount as root directory instead of that one in flash memory:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
  RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 # execute kernel image with information where to &lt;br /&gt;
 # find root directory in parameter string&lt;br /&gt;
  RedBoot&amp;gt; ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.10.1:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: exportfs is a part of knfs package for debian systems (ubuntu,...)&lt;br /&gt;
&lt;br /&gt;
== Login with telnet ==&lt;br /&gt;
 telnet &amp;lt;ip address of boa&amp;gt;&lt;br /&gt;
Log in as root, ask me for the password. --[[User:Sojka|Sojka]] 20:42, 21 March 2007 (CET)&lt;br /&gt;
==Setting up BOA5200==&lt;br /&gt;
&lt;br /&gt;
Use &#039;fconfig&#039; command (see http://ecos.sourceware.org/ecos/docs-latest/redboot/persistent-state-flash.html manual) to set up BOA5200 configuration. Recommended configuration:&lt;br /&gt;
&lt;br /&gt;
 Run script at boot: true&lt;br /&gt;
 Boot script:&lt;br /&gt;
  load zImage.elf&lt;br /&gt;
  ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.123.254:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
 Boot script timeout (1000ms resolution): 10 &lt;br /&gt;
 Use BOOTP for network configuration: true&lt;br /&gt;
 Default server IP address: IP address of your computer&lt;br /&gt;
 FEC Network hardware address [MAC]: choose MAC address of the unit (example: 0x00:0x00:0x00:0x00:0x00:0x02)&lt;br /&gt;
 GDB connection port: 9000&lt;br /&gt;
 Force console for special debug messages: false&lt;br /&gt;
 Network debug at boot time: false&lt;br /&gt;
 Update RedBoot non-volatile configuration - continue (y/n)? y&lt;br /&gt;
&lt;br /&gt;
==Socketcan==&lt;br /&gt;
&lt;br /&gt;
Prior to compiling linux kernel with socketcan driver, it is necessary to [http://rtime.felk.cvut.cz/hw/index.php/HOWTO#Applying_kernel_patches  apply kernel patches] , which can be found in [http://rtime.felk.cvut.cz/repos/boa5200-linux/patches/ DARCS repository]&lt;br /&gt;
&lt;br /&gt;
To set up can interface, it is necessary to configure the communication speed first and then bring the interface up. Communication speed can be set up using following command (for can0 interface):&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
&lt;br /&gt;
The constant 660000 was found experimentally, driver seems to calculate the transmission speed improperly. To bring up the can network interface, use the same command as with any other network interface, i.e.&lt;br /&gt;
&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
&lt;br /&gt;
The most comfortable way of setting up both can interfaces upon startup of system is to place following script to /etc/init.d/ (name it &#039;can&#039;, for example)&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can1/can_baudrate&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
 ifconfig can1 up&lt;br /&gt;
&lt;br /&gt;
==CanFestival==&lt;br /&gt;
&lt;br /&gt;
===Obtaining and building CanFestival===&lt;br /&gt;
&lt;br /&gt;
CanFestival driver source can be downloaded from. The primary way how to do it is to check out the source directory from CanFestival CVS by these steps:&lt;br /&gt;
 cvs -d:pserver:anonymous@lolitech.dyndns.org:/canfestival login&lt;br /&gt;
 (type return, without entering a password)&lt;br /&gt;
The system will respond:&lt;br /&gt;
 Logging in to :pserver:anonymous@lolitech.dyndns.org:2401/canfestival&lt;br /&gt;
Then, enter:&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@lolitech.dyndns.org:/canfestival co -P CanFestival-3&lt;br /&gt;
Then insert CanFestival folder and run this commands:&lt;br /&gt;
 ./configure --timers=unix --can=socket --cc=powerpc-603e-linux-gnu-gcc --arch=ppc --os=linux --target=unix &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
Building of CanFestival will produce some libraries and copy them to /usr/powerpc-603e-linux-gnu/lib folder.&lt;br /&gt;
&lt;br /&gt;
===Setting up local CANopen node===&lt;br /&gt;
&lt;br /&gt;
CanFestival source includes tool called &#039;&#039;objdictedit&#039;&#039;. This program has graphical user interface and serves to creating configuration of the CANopen node of application we develop. It is started by command &#039;&#039;objdictedit&#039;&#039;. Using this program you can create the object dictionary for the CanFestival. Mainly it is necessary to set up all SDO and PDO, the node has to send and receive. To each PDO you have to define more things - PDO receive or transmit, variable to be mapped and variable mapping. The variable will then be used in application code to exchange data between CanFestival driver and application. If you set up PDOs here they will be sent and received automatically and the values will be stored into mapped variable. Setting up SDO means that you can use it in your application, but if you want to send it, it has to be done in code.&lt;br /&gt;
After creating this basic configuration you have to build the dictionary which results into to files with extensions .h and .c. You have to link these files with your application.&lt;br /&gt;
&lt;br /&gt;
===Initializing and starting CanFestival===&lt;br /&gt;
&lt;br /&gt;
To explain how to use CanFestival I include some code examples. It supposes node configuration generated by &#039;&#039;objdictedit&#039;&#039; which name is &#039;&#039;canopen&#039;&#039;. It is then used as prefix of automatically generated functions and variables (&#039;&#039;canopen_Data&#039;&#039; is for example object dictionary used by CanFestival). &lt;br /&gt;
Header &#039;&#039;canfestival.h&#039;&#039; has to be included. For start using CanFestival it is necessary to load dynamic library with CAN bus driver API created while compiling CanFestival source. In the example SocketCan driver is used to access CAN bus. &lt;br /&gt;
 if(!LoadCanDriver(&amp;quot;libcanfestival_can_socket.so&amp;quot;)) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
Then you have to open CAN device. Parameters of the communication have to be prepared in structure of type &#039;&#039;s_Board&#039;&#039;. In this case CAN is set to use device &#039;&#039;can1&#039;&#039; and baudrate 1Mbps. Handler of the bus is then stored to variable of type &#039;&#039;CAN_HANDLE&#039;&#039;.&lt;br /&gt;
 /**&lt;br /&gt;
  * CAN board definition.&lt;br /&gt;
  * Device name can1, baudrate 1M&lt;br /&gt;
  */&lt;br /&gt;
 s_BOARD canopen_board = {&amp;quot;1&amp;quot;, &amp;quot;1000&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
 CAN_HANDLE canopen_handle;&lt;br /&gt;
 &lt;br /&gt;
 if(!(canopen_handle = canOpen(&amp;amp;canopen_board, &amp;amp;canopen_Data))) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
CanFestival implements callbacks to some events like change of state or message reception. There are pointers to callback functions in &#039;&#039;canopen_Data&#039;&#039; structure. You can assign your own functions to these pointers or leave them unused.&lt;br /&gt;
 canopen_Data.initialisation = canopen_initialisation;&lt;br /&gt;
 canopen_Data.preOperational = canopen_preOperational; &lt;br /&gt;
 canopen_Data.operational = canopen_operational; &lt;br /&gt;
 canopen_Data.post_sync = canopen_post_sync; &lt;br /&gt;
 canopen_Data.post_TPDO = canopen_post_TPDO; &lt;br /&gt;
 canopen_Data.stopped = canopen_stopped; &lt;br /&gt;
After setting up these few things you have to call function &#039;&#039;StartTimerLoop&#039;&#039; which initializes CanFestival timers. As an argument you have to insert pointer to the first function you want to proceed after starting the timers. &lt;br /&gt;
 StartTimerLoop(&amp;amp;initNode); &lt;br /&gt;
Here is an example of such a function. It sets local node ID to 1 and bring the node to operation state. Callback functions are called after changing state if used.&lt;br /&gt;
 void initNode(CO_Data * d, UNS32 id)&lt;br /&gt;
 {&lt;br /&gt;
 	setNodeId(&amp;amp;canopen_Data, 0x01);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Initialisation);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Operational);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Stopping CanFestival===&lt;br /&gt;
&lt;br /&gt;
After finishing work with CANopen it is good to stop the communication and timers and close the device. It is done by these few functions.&lt;br /&gt;
 setState(&amp;amp;canopen_Data, Stopped);&lt;br /&gt;
 StopTimerLoop();&lt;br /&gt;
 canClose(&amp;amp;canopen_Data);&lt;br /&gt;
 canopen_handle = NULL;&lt;br /&gt;
&lt;br /&gt;
===Writing to Object dictionary===&lt;br /&gt;
&lt;br /&gt;
CANopen devices and all network services of each node are configured by writing to device object dictionary (OD). It is different while writing to local OD or OD of some network device.&lt;br /&gt;
====Writing to local OD====&lt;br /&gt;
Function &#039;&#039;WriteLocalDict&#039;&#039; is used for writing to OD of local node managed by CanFestival.&lt;br /&gt;
 UNS32 writeLocalDict( CO_Data* d, &lt;br /&gt;
 UNS16 wIndex, &lt;br /&gt;
 UNS8 bSubindex, &lt;br /&gt;
 void * pSourceData, &lt;br /&gt;
 UNS8 * pExpectedSize, &lt;br /&gt;
 UNS8 checkAccess);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;wIndex&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;bSubindex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this   index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;pbSourceData&#039;&#039;&#039; - pointer to the variable that holds the value that should be copied into the object dictionary&lt;br /&gt;
 &#039;&#039;&#039;pExpectedSize&#039;&#039;&#039; - pointer to variable with size of the data to be written&lt;br /&gt;
 &#039;&#039;&#039;CheckAccess&#039;&#039;&#039; - if other than 0, do not read if the data is Read Only or Constant&lt;br /&gt;
&lt;br /&gt;
====Writing to network OD====&lt;br /&gt;
&lt;br /&gt;
It is necessary to use SDO service for writing data to OD of some network device. Each CANopen device has at least one SDO server. It means that it is able to receive SDOs with one ID and answer by SDOs with another ID. It is usual that the server listen for SDOs with ID 0x600 + ID of the node and transmits SDOs of ID 0x580 + node ID. Each SDO we want to use has to be defined while creating node configuration by &#039;&#039;objdictedit&#039;&#039;. Then the SDO is sent by calling appropriate function. The best is to use function &#039;&#039;writeNetworkDictCallBack&#039;&#039; which syntax is shown below.&lt;br /&gt;
 UNS8 writeNetworkDictCallBack (CO_Data* d, &lt;br /&gt;
 UNS8 nodeId, &lt;br /&gt;
 UNS16 index,&lt;br /&gt;
 UNS8 subIndex, &lt;br /&gt;
 UNS8 count, &lt;br /&gt;
 UNS8 dataType, &lt;br /&gt;
 void *data, &lt;br /&gt;
 SDOCallback_t Callback);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we want to send SDO&lt;br /&gt;
 &#039;&#039;&#039;index&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;subIndex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;count&#039;&#039;&#039; - number of bytes to be written&lt;br /&gt;
 &#039;&#039;&#039;dataType&#039;&#039;&#039; - type of the data, use 0 for integers, real numbers and other values&lt;br /&gt;
 &#039;&#039;&#039;data&#039;&#039;&#039; - pointer to the data&lt;br /&gt;
 &#039;&#039;&#039;Callback&#039;&#039;&#039; - pointer to a function which is called after finishing the transfer&lt;br /&gt;
The SDO service is by definition confirmed. It means that SDO server sends response with result of the transfer after each SDO reception. This response has to be read by client to be sure that the data were written correctly. The result should be read in your function which pointer is given to the function &#039;&#039;writeNetworkDictCallBack&#039;&#039; as parameter &#039;&#039;callback&#039;&#039;. The result of SDO transfer in such a function is read by CanFestival function &#039;&#039;getWriteResultNetworkDict&#039;&#039;. This function has to be called after each SDO transmission because it releases line used to transfer. Header of this function is:&lt;br /&gt;
 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we have sent SDO&lt;br /&gt;
 &#039;&#039;&#039;abortCode&#039;&#039;&#039; - pointer to the variable where error code is written in case of error&lt;br /&gt;
The function can return one of these values according to the SDO transfer state:&lt;br /&gt;
 &#039;&#039;&#039;SDO_FINISHED&#039;&#039;&#039; - data is available&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_RCV&#039;&#039;&#039; - Transfer failed. (abort SDO received)&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_INTERNAL&#039;&#039;&#039; - Transfer failed. Internal abort.&lt;br /&gt;
 &#039;&#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;&#039; - Data not yet available&lt;br /&gt;
The function can be used in cycle waiting while return value is &#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;. But the better solution is calling it in callback function from &#039;&#039;writeNetworkDictCallBack&#039;&#039;. The callback is call after finishing the transfer.&lt;br /&gt;
&lt;br /&gt;
===Using PDO service===&lt;br /&gt;
&lt;br /&gt;
Using PDO service for data exchange is very easy in CanFestival. The most usual transmission type of PDOs is that they are transmitted after SYNC message. In this case it just has to be set up in objdictedit configuration and then it works, reads and stores values into mapped variables. After each PDO reception or transmission &#039;&#039;post_TPDO&#039;&#039; callback is called if used. &lt;br /&gt;
Sometimes it is necessary to send PDO from code without SYNC message reception. This is done by calling the function &#039;&#039;sendPDOevent&#039;&#039; with this syntax:&lt;br /&gt;
 UNS8 sendPDOevent(CO_Data* d);&lt;br /&gt;
where &#039;&#039;d&#039;&#039; is the pointer to local object dictionary structure. This function sends all PDOs defined by &#039;objdictedit&#039; and transmission type &#039;&#039;after event&#039;&#039; (0x255).&lt;br /&gt;
&lt;br /&gt;
===Generating SYNC message===&lt;br /&gt;
&lt;br /&gt;
If you want to set up local node to become the SYNC server you have to write some information to local OD. Here is an example of function which set up the SYNC messages generation:&lt;br /&gt;
 /**&lt;br /&gt;
  * This function initializes local canopen node to send SYNC message&lt;br /&gt;
  * with given period. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param period - period of the SYNC message in us&lt;br /&gt;
  */&lt;br /&gt;
 void synchro_setup(CO_Data *d, unsigned long period)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 SYNC_COBID = 0x40000080;&lt;br /&gt;
 	UNS32 SYNC_INTER = period;&lt;br /&gt;
 	UNS8 size = sizeof(UNS32); &lt;br /&gt;
 	writeLocalDict(d, 0x1006, 0x0, &amp;amp;SYNC_INTER, &amp;amp;size, RW);&lt;br /&gt;
 	writeLocalDict(d, 0x1005, 0x0, &amp;amp;SYNC_COBID, &amp;amp;size, RW);&lt;br /&gt;
 }&lt;br /&gt;
According to CANopen specification ID of the SYNC message is 0x80.&lt;br /&gt;
After the setup it can be started by command &#039;&#039;startSYNC(CO_Data *d)&#039;&#039; and stopped by command &#039;&#039;stopSYNC(CO_Data *d)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===SDO and PDO example===&lt;br /&gt;
&lt;br /&gt;
At the end I attach example of a function (&#039;&#039;cpd_start()&#039;&#039;) which starts some device communicating by CANopen. The ID of the device is given by the parameter. The other function (&#039;&#039;cpd_checkSDO_start()&#039;&#039;) is callback used to handle SDO transfer result. It is necessary to wait until one SDO transfer is finished before starting some other. Global variable &#039;&#039;cpd_init_step&#039;&#039; is used for counting actual step of SDO transfer. If some SDO transfer fails it is set to -1 and the startup process is terminated. &lt;br /&gt;
 /**&lt;br /&gt;
  * This function is given to the writeNetworkDict function as a callback.&lt;br /&gt;
  * It checks the result of SDO transmition and after finishing the transmition&lt;br /&gt;
  * it closes the transfer.&lt;br /&gt;
  * @param d - local object disctionary&lt;br /&gt;
  * @param nodeID - ID of the node which the local node is communicating with&lt;br /&gt;
  */ &lt;br /&gt;
 void cpd_checkSDO_start(CO_Data* d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 abortCode;	&lt;br /&gt;
 	if(getWriteResultNetworkDict (d, nodeId, &amp;amp;abortCode) != SDO_FINISHED) {&lt;br /&gt;
 		cpd_init_step = -1;&lt;br /&gt;
 	}&lt;br /&gt;
 	closeSDOtransfer(&amp;amp;canopen_Data, nodeId, SDO_CLIENT);&lt;br /&gt;
 	cpd_start(&amp;amp;canopen_Data, nodeId);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /**&lt;br /&gt;
  * This function switch canopen device into operational state. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param nodeId - ID of the device&lt;br /&gt;
  * return 0 - ok, -1 - failed&lt;br /&gt;
  */&lt;br /&gt;
 int cpd_start(CO_Data *d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS8 data8;&lt;br /&gt;
 	UNS16 data16;&lt;br /&gt;
 	UNS32 data32;&lt;br /&gt;
 	switch(cpd_init_step++) {&lt;br /&gt;
 		case 0:&lt;br /&gt;
 			masterSendNMTstateChange(d, nodeId, NMT_Start_Node);&lt;br /&gt;
 			s_PDO pdo;&lt;br /&gt;
 			cpd_controlword = 0;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			int i = 0;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 6;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 7;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 0x0F;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0xF;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 &lt;br /&gt;
 			// Start operational mode&lt;br /&gt;
 			data8 = 0xFC;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x6060, 0x00, 1, 0, &amp;amp;data8, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 1:&lt;br /&gt;
 			// Check operation status&lt;br /&gt;
 			readNetworkDictCallback(d, nodeId, 0x6061, 0x00, 0, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 2:&lt;br /&gt;
 			// Setpoint specification&lt;br /&gt;
 			data16 = 0x0002;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x301B, 0x11, 2, 0, &amp;amp;data16, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 3:&lt;br /&gt;
 			canopen_init_result = 0;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case -1:&lt;br /&gt;
 			canopen_init_result = -1;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 } &lt;br /&gt;
&lt;br /&gt;
===Emergency message===&lt;br /&gt;
&lt;br /&gt;
New version of CanFestival is extended by EMCY messages support. There is callback added which can be set to point to your own EMCY message handler.This handler has to be a function with three parameters defined in this way:&lt;br /&gt;
 void my_post_emcy(UNS8 nodeID, UNS16 errCode, UNS8 errReg)&lt;br /&gt;
After reception of an EMCY message this callback is called. The parameters keep information about node ID of the EMCY producer, error code and content of the error register.&lt;br /&gt;
To register your handler you have to set the callback in CanFestival initialization.&lt;br /&gt;
 my_Data.post_emcy = my_post_emcy;&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3121</id>
		<title>Boa5200 HOWTO</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3121"/>
		<updated>2007-11-04T15:25:48Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* Emergency message */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This document describes how to install and setup Linux and development environment for BOA5200  board. &lt;br /&gt;
Assume that you have a development machine (your PC) that you use for development and building your applications which you consequently want to get running and test on BOA5200.&lt;br /&gt;
&lt;br /&gt;
==Serial line setting==&lt;br /&gt;
The easiest way to communicate with the board ,when there is no OS and remote shell running on it, is over serial line. Recommended serial communication program is minicom. Setup minicom as follows:&lt;br /&gt;
&lt;br /&gt;
Baud Rate – 38400&lt;br /&gt;
&lt;br /&gt;
Bits - 8&lt;br /&gt;
&lt;br /&gt;
Parity – N&lt;br /&gt;
&lt;br /&gt;
Stop Bits - 1&lt;br /&gt;
&lt;br /&gt;
Hardware Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
Software Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
After the setup you will see Redboot&amp;gt; command prompt. Here you can enter Redboot`s commands.&lt;br /&gt;
Redboot is a simple boot manager bulit upon eCos real-time OS. For more details , see http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html.&lt;br /&gt;
&lt;br /&gt;
==DHCP server setup==&lt;br /&gt;
Redboot supports BOOTP protocol which means that it is able to get network information(IP,netmask,gateway IP address,etc.) from DHCP server(provides BOOTP besides DHCP protocol). Install dhcp server (on debian: apt-get install dhcpd) on your development machine. Example of my dhcp configuration file /etc/dhcpd.conf:&lt;br /&gt;
 # I have two ethernet interfaces: &lt;br /&gt;
 # eth0 - Internet&lt;br /&gt;
 # eth1 - connection to BOA5200 (IP= 192.168.10.1)&lt;br /&gt;
 # I do not want to progate infos to 147.32.0.0 subnetwork&lt;br /&gt;
 subnet 147.32.0.0 netmask 255.255.0.0 {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 # private subnetwork&lt;br /&gt;
 subnet 192.168.10.0 netmask 255.255.255.0 {&lt;br /&gt;
  option broadcast-address 192.168.10.255;&lt;br /&gt;
  option routers 192.168.10.1;&lt;br /&gt;
  option subnet-mask 255.255.255.0;&lt;br /&gt;
  default-lease-time 600;&lt;br /&gt;
  max-lease-time 7200;&lt;br /&gt;
 &lt;br /&gt;
 # settings for BOA5200&lt;br /&gt;
  host BOA5200 {&lt;br /&gt;
   hardware ethernet 00:08:f1:11:22:33;&lt;br /&gt;
   fixed-address 192.168.10.2;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dhcp server and reboot the board. After booting it has assigned IP, netmask and gateway address:&lt;br /&gt;
 +PHY0: AMD AM79C874&lt;br /&gt;
 FEC eth0: 100Mb/Full Duplex&lt;br /&gt;
 Ethernet eth0: MAC address 00:08:f1:11:22:33&lt;br /&gt;
 IP: 192.168.10.2/255.255.255.0, Gateway: 192.168.10.1&lt;br /&gt;
 Default server: 192.168.10.1&lt;br /&gt;
&lt;br /&gt;
==TFTP server setup==&lt;br /&gt;
Redboot is able to load file from remote tftp server into memory. Tftp server is lanuched by inetd daemon when a new &lt;br /&gt;
connection comes. &lt;br /&gt;
Therefore add the following line into /etc/inetd.conf :&lt;br /&gt;
 tftp            dgram   udp     wait    nobody  /usr/sbin/tcpd  /usr/sbin/in.tftpd&lt;br /&gt;
&lt;br /&gt;
Default tftp root directory is /tftpboot. You can change it by calling in.tftpd with specified directory as a parameter.&lt;br /&gt;
&lt;br /&gt;
===Alternative way for Ubuntu based distro===&lt;br /&gt;
&lt;br /&gt;
1. Install tftpd and related packages.&lt;br /&gt;
 sudo apt-get install xinetd tftpd tftp&lt;br /&gt;
&lt;br /&gt;
2. Create /etc/xinetd.d/tftp and put this entry:&lt;br /&gt;
&lt;br /&gt;
 service tftp&lt;br /&gt;
 {&lt;br /&gt;
 protocol        = udp&lt;br /&gt;
 port            = 69&lt;br /&gt;
 socket_type     = dgram&lt;br /&gt;
 wait            = yes&lt;br /&gt;
 user            = nobody&lt;br /&gt;
 server          = /usr/sbin/in.tftpd&lt;br /&gt;
 server_args     = /tftpboot&lt;br /&gt;
 disable         = no&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
3. Make /tftpboot directory&lt;br /&gt;
&lt;br /&gt;
 sudo mkdir /tftpboot&lt;br /&gt;
 sudo chmod -R 777 /tftpboot&lt;br /&gt;
 sudo chown -R nobody /tftpboot&lt;br /&gt;
&lt;br /&gt;
4. Start tftpd through xinetd&lt;br /&gt;
&lt;br /&gt;
 sudo /etc/init.d/xinetd start&lt;br /&gt;
&lt;br /&gt;
see [[http://www.example.com Installing and setting TFTPD in Ubuntu]]&lt;br /&gt;
&lt;br /&gt;
==Tool chain==&lt;br /&gt;
Toolchain(gcc, ld, ...) for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Unpack the archive:&lt;br /&gt;
&lt;br /&gt;
 cd /&lt;br /&gt;
 tar xvzf gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
&lt;br /&gt;
You can also create a debian package from archive and then install the package:&lt;br /&gt;
 alien --to-deb gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Note: If you are not root, use fakeroot to run the command.&lt;br /&gt;
&lt;br /&gt;
==Applying kernel patches==&lt;br /&gt;
It is recommended to use [http://linux.die.net/man/1/quilt quilt] tool to manage series of patches.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mini-Howto:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Assuming kernel sources are in directory /usr/src/linux.&lt;br /&gt;
&lt;br /&gt;
1. cd /usr/src/linux&lt;br /&gt;
&lt;br /&gt;
2. mkdir patches&lt;br /&gt;
&lt;br /&gt;
3. Copy all patches you want to apply to &#039;&#039;patches&#039;&#039; subdirectory&lt;br /&gt;
&lt;br /&gt;
4. Create &#039;&#039;series&#039;&#039; file in &#039;&#039;patches&#039;&#039; subdirectory and write names of patch files each on separate line. The order &lt;br /&gt;
the patches are stated in the file is significant!! The patch on the first line will be applied first followed by others.&lt;br /&gt;
&lt;br /&gt;
4. &#039;&#039;quilt push&#039;&#039; (&#039;&#039;quilt pop&#039;&#039;)  - applies (unapplies) all patches in &#039;&#039;series&#039;&#039; file&lt;br /&gt;
&lt;br /&gt;
==Building kernel==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.4 kernel sources&#039;&#039;&#039; for MPC5200 can be found in &#039;&#039;eCos_Linux_boa5200/tgz&#039;&#039; directory on BOARD DOCUMENTATION CD or from ftp://rtime.felk.cvut.cz/MPC5200/kernel_2.4/linuxppc-2.4-boa5200-release_2006_05_10.tgz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.6 Kernel sources&#039;&#039;&#039; for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/linuxppc-2.6.18-1_AM.tar.gz.&lt;br /&gt;
Default kernel configuration file is ftp://rtime.felk.cvut.cz/MPC5200/config-2.6.18-1_AM.&lt;br /&gt;
Do not forget to set ARCH and CROSS_COMPILE variables to this values in Makefile:&lt;br /&gt;
 ARCH=ppc&lt;br /&gt;
 CROSS_COMPILE=powerpc-603e-linux-gnu-&lt;br /&gt;
&lt;br /&gt;
After compilation a built image is placed into arch/ppc/boot/image directory.&lt;br /&gt;
&lt;br /&gt;
The following commnad will install modules into &#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039;/lib/modules/...&lt;br /&gt;
 make INSTALL_MOD_PATH=&#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039; modules_install   &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Make the building directory linuxppc-2.6.18-1_AM_build, where object files will be placed, outside the origin source directory linuxppc-2.6.18-1_AM&lt;br /&gt;
&lt;br /&gt;
 mkdir linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
2. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM &lt;br /&gt;
linuxppc-2.6.18-1_AM directory must be clean i.e. no make, make menuconfig executed from this directory&lt;br /&gt;
before!&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
 make O=../linuxppc-2.6.18-1_AM_build menuconfig  &lt;br /&gt;
kernel config file (.config) will be created in   linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
Next time, always run make menuconfig always from the building directory, i.e. linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
4. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
5. &lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/GNUmakefile&lt;br /&gt;
&lt;br /&gt;
6. &lt;br /&gt;
Edit GNUmakefile and change paths in KERNELSRC and KERNELOUTPUT variables&lt;br /&gt;
&lt;br /&gt;
7. &lt;br /&gt;
 make &amp;amp;&amp;amp; make modules_install&lt;br /&gt;
&lt;br /&gt;
== Loading kernel ==&lt;br /&gt;
&lt;br /&gt;
You can test your new image on the board as follows:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
   RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 &lt;br /&gt;
 # execute image; root directory (/) is on flash memory&lt;br /&gt;
   RedBoot&amp;gt; exec&lt;br /&gt;
If you want to load the kernel from different TFTP server than the one provided by DHCP, you can use the following command to set the IP address of your server:&lt;br /&gt;
   RedBoot&amp;gt; ip_address -h 147.32.86.&amp;lt;xxx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CAUTION:&#039;&#039;&#039; you must boot the kernel by  RedBoot release at least 2007_02_01 otherwise it will not run! So you must load into RAM and then run the appropriate RedBoot image (or replace/update its image on flash with the new one - see  &lt;br /&gt;
the next section) and after then you can execute kernel image.&lt;br /&gt;
&lt;br /&gt;
==Updating RedBoot==&lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/MPC5200-2007.02.01-redbootROMRAM.srec &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # load RedBoot image from tftp server into memory at the address 0x100000&lt;br /&gt;
 RedBoot&amp;gt;lo -b 0x100000 MPC5200-2007.02.01-redbootROMRAM.srec&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # write image in flash memory&lt;br /&gt;
 RedBoot&amp;gt;fi cr RedBoot&lt;br /&gt;
 RedBoot&amp;gt;reset&lt;br /&gt;
&lt;br /&gt;
If upgrade fails you can fallback to ROM Redboot image by typing &#039;A&amp;amp;M:&#039;&lt;br /&gt;
&lt;br /&gt;
If image of ROMRAM version of RedBoot with name &amp;quot;RedBoot&amp;quot; (case sensitive!!) is not found in FLASH minimal version of ROM RedBoot is started. This version does not support many services like TFTP protocol and FLASH management. To download ROMRAM version of RedBoot to FLASH it is necessary to follow these steps:&lt;br /&gt;
&lt;br /&gt;
Load RAM version of RedBoot to BOA using xmodem (the image file MPC5200-2006.05.10-redbootRAM.srec is placed on BOA original CD):&lt;br /&gt;
 RedBoot&amp;gt; lo -m xmodem&lt;br /&gt;
&lt;br /&gt;
When finished RedBoot should answer with something like that:&lt;br /&gt;
&lt;br /&gt;
 CEntry point: 0x00080100, address range: 0x00080000-0x000bea04&lt;br /&gt;
 xyzModem - CRC mode, 5763(SOH)/0(STX)/0(CAN) packets, 1 retries&lt;br /&gt;
&lt;br /&gt;
Then start the RedBoot:&lt;br /&gt;
 RedBoot&amp;gt; go&lt;br /&gt;
&lt;br /&gt;
RAM RedBoot should start now. Download the new version of ROMRAM RedBoot to FLASH according to the steps above.&lt;br /&gt;
&lt;br /&gt;
==NFS-root setup==&lt;br /&gt;
&lt;br /&gt;
During the development phase of application it must be tested many times. However, it is annoying to copy several application files to flash memory every time.  The practical solution is to mount via NFS working directory or whole root directory from the point of OS running on the board.&lt;br /&gt;
&lt;br /&gt;
You can download already prepared root directory from ftp://rtime.felk.cvut.cz/MPC5200/MPC5200_root_070321.tar.gz&lt;br /&gt;
&lt;br /&gt;
To export /var/MPC5200_root directory via NFS add the following line to /etc/exports:&lt;br /&gt;
&lt;br /&gt;
 /var/MPC5200_root 192.168.10.0/255.255.255.0(rw,sync,no_root_squash)&lt;br /&gt;
&lt;br /&gt;
Then run command &#039;exportfs -ra&#039; so that the change take an effect.&lt;br /&gt;
&lt;br /&gt;
If you want MPC5200 to be mount as root directory instead of that one in flash memory:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
  RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 # execute kernel image with information where to &lt;br /&gt;
 # find root directory in parameter string&lt;br /&gt;
  RedBoot&amp;gt; ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.10.1:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: exportfs is a part of knfs package for debian systems (ubuntu,...)&lt;br /&gt;
&lt;br /&gt;
== Login with telnet ==&lt;br /&gt;
 telnet &amp;lt;ip address of boa&amp;gt;&lt;br /&gt;
Log in as root, ask me for the password. --[[User:Sojka|Sojka]] 20:42, 21 March 2007 (CET)&lt;br /&gt;
==Setting up BOA5200==&lt;br /&gt;
&lt;br /&gt;
Use &#039;fconfig&#039; command (see http://ecos.sourceware.org/ecos/docs-latest/redboot/persistent-state-flash.html manual) to set up BOA5200 configuration. Recommended configuration:&lt;br /&gt;
&lt;br /&gt;
 Run script at boot: true&lt;br /&gt;
 Boot script:&lt;br /&gt;
  load zImage.elf&lt;br /&gt;
  ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.123.254:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
 Boot script timeout (1000ms resolution): 10 &lt;br /&gt;
 Use BOOTP for network configuration: true&lt;br /&gt;
 Default server IP address: IP address of your computer&lt;br /&gt;
 FEC Network hardware address [MAC]: choose MAC address of the unit (example: 0x00:0x00:0x00:0x00:0x00:0x02)&lt;br /&gt;
 GDB connection port: 9000&lt;br /&gt;
 Force console for special debug messages: false&lt;br /&gt;
 Network debug at boot time: false&lt;br /&gt;
 Update RedBoot non-volatile configuration - continue (y/n)? y&lt;br /&gt;
&lt;br /&gt;
==Socketcan==&lt;br /&gt;
&lt;br /&gt;
Prior to compiling linux kernel with socketcan driver, it is necessary to [http://rtime.felk.cvut.cz/hw/index.php/HOWTO#Applying_kernel_patches  apply kernel patches] , which can be found in [http://rtime.felk.cvut.cz/repos/boa5200-linux/patches/ DARCS repository]&lt;br /&gt;
&lt;br /&gt;
To set up can interface, it is necessary to configure the communication speed first and then bring the interface up. Communication speed can be set up using following command (for can0 interface):&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
&lt;br /&gt;
The constant 660000 was found experimentally, driver seems to calculate the transmission speed improperly. To bring up the can network interface, use the same command as with any other network interface, i.e.&lt;br /&gt;
&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
&lt;br /&gt;
The most comfortable way of setting up both can interfaces upon startup of system is to place following script to /etc/init.d/ (name it &#039;can&#039;, for example)&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can1/can_baudrate&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
 ifconfig can1 up&lt;br /&gt;
&lt;br /&gt;
==CanFestival==&lt;br /&gt;
&lt;br /&gt;
===Obtaining and building CanFestival===&lt;br /&gt;
&lt;br /&gt;
CanFestival driver source can be downloaded from. The primary way how to do it is to check out the source directory from CanFestival CVS by these steps:&lt;br /&gt;
 cvs -d:pserver:anonymous@lolitech.dyndns.org:/canfestival login&lt;br /&gt;
 (type return, without entering a password)&lt;br /&gt;
The system will respond:&lt;br /&gt;
 Logging in to :pserver:anonymous@lolitech.dyndns.org:2401/canfestival&lt;br /&gt;
Then, enter:&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@lolitech.dyndns.org:/canfestival co -P CanFestival-3&lt;br /&gt;
Then insert CanFestival folder and run this commands:&lt;br /&gt;
 ./configure --timers=unix --can=socket --cc=powerpc-603e-linux-gnu-gcc --arch=ppc --os=linux --target=unix &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
Building of CanFestival will produce some libraries and copy them to /usr/powerpc-603e-linux-gnu/lib folder.&lt;br /&gt;
&lt;br /&gt;
===Setting up local CANopen node===&lt;br /&gt;
&lt;br /&gt;
CanFestival source includes tool called &#039;&#039;objdictedit&#039;&#039;. This program has graphical user interface and serves to creating configuration of the CANopen node of application we develop. It is started by command &#039;&#039;objdictedit&#039;&#039;. Using this program you can create the object dictionary for the CanFestival. Mainly it is necessary to set up all SDO and PDO, the node has to send and receive. To each PDO you have to define more things - PDO receive or transmit, variable to be mapped and variable mapping. The variable will then be used in application code to exchange data between CanFestival driver and application. If you set up PDOs here they will be sent and received automatically and the values will be stored into mapped variable. Setting up SDO means that you can use it in your application, but if you want to send it, it has to be done in code.&lt;br /&gt;
After creating this basic configuration you have to build the dictionary which results into to files with extensions .h and .c. You have to link these files with your application.&lt;br /&gt;
&lt;br /&gt;
===Initializing and starting CanFestival===&lt;br /&gt;
&lt;br /&gt;
To explain how to use CanFestival I include some code examples. It supposes node configuration generated by &#039;&#039;objdictedit&#039;&#039; which name is &#039;&#039;canopen&#039;&#039;. It is then used as prefix of automatically generated functions and variables (&#039;&#039;canopen_Data&#039;&#039; is for example object dictionary used by CanFestival). &lt;br /&gt;
Header &#039;&#039;canfestival.h&#039;&#039; has to be included. For start using CanFestival it is necessary to load dynamic library with CAN bus driver API created while compiling CanFestival source. In the example SocketCan driver is used to access CAN bus. &lt;br /&gt;
 if(!LoadCanDriver(&amp;quot;libcanfestival_can_socket.so&amp;quot;)) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
Then you have to open CAN device. Parameters of the communication have to be prepared in structure of type &#039;&#039;s_Board&#039;&#039;. In this case CAN is set to use device &#039;&#039;can1&#039;&#039; and baudrate 1Mbps. Handler of the bus is then stored to variable of type &#039;&#039;CAN_HANDLE&#039;&#039;.&lt;br /&gt;
 /**&lt;br /&gt;
  * CAN board definition.&lt;br /&gt;
  * Device name can1, baudrate 1M&lt;br /&gt;
  */&lt;br /&gt;
 s_BOARD canopen_board = {&amp;quot;1&amp;quot;, &amp;quot;1000&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
 CAN_HANDLE canopen_handle;&lt;br /&gt;
 &lt;br /&gt;
 if(!(canopen_handle = canOpen(&amp;amp;canopen_board, &amp;amp;canopen_Data))) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
CanFestival implements callbacks to some events like change of state or message reception. There are pointers to callback functions in &#039;&#039;canopen_Data&#039;&#039; structure. You can assign your own functions to these pointers or leave them unused.&lt;br /&gt;
 canopen_Data.initialisation = canopen_initialisation;&lt;br /&gt;
 canopen_Data.preOperational = canopen_preOperational; &lt;br /&gt;
 canopen_Data.operational = canopen_operational; &lt;br /&gt;
 canopen_Data.post_sync = canopen_post_sync; &lt;br /&gt;
 canopen_Data.post_TPDO = canopen_post_TPDO; &lt;br /&gt;
 canopen_Data.stopped = canopen_stopped; &lt;br /&gt;
After setting up these few things you have to call function &#039;&#039;StartTimerLoop&#039;&#039; which initializes CanFestival timers. As an argument you have to insert pointer to the first function you want to proceed after starting the timers. &lt;br /&gt;
 StartTimerLoop(&amp;amp;initNode); &lt;br /&gt;
Here is an example of such a function. It sets local node ID to 1 and bring the node to operation state. Callback functions are called after changing state if used.&lt;br /&gt;
 void initNode(CO_Data * d, UNS32 id)&lt;br /&gt;
 {&lt;br /&gt;
 	setNodeId(&amp;amp;canopen_Data, 0x01);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Initialisation);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Operational);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Stopping CanFestival===&lt;br /&gt;
&lt;br /&gt;
After finishing work with CANopen it is good to stop the communication and timers and close the device. It is done by these few functions.&lt;br /&gt;
 setState(&amp;amp;canopen_Data, Stopped);&lt;br /&gt;
 StopTimerLoop();&lt;br /&gt;
 canClose(&amp;amp;canopen_Data);&lt;br /&gt;
 canopen_handle = NULL;&lt;br /&gt;
&lt;br /&gt;
===Writing to Object dictionary===&lt;br /&gt;
&lt;br /&gt;
CANopen devices and all network services of each node are configured by writing to device object dictionary (OD). It is different while writing to local OD or OD of some network device.&lt;br /&gt;
====Writing to local OD====&lt;br /&gt;
Function &#039;&#039;WriteLocalDict&#039;&#039; is used for writing to OD of local node managed by CanFestival.&lt;br /&gt;
 UNS32 writeLocalDict( CO_Data* d, &lt;br /&gt;
 UNS16 wIndex, &lt;br /&gt;
 UNS8 bSubindex, &lt;br /&gt;
 void * pSourceData, &lt;br /&gt;
 UNS8 * pExpectedSize, &lt;br /&gt;
 UNS8 checkAccess);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;wIndex&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;bSubindex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this   index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;pbSourceData&#039;&#039;&#039; - pointer to the variable that holds the value that should be copied into the object dictionary&lt;br /&gt;
 &#039;&#039;&#039;pExpectedSize&#039;&#039;&#039; - pointer to variable with size of the data to be written&lt;br /&gt;
 &#039;&#039;&#039;CheckAccess&#039;&#039;&#039; - if other than 0, do not read if the data is Read Only or Constant&lt;br /&gt;
&lt;br /&gt;
====Writing to network OD====&lt;br /&gt;
&lt;br /&gt;
It is necessary to use SDO service for writing data to OD of some network device. Each CANopen device has at least one SDO server. It means that it is able to receive SDOs with one ID and answer by SDOs with another ID. It is usual that the server listen for SDOs with ID 0x600 + ID of the node and transmits SDOs of ID 0x580 + node ID. Each SDO we want to use has to be defined while creating node configuration by &#039;&#039;objdictedit&#039;&#039;. Then the SDO is sent by calling appropriate function. The best is to use function &#039;&#039;writeNetworkDictCallBack&#039;&#039; which syntax is shown below.&lt;br /&gt;
 UNS8 writeNetworkDictCallBack (CO_Data* d, &lt;br /&gt;
 UNS8 nodeId, &lt;br /&gt;
 UNS16 index,&lt;br /&gt;
 UNS8 subIndex, &lt;br /&gt;
 UNS8 count, &lt;br /&gt;
 UNS8 dataType, &lt;br /&gt;
 void *data, &lt;br /&gt;
 SDOCallback_t Callback);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we want to send SDO&lt;br /&gt;
 &#039;&#039;&#039;index&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;subIndex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;count&#039;&#039;&#039; - number of bytes to be written&lt;br /&gt;
 &#039;&#039;&#039;dataType&#039;&#039;&#039; - type of the data, use 0 for integers, real numbers and other values&lt;br /&gt;
 &#039;&#039;&#039;data&#039;&#039;&#039; - pointer to the data&lt;br /&gt;
 &#039;&#039;&#039;Callback&#039;&#039;&#039; - pointer to a function which is called after finishing the transfer&lt;br /&gt;
The SDO service is by definition confirmed. It means that SDO server sends response with result of the transfer after each SDO reception. This response has to be read by client to be sure that the data were written correctly. The result should be read in your function which pointer is given to the function &#039;&#039;writeNetworkDictCallBack&#039;&#039; as parameter &#039;&#039;callback&#039;&#039;. The result of SDO transfer in such a function is read by CanFestival function &#039;&#039;getWriteResultNetworkDict&#039;&#039;. This function has to be called after each SDO transmission because it releases line used to transfer. Header of this function is:&lt;br /&gt;
 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we have sent SDO&lt;br /&gt;
 &#039;&#039;&#039;abortCode&#039;&#039;&#039; - pointer to the variable where error code is written in case of error&lt;br /&gt;
The function can return one of these values according to the SDO transfer state:&lt;br /&gt;
 &#039;&#039;&#039;SDO_FINISHED&#039;&#039;&#039; - data is available&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_RCV&#039;&#039;&#039; - Transfer failed. (abort SDO received)&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_INTERNAL&#039;&#039;&#039; - Transfer failed. Internal abort.&lt;br /&gt;
 &#039;&#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;&#039; - Data not yet available&lt;br /&gt;
The function can be used in cycle waiting while return value is &#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;. But the better solution is calling it in callback function from &#039;&#039;writeNetworkDictCallBack&#039;&#039;. The callback is call after finishing the transfer.&lt;br /&gt;
&lt;br /&gt;
===Using PDO service===&lt;br /&gt;
&lt;br /&gt;
Using PDO service for data exchange is very easy in CanFestival. The most usual transmission type of PDOs is that they are transmitted after SYNC message. In this case it just has to be set up in objdictedit configuration and then it works, reads and stores values into mapped variables. After each PDO reception or transmission &#039;&#039;post_TPDO&#039;&#039; callback is called if used. &lt;br /&gt;
Sometimes it is necessary to send PDO from code without SYNC message reception. This is very inconsistent in CanFestival version 3. There are some functions which should solve this situation but they are commented and some other solution is promised to be done in the future. For now I have done it by using function sendPDO which syntax is:&lt;br /&gt;
 UNS8 sendPDO (CO_Data* d, s_PDO pdo, UNS8 request);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;pdo&#039;&#039;&#039; - structure with PDO message&lt;br /&gt;
 &#039;&#039;&#039;request&#039;&#039;&#039; - REQUEST (request for sending PDO) or NOT_A_REQUEST (normal PDO)&lt;br /&gt;
PDO message has to be created using structure s_PDO which meaning is clear:&lt;br /&gt;
 typedef struct struct_s_PDO {&lt;br /&gt;
   	UNS32 cobId;	  	/* COB-ID */&lt;br /&gt;
   	UNS8 len;	  	/* Number of data transmitted (in data[]) */&lt;br /&gt;
   	UNS8 data[8]; 	/* Contain the data */&lt;br /&gt;
 } s_PDO;&lt;br /&gt;
&lt;br /&gt;
===Generating SYNC message===&lt;br /&gt;
&lt;br /&gt;
If you want to set up local node to become the SYNC server you have to write some information to local OD. Here is an example of function which set up the SYNC messages generation:&lt;br /&gt;
 /**&lt;br /&gt;
  * This function initializes local canopen node to send SYNC message&lt;br /&gt;
  * with given period. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param period - period of the SYNC message in us&lt;br /&gt;
  */&lt;br /&gt;
 void synchro_setup(CO_Data *d, unsigned long period)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 SYNC_COBID = 0x40000080;&lt;br /&gt;
 	UNS32 SYNC_INTER = period;&lt;br /&gt;
 	UNS8 size = sizeof(UNS32); &lt;br /&gt;
 	writeLocalDict(d, 0x1006, 0x0, &amp;amp;SYNC_INTER, &amp;amp;size, RW);&lt;br /&gt;
 	writeLocalDict(d, 0x1005, 0x0, &amp;amp;SYNC_COBID, &amp;amp;size, RW);&lt;br /&gt;
 }&lt;br /&gt;
According to CANopen specification ID of the SYNC message is 0x80.&lt;br /&gt;
After the setup it can be started by command &#039;&#039;startSYNC(CO_Data *d)&#039;&#039; and stopped by command &#039;&#039;stopSYNC(CO_Data *d)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===SDO and PDO example===&lt;br /&gt;
&lt;br /&gt;
At the end I attach example of a function (&#039;&#039;cpd_start()&#039;&#039;) which starts some device communicating by CANopen. The ID of the device is given by the parameter. The other function (&#039;&#039;cpd_checkSDO_start()&#039;&#039;) is callback used to handle SDO transfer result. It is necessary to wait until one SDO transfer is finished before starting some other. Global variable &#039;&#039;cpd_init_step&#039;&#039; is used for counting actual step of SDO transfer. If some SDO transfer fails it is set to -1 and the startup process is terminated. &lt;br /&gt;
 /**&lt;br /&gt;
  * This function is given to the writeNetworkDict function as a callback.&lt;br /&gt;
  * It checks the result of SDO transmition and after finishing the transmition&lt;br /&gt;
  * it closes the transfer.&lt;br /&gt;
  * @param d - local object disctionary&lt;br /&gt;
  * @param nodeID - ID of the node which the local node is communicating with&lt;br /&gt;
  */ &lt;br /&gt;
 void cpd_checkSDO_start(CO_Data* d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 abortCode;	&lt;br /&gt;
 	if(getWriteResultNetworkDict (d, nodeId, &amp;amp;abortCode) != SDO_FINISHED) {&lt;br /&gt;
 		cpd_init_step = -1;&lt;br /&gt;
 	}&lt;br /&gt;
 	closeSDOtransfer(&amp;amp;canopen_Data, nodeId, SDO_CLIENT);&lt;br /&gt;
 	cpd_start(&amp;amp;canopen_Data, nodeId);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /**&lt;br /&gt;
  * This function switch canopen device into operational state. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param nodeId - ID of the device&lt;br /&gt;
  * return 0 - ok, -1 - failed&lt;br /&gt;
  */&lt;br /&gt;
 int cpd_start(CO_Data *d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS8 data8;&lt;br /&gt;
 	UNS16 data16;&lt;br /&gt;
 	UNS32 data32;&lt;br /&gt;
 	switch(cpd_init_step++) {&lt;br /&gt;
 		case 0:&lt;br /&gt;
 			masterSendNMTstateChange(d, nodeId, NMT_Start_Node);&lt;br /&gt;
 			s_PDO pdo;&lt;br /&gt;
 			cpd_controlword = 0;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			int i = 0;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 6;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 7;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 0x0F;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0xF;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 &lt;br /&gt;
 			// Start operational mode&lt;br /&gt;
 			data8 = 0xFC;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x6060, 0x00, 1, 0, &amp;amp;data8, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 1:&lt;br /&gt;
 			// Check operation status&lt;br /&gt;
 			readNetworkDictCallback(d, nodeId, 0x6061, 0x00, 0, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 2:&lt;br /&gt;
 			// Setpoint specification&lt;br /&gt;
 			data16 = 0x0002;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x301B, 0x11, 2, 0, &amp;amp;data16, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 3:&lt;br /&gt;
 			canopen_init_result = 0;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case -1:&lt;br /&gt;
 			canopen_init_result = -1;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 } &lt;br /&gt;
&lt;br /&gt;
===Emergency message===&lt;br /&gt;
&lt;br /&gt;
New version of CanFestival is extended by EMCY messages support. There is callback added which can be set to point to your own EMCY message handler.This handler has to be a function with three parameters defined in this way:&lt;br /&gt;
 void my_post_emcy(UNS8 nodeID, UNS16 errCode, UNS8 errReg)&lt;br /&gt;
After reception of an EMCY message this callback is called. The parameters keep information about node ID of the EMCY producer, error code and content of the error register.&lt;br /&gt;
To register your handler you have to set the callback in CanFestival initialization.&lt;br /&gt;
 my_Data.post_emcy = my_post_emcy;&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200&amp;diff=3120</id>
		<title>Boa5200</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200&amp;diff=3120"/>
		<updated>2007-10-23T15:36:53Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* Work Progress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* [ftp://rtime.felk.cvut.cz/MPC5200 Original documentation]&lt;br /&gt;
* [http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html Redboot documentace] - Redboot howto na CD k desce je neaktualny.&lt;br /&gt;
* [[HOWTO]]&lt;br /&gt;
&lt;br /&gt;
== Work Progress ==&lt;br /&gt;
* CanFestival tutorial added into [[HOWTO]] --[[User:Hamacl1|Hamacl1]] 17:36, 23 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
* New version of the root file-system. Telnet server is started during boot and tcpdump and strace was added from Debian. --[[User:Sojka|Sojka]] 20:40, 21 March 2007 (CET)&lt;br /&gt;
* Added links to darcs repository --[[User:Sojka|Sojka]] 16:42, 7 March 2007 (CET)&lt;br /&gt;
* few edits in HOWTO, successful test of TFTP boot, NFS from desktop OK --[[User:Zidekm|Zidekm]] 19:47, 19 February 2007 (CET)&lt;br /&gt;
* TODO - instalace CAN driveru&lt;br /&gt;
*HowTo k MPC5200 - done &lt;br /&gt;
--[[User:Molnam1|Molnam1]] 17:32, 9 February 2007 (CET)&lt;br /&gt;
*build toolchain+ kernel 2.6.18(Pavel P.); dhcp,tftp, root over nfs, testy (Martin M.) - done&lt;br /&gt;
--[[User:Molnam1|Molnam1]] 17:00, 6 February 2007 (CET)&lt;br /&gt;
* Added this section. The purpose is to keep people in sync with other&#039;s work. You should add here the brief description of your daily results. Use signature icon to put your name and date here. --[[User:Sojka|Sojka]] 15:18, 6 February 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Darcs repository ==&lt;br /&gt;
&lt;br /&gt;
You can [http://rtime.felk.cvut.cz/darcs/darcsweb.cgi?r=boa5200-linux browse the repository] or you can download it by:&lt;br /&gt;
 darcs get &amp;lt;login&amp;gt;@rtime.felk.cvut.cz:/var/repos/boa5200-linux&lt;br /&gt;
or&lt;br /&gt;
 darcs get http://rtime.felk.cvut.cz/repos/boa5200-linux&lt;br /&gt;
&lt;br /&gt;
== Úkoly ==&lt;br /&gt;
&lt;br /&gt;
Vždy když je úkol splněný přeškrtněte ho a případně k němu napište komentář.&lt;br /&gt;
&lt;br /&gt;
* Carrier board - &#039;&#039;&#039;Libor&#039;&#039;&#039;&lt;br /&gt;
** Pridat NAND flash&lt;br /&gt;
&lt;br /&gt;
* Linux 2.6 - &#039;&#039;&#039;Pavel&#039;&#039;&#039;&lt;br /&gt;
** Žižka&lt;br /&gt;
** &amp;lt;strike&amp;gt;A&amp;amp;Micro&amp;lt;/strike&amp;gt; - poslali patch k 2.6 a novou verzi Redbootu, otestovano - OK   &lt;br /&gt;
** &amp;lt;strike&amp;gt;DENX &amp;lt;/strike&amp;gt;(&#039;&#039;&#039;Martin M.&#039;&#039;&#039;) - distribuce primarne urcena pro MPC5200Lite desku; pokus na desce BOA5200 byl neuspesny; z vyse uvedenych duvodu ani nema cenu resit  &lt;br /&gt;
* Linux 2.4 - &#039;&#039;&#039;Martin Ž.&#039;&#039;&#039;&lt;br /&gt;
** &amp;lt;strike&amp;gt;Překopilování 2.4&amp;lt;/strike&amp;gt; - nepodstatne, viz. rozchozeni jadra 2.6, kompilace 2.6 OK&lt;br /&gt;
** &amp;lt;strike&amp;gt;TFTP boot&amp;lt;/strike&amp;gt; OK&lt;br /&gt;
** &amp;lt;strike&amp;gt;Zkouška aplikace (Hello world)&amp;lt;/strike&amp;gt; - OK&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;SocketCAN&amp;lt;/strike&amp;gt; - &#039;&#039;&#039;Martin Ž.&#039;&#039;&#039; (pomůže Pavel) - OK&lt;br /&gt;
&lt;br /&gt;
* LinCAN - Petera&lt;br /&gt;
&lt;br /&gt;
* CANopen&lt;br /&gt;
** &amp;lt;strike&amp;gt;Boa5200 master&amp;lt;/strike&amp;gt; (&#039;&#039;&#039;Hamáek&#039;&#039;&#039;) - Canfestival tutorial added into [[HOWTO]] &lt;br /&gt;
** H8S slave (&#039;&#039;&#039;Benda&#039;&#039;&#039;)&lt;br /&gt;
** ?? slave (&#039;&#039;&#039;Hamáek&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
* Toolchain + User-space (&#039;&#039;&#039;Michal + Martin Ž.&#039;&#039;&#039;)&lt;br /&gt;
** GLIBC&lt;br /&gt;
** BusyBox&lt;br /&gt;
** PTXdist&lt;br /&gt;
&lt;br /&gt;
* Build sandbox (&#039;&#039;&#039;Michal&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
== Budoucí rozšíření ==&lt;br /&gt;
&lt;br /&gt;
* Při výrobě nových DPS pro BOA5200 zvážit přidání USB hosta. Zapojení dle: [http://www.synertronixx.de/download/AppNotes/AN009.pdf AN009] - AN pro zapojení USB host na datovou sběrnici.&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200&amp;diff=3119</id>
		<title>Boa5200</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200&amp;diff=3119"/>
		<updated>2007-10-23T15:34:37Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* koly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* [ftp://rtime.felk.cvut.cz/MPC5200 Original documentation]&lt;br /&gt;
* [http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html Redboot documentace] - Redboot howto na CD k desce je neaktualny.&lt;br /&gt;
* [[HOWTO]]&lt;br /&gt;
&lt;br /&gt;
== Work Progress ==&lt;br /&gt;
* New version of the root file-system. Telnet server is started during boot and tcpdump and strace was added from Debian. --[[User:Sojka|Sojka]] 20:40, 21 March 2007 (CET)&lt;br /&gt;
* Added links to darcs repository --[[User:Sojka|Sojka]] 16:42, 7 March 2007 (CET)&lt;br /&gt;
* few edits in HOWTO, successful test of TFTP boot, NFS from desktop OK --[[User:Zidekm|Zidekm]] 19:47, 19 February 2007 (CET)&lt;br /&gt;
* TODO - instalace CAN driveru&lt;br /&gt;
*HowTo k MPC5200 - done &lt;br /&gt;
--[[User:Molnam1|Molnam1]] 17:32, 9 February 2007 (CET)&lt;br /&gt;
*build toolchain+ kernel 2.6.18(Pavel P.); dhcp,tftp, root over nfs, testy (Martin M.) - done&lt;br /&gt;
--[[User:Molnam1|Molnam1]] 17:00, 6 February 2007 (CET)&lt;br /&gt;
* Added this section. The purpose is to keep people in sync with other&#039;s work. You should add here the brief description of your daily results. Use signature icon to put your name and date here. --[[User:Sojka|Sojka]] 15:18, 6 February 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Darcs repository ==&lt;br /&gt;
&lt;br /&gt;
You can [http://rtime.felk.cvut.cz/darcs/darcsweb.cgi?r=boa5200-linux browse the repository] or you can download it by:&lt;br /&gt;
 darcs get &amp;lt;login&amp;gt;@rtime.felk.cvut.cz:/var/repos/boa5200-linux&lt;br /&gt;
or&lt;br /&gt;
 darcs get http://rtime.felk.cvut.cz/repos/boa5200-linux&lt;br /&gt;
&lt;br /&gt;
== Úkoly ==&lt;br /&gt;
&lt;br /&gt;
Vždy když je úkol splněný přeškrtněte ho a případně k němu napište komentář.&lt;br /&gt;
&lt;br /&gt;
* Carrier board - &#039;&#039;&#039;Libor&#039;&#039;&#039;&lt;br /&gt;
** Pridat NAND flash&lt;br /&gt;
&lt;br /&gt;
* Linux 2.6 - &#039;&#039;&#039;Pavel&#039;&#039;&#039;&lt;br /&gt;
** Žižka&lt;br /&gt;
** &amp;lt;strike&amp;gt;A&amp;amp;Micro&amp;lt;/strike&amp;gt; - poslali patch k 2.6 a novou verzi Redbootu, otestovano - OK   &lt;br /&gt;
** &amp;lt;strike&amp;gt;DENX &amp;lt;/strike&amp;gt;(&#039;&#039;&#039;Martin M.&#039;&#039;&#039;) - distribuce primarne urcena pro MPC5200Lite desku; pokus na desce BOA5200 byl neuspesny; z vyse uvedenych duvodu ani nema cenu resit  &lt;br /&gt;
* Linux 2.4 - &#039;&#039;&#039;Martin Ž.&#039;&#039;&#039;&lt;br /&gt;
** &amp;lt;strike&amp;gt;Překopilování 2.4&amp;lt;/strike&amp;gt; - nepodstatne, viz. rozchozeni jadra 2.6, kompilace 2.6 OK&lt;br /&gt;
** &amp;lt;strike&amp;gt;TFTP boot&amp;lt;/strike&amp;gt; OK&lt;br /&gt;
** &amp;lt;strike&amp;gt;Zkouška aplikace (Hello world)&amp;lt;/strike&amp;gt; - OK&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;SocketCAN&amp;lt;/strike&amp;gt; - &#039;&#039;&#039;Martin Ž.&#039;&#039;&#039; (pomůže Pavel) - OK&lt;br /&gt;
&lt;br /&gt;
* LinCAN - Petera&lt;br /&gt;
&lt;br /&gt;
* CANopen&lt;br /&gt;
** &amp;lt;strike&amp;gt;Boa5200 master&amp;lt;/strike&amp;gt; (&#039;&#039;&#039;Hamáek&#039;&#039;&#039;) - Canfestival tutorial added into [[HOWTO]] &lt;br /&gt;
** H8S slave (&#039;&#039;&#039;Benda&#039;&#039;&#039;)&lt;br /&gt;
** ?? slave (&#039;&#039;&#039;Hamáek&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
* Toolchain + User-space (&#039;&#039;&#039;Michal + Martin Ž.&#039;&#039;&#039;)&lt;br /&gt;
** GLIBC&lt;br /&gt;
** BusyBox&lt;br /&gt;
** PTXdist&lt;br /&gt;
&lt;br /&gt;
* Build sandbox (&#039;&#039;&#039;Michal&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
== Budoucí rozšíření ==&lt;br /&gt;
&lt;br /&gt;
* Při výrobě nových DPS pro BOA5200 zvážit přidání USB hosta. Zapojení dle: [http://www.synertronixx.de/download/AppNotes/AN009.pdf AN009] - AN pro zapojení USB host na datovou sběrnici.&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
	<entry>
		<id>https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3118</id>
		<title>Boa5200 HOWTO</title>
		<link rel="alternate" type="text/html" href="https://rtime.felk.cvut.cz/hw/index.php?title=Boa5200_HOWTO&amp;diff=3118"/>
		<updated>2007-10-23T15:31:21Z</updated>

		<summary type="html">&lt;p&gt;Hamacl1: /* CanFestival */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This document describes how to install and setup Linux and development environment for BOA5200  board. &lt;br /&gt;
Assume that you have a development machine (your PC) that you use for development and building your applications which you consequently want to get running and test on BOA5200.&lt;br /&gt;
&lt;br /&gt;
==Serial line setting==&lt;br /&gt;
The easiest way to communicate with the board ,when there is no OS and remote shell running on it, is over serial line. Recommended serial communication program is minicom. Setup minicom as follows:&lt;br /&gt;
&lt;br /&gt;
Baud Rate – 38400&lt;br /&gt;
&lt;br /&gt;
Bits - 8&lt;br /&gt;
&lt;br /&gt;
Parity – N&lt;br /&gt;
&lt;br /&gt;
Stop Bits - 1&lt;br /&gt;
&lt;br /&gt;
Hardware Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
Software Flow Control:- No&lt;br /&gt;
&lt;br /&gt;
After the setup you will see Redboot&amp;gt; command prompt. Here you can enter Redboot`s commands.&lt;br /&gt;
Redboot is a simple boot manager bulit upon eCos real-time OS. For more details , see http://ecos.sourceware.org/ecos/docs-latest/redboot/redboot-guide.html.&lt;br /&gt;
&lt;br /&gt;
==DHCP server setup==&lt;br /&gt;
Redboot supports BOOTP protocol which means that it is able to get network information(IP,netmask,gateway IP address,etc.) from DHCP server(provides BOOTP besides DHCP protocol). Install dhcp server (on debian: apt-get install dhcpd) on your development machine. Example of my dhcp configuration file /etc/dhcpd.conf:&lt;br /&gt;
 # I have two ethernet interfaces: &lt;br /&gt;
 # eth0 - Internet&lt;br /&gt;
 # eth1 - connection to BOA5200 (IP= 192.168.10.1)&lt;br /&gt;
 # I do not want to progate infos to 147.32.0.0 subnetwork&lt;br /&gt;
 subnet 147.32.0.0 netmask 255.255.0.0 {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 # private subnetwork&lt;br /&gt;
 subnet 192.168.10.0 netmask 255.255.255.0 {&lt;br /&gt;
  option broadcast-address 192.168.10.255;&lt;br /&gt;
  option routers 192.168.10.1;&lt;br /&gt;
  option subnet-mask 255.255.255.0;&lt;br /&gt;
  default-lease-time 600;&lt;br /&gt;
  max-lease-time 7200;&lt;br /&gt;
 &lt;br /&gt;
 # settings for BOA5200&lt;br /&gt;
  host BOA5200 {&lt;br /&gt;
   hardware ethernet 00:08:f1:11:22:33;&lt;br /&gt;
   fixed-address 192.168.10.2;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start dhcp server and reboot the board. After booting it has assigned IP, netmask and gateway address:&lt;br /&gt;
 +PHY0: AMD AM79C874&lt;br /&gt;
 FEC eth0: 100Mb/Full Duplex&lt;br /&gt;
 Ethernet eth0: MAC address 00:08:f1:11:22:33&lt;br /&gt;
 IP: 192.168.10.2/255.255.255.0, Gateway: 192.168.10.1&lt;br /&gt;
 Default server: 192.168.10.1&lt;br /&gt;
&lt;br /&gt;
==TFTP server setup==&lt;br /&gt;
Redboot is able to load file from remote tftp server into memory. Tftp server is lanuched by inetd daemon when a new &lt;br /&gt;
connection comes. &lt;br /&gt;
Therefore add the following line into /etc/inetd.conf :&lt;br /&gt;
 tftp            dgram   udp     wait    nobody  /usr/sbin/tcpd  /usr/sbin/in.tftpd&lt;br /&gt;
&lt;br /&gt;
Default tftp root directory is /tftpboot. You can change it by calling in.tftpd with specified directory as a parameter.&lt;br /&gt;
&lt;br /&gt;
===Alternative way for Ubuntu based distro===&lt;br /&gt;
&lt;br /&gt;
1. Install tftpd and related packages.&lt;br /&gt;
 sudo apt-get install xinetd tftpd tftp&lt;br /&gt;
&lt;br /&gt;
2. Create /etc/xinetd.d/tftp and put this entry:&lt;br /&gt;
&lt;br /&gt;
 service tftp&lt;br /&gt;
 {&lt;br /&gt;
 protocol        = udp&lt;br /&gt;
 port            = 69&lt;br /&gt;
 socket_type     = dgram&lt;br /&gt;
 wait            = yes&lt;br /&gt;
 user            = nobody&lt;br /&gt;
 server          = /usr/sbin/in.tftpd&lt;br /&gt;
 server_args     = /tftpboot&lt;br /&gt;
 disable         = no&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
3. Make /tftpboot directory&lt;br /&gt;
&lt;br /&gt;
 sudo mkdir /tftpboot&lt;br /&gt;
 sudo chmod -R 777 /tftpboot&lt;br /&gt;
 sudo chown -R nobody /tftpboot&lt;br /&gt;
&lt;br /&gt;
4. Start tftpd through xinetd&lt;br /&gt;
&lt;br /&gt;
 sudo /etc/init.d/xinetd start&lt;br /&gt;
&lt;br /&gt;
see [[http://www.example.com Installing and setting TFTPD in Ubuntu]]&lt;br /&gt;
&lt;br /&gt;
==Tool chain==&lt;br /&gt;
Toolchain(gcc, ld, ...) for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Unpack the archive:&lt;br /&gt;
&lt;br /&gt;
 cd /&lt;br /&gt;
 tar xvzf gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
&lt;br /&gt;
You can also create a debian package from archive and then install the package:&lt;br /&gt;
 alien --to-deb gcc-powerpc-603e-linux-gnu-4.1.1-bin.tar.gz&lt;br /&gt;
Note: If you are not root, use fakeroot to run the command.&lt;br /&gt;
&lt;br /&gt;
==Applying kernel patches==&lt;br /&gt;
It is recommended to use [http://linux.die.net/man/1/quilt quilt] tool to manage series of patches.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mini-Howto:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Assuming kernel sources are in directory /usr/src/linux.&lt;br /&gt;
&lt;br /&gt;
1. cd /usr/src/linux&lt;br /&gt;
&lt;br /&gt;
2. mkdir patches&lt;br /&gt;
&lt;br /&gt;
3. Copy all patches you want to apply to &#039;&#039;patches&#039;&#039; subdirectory&lt;br /&gt;
&lt;br /&gt;
4. Create &#039;&#039;series&#039;&#039; file in &#039;&#039;patches&#039;&#039; subdirectory and write names of patch files each on separate line. The order &lt;br /&gt;
the patches are stated in the file is significant!! The patch on the first line will be applied first followed by others.&lt;br /&gt;
&lt;br /&gt;
4. &#039;&#039;quilt push&#039;&#039; (&#039;&#039;quilt pop&#039;&#039;)  - applies (unapplies) all patches in &#039;&#039;series&#039;&#039; file&lt;br /&gt;
&lt;br /&gt;
==Building kernel==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.4 kernel sources&#039;&#039;&#039; for MPC5200 can be found in &#039;&#039;eCos_Linux_boa5200/tgz&#039;&#039; directory on BOARD DOCUMENTATION CD or from ftp://rtime.felk.cvut.cz/MPC5200/kernel_2.4/linuxppc-2.4-boa5200-release_2006_05_10.tgz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.6 Kernel sources&#039;&#039;&#039; for MPC5200 can be downloaded from ftp://rtime.felk.cvut.cz/MPC5200/linuxppc-2.6.18-1_AM.tar.gz.&lt;br /&gt;
Default kernel configuration file is ftp://rtime.felk.cvut.cz/MPC5200/config-2.6.18-1_AM.&lt;br /&gt;
Do not forget to set ARCH and CROSS_COMPILE variables to this values in Makefile:&lt;br /&gt;
 ARCH=ppc&lt;br /&gt;
 CROSS_COMPILE=powerpc-603e-linux-gnu-&lt;br /&gt;
&lt;br /&gt;
After compilation a built image is placed into arch/ppc/boot/image directory.&lt;br /&gt;
&lt;br /&gt;
The following commnad will install modules into &#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039;/lib/modules/...&lt;br /&gt;
 make INSTALL_MOD_PATH=&#039;&#039;&amp;lt;directory&amp;gt;&#039;&#039; modules_install   &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Make the building directory linuxppc-2.6.18-1_AM_build, where object files will be placed, outside the origin source directory linuxppc-2.6.18-1_AM&lt;br /&gt;
&lt;br /&gt;
 mkdir linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
2. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM &lt;br /&gt;
linuxppc-2.6.18-1_AM directory must be clean i.e. no make, make menuconfig executed from this directory&lt;br /&gt;
before!&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
 make O=../linuxppc-2.6.18-1_AM_build menuconfig  &lt;br /&gt;
kernel config file (.config) will be created in   linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
Next time, always run make menuconfig always from the building directory, i.e. linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
4. &lt;br /&gt;
 cd linuxppc-2.6.18-1_AM_build&lt;br /&gt;
&lt;br /&gt;
5. &lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/GNUmakefile&lt;br /&gt;
&lt;br /&gt;
6. &lt;br /&gt;
Edit GNUmakefile and change paths in KERNELSRC and KERNELOUTPUT variables&lt;br /&gt;
&lt;br /&gt;
7. &lt;br /&gt;
 make &amp;amp;&amp;amp; make modules_install&lt;br /&gt;
&lt;br /&gt;
== Loading kernel ==&lt;br /&gt;
&lt;br /&gt;
You can test your new image on the board as follows:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
   RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 &lt;br /&gt;
 # execute image; root directory (/) is on flash memory&lt;br /&gt;
   RedBoot&amp;gt; exec&lt;br /&gt;
If you want to load the kernel from different TFTP server than the one provided by DHCP, you can use the following command to set the IP address of your server:&lt;br /&gt;
   RedBoot&amp;gt; ip_address -h 147.32.86.&amp;lt;xxx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CAUTION:&#039;&#039;&#039; you must boot the kernel by  RedBoot release at least 2007_02_01 otherwise it will not run! So you must load into RAM and then run the appropriate RedBoot image (or replace/update its image on flash with the new one - see  &lt;br /&gt;
the next section) and after then you can execute kernel image.&lt;br /&gt;
&lt;br /&gt;
==Updating RedBoot==&lt;br /&gt;
Download ftp://rtime.felk.cvut.cz/MPC5200/MPC5200-2007.02.01-redbootROMRAM.srec &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # load RedBoot image from tftp server into memory at the address 0x100000&lt;br /&gt;
 RedBoot&amp;gt;lo -b 0x100000 MPC5200-2007.02.01-redbootROMRAM.srec&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!!! Warning: File names are case-sensitive !!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # write image in flash memory&lt;br /&gt;
 RedBoot&amp;gt;fi cr RedBoot&lt;br /&gt;
 RedBoot&amp;gt;reset&lt;br /&gt;
&lt;br /&gt;
If upgrade fails you can fallback to ROM Redboot image by typing &#039;A&amp;amp;M:&#039;&lt;br /&gt;
&lt;br /&gt;
If image of ROMRAM version of RedBoot with name &amp;quot;RedBoot&amp;quot; (case sensitive!!) is not found in FLASH minimal version of ROM RedBoot is started. This version does not support many services like TFTP protocol and FLASH management. To download ROMRAM version of RedBoot to FLASH it is necessary to follow these steps:&lt;br /&gt;
&lt;br /&gt;
Load RAM version of RedBoot to BOA using xmodem (the image file MPC5200-2006.05.10-redbootRAM.srec is placed on BOA original CD):&lt;br /&gt;
 RedBoot&amp;gt; lo -m xmodem&lt;br /&gt;
&lt;br /&gt;
When finished RedBoot should answer with something like that:&lt;br /&gt;
&lt;br /&gt;
 CEntry point: 0x00080100, address range: 0x00080000-0x000bea04&lt;br /&gt;
 xyzModem - CRC mode, 5763(SOH)/0(STX)/0(CAN) packets, 1 retries&lt;br /&gt;
&lt;br /&gt;
Then start the RedBoot:&lt;br /&gt;
 RedBoot&amp;gt; go&lt;br /&gt;
&lt;br /&gt;
RAM RedBoot should start now. Download the new version of ROMRAM RedBoot to FLASH according to the steps above.&lt;br /&gt;
&lt;br /&gt;
==NFS-root setup==&lt;br /&gt;
&lt;br /&gt;
During the development phase of application it must be tested many times. However, it is annoying to copy several application files to flash memory every time.  The practical solution is to mount via NFS working directory or whole root directory from the point of OS running on the board.&lt;br /&gt;
&lt;br /&gt;
You can download already prepared root directory from ftp://rtime.felk.cvut.cz/MPC5200/MPC5200_root_070321.tar.gz&lt;br /&gt;
&lt;br /&gt;
To export /var/MPC5200_root directory via NFS add the following line to /etc/exports:&lt;br /&gt;
&lt;br /&gt;
 /var/MPC5200_root 192.168.10.0/255.255.255.0(rw,sync,no_root_squash)&lt;br /&gt;
&lt;br /&gt;
Then run command &#039;exportfs -ra&#039; so that the change take an effect.&lt;br /&gt;
&lt;br /&gt;
If you want MPC5200 to be mount as root directory instead of that one in flash memory:&lt;br /&gt;
 # load kernel image from tftp server into memory&lt;br /&gt;
  RedBoot&amp;gt; load zImage.elf&lt;br /&gt;
 # execute kernel image with information where to &lt;br /&gt;
 # find root directory in parameter string&lt;br /&gt;
  RedBoot&amp;gt; ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.10.1:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: exportfs is a part of knfs package for debian systems (ubuntu,...)&lt;br /&gt;
&lt;br /&gt;
== Login with telnet ==&lt;br /&gt;
 telnet &amp;lt;ip address of boa&amp;gt;&lt;br /&gt;
Log in as root, ask me for the password. --[[User:Sojka|Sojka]] 20:42, 21 March 2007 (CET)&lt;br /&gt;
==Setting up BOA5200==&lt;br /&gt;
&lt;br /&gt;
Use &#039;fconfig&#039; command (see http://ecos.sourceware.org/ecos/docs-latest/redboot/persistent-state-flash.html manual) to set up BOA5200 configuration. Recommended configuration:&lt;br /&gt;
&lt;br /&gt;
 Run script at boot: true&lt;br /&gt;
 Boot script:&lt;br /&gt;
  load zImage.elf&lt;br /&gt;
  ex -c &amp;quot;root=/dev/nfs rw nfsroot=192.168.123.254:/var/MPC5200_root ip=dhcp&amp;quot;&lt;br /&gt;
 Boot script timeout (1000ms resolution): 10 &lt;br /&gt;
 Use BOOTP for network configuration: true&lt;br /&gt;
 Default server IP address: IP address of your computer&lt;br /&gt;
 FEC Network hardware address [MAC]: choose MAC address of the unit (example: 0x00:0x00:0x00:0x00:0x00:0x02)&lt;br /&gt;
 GDB connection port: 9000&lt;br /&gt;
 Force console for special debug messages: false&lt;br /&gt;
 Network debug at boot time: false&lt;br /&gt;
 Update RedBoot non-volatile configuration - continue (y/n)? y&lt;br /&gt;
&lt;br /&gt;
==Socketcan==&lt;br /&gt;
&lt;br /&gt;
Prior to compiling linux kernel with socketcan driver, it is necessary to [http://rtime.felk.cvut.cz/hw/index.php/HOWTO#Applying_kernel_patches  apply kernel patches] , which can be found in [http://rtime.felk.cvut.cz/repos/boa5200-linux/patches/ DARCS repository]&lt;br /&gt;
&lt;br /&gt;
To set up can interface, it is necessary to configure the communication speed first and then bring the interface up. Communication speed can be set up using following command (for can0 interface):&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
&lt;br /&gt;
The constant 660000 was found experimentally, driver seems to calculate the transmission speed improperly. To bring up the can network interface, use the same command as with any other network interface, i.e.&lt;br /&gt;
&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
&lt;br /&gt;
The most comfortable way of setting up both can interfaces upon startup of system is to place following script to /etc/init.d/ (name it &#039;can&#039;, for example)&lt;br /&gt;
&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can0/can_baudrate&lt;br /&gt;
 echo 660000 &amp;gt;/sys/class/net/can1/can_baudrate&lt;br /&gt;
 ifconfig can0 up&lt;br /&gt;
 ifconfig can1 up&lt;br /&gt;
&lt;br /&gt;
==CanFestival==&lt;br /&gt;
&lt;br /&gt;
===Obtaining and building CanFestival===&lt;br /&gt;
&lt;br /&gt;
CanFestival driver source can be downloaded from. The primary way how to do it is to check out the source directory from CanFestival CVS by these steps:&lt;br /&gt;
 cvs -d:pserver:anonymous@lolitech.dyndns.org:/canfestival login&lt;br /&gt;
 (type return, without entering a password)&lt;br /&gt;
The system will respond:&lt;br /&gt;
 Logging in to :pserver:anonymous@lolitech.dyndns.org:2401/canfestival&lt;br /&gt;
Then, enter:&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@lolitech.dyndns.org:/canfestival co -P CanFestival-3&lt;br /&gt;
Then insert CanFestival folder and run this commands:&lt;br /&gt;
 ./configure --timers=unix --can=socket --cc=powerpc-603e-linux-gnu-gcc --arch=ppc --os=linux --target=unix &lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
Building of CanFestival will produce some libraries and copy them to /usr/powerpc-603e-linux-gnu/lib folder.&lt;br /&gt;
&lt;br /&gt;
===Setting up local CANopen node===&lt;br /&gt;
&lt;br /&gt;
CanFestival source includes tool called &#039;&#039;objdictedit&#039;&#039;. This program has graphical user interface and serves to creating configuration of the CANopen node of application we develop. It is started by command &#039;&#039;objdictedit&#039;&#039;. Using this program you can create the object dictionary for the CanFestival. Mainly it is necessary to set up all SDO and PDO, the node has to send and receive. To each PDO you have to define more things - PDO receive or transmit, variable to be mapped and variable mapping. The variable will then be used in application code to exchange data between CanFestival driver and application. If you set up PDOs here they will be sent and received automatically and the values will be stored into mapped variable. Setting up SDO means that you can use it in your application, but if you want to send it, it has to be done in code.&lt;br /&gt;
After creating this basic configuration you have to build the dictionary which results into to files with extensions .h and .c. You have to link these files with your application.&lt;br /&gt;
&lt;br /&gt;
===Initializing and starting CanFestival===&lt;br /&gt;
&lt;br /&gt;
To explain how to use CanFestival I include some code examples. It supposes node configuration generated by &#039;&#039;objdictedit&#039;&#039; which name is &#039;&#039;canopen&#039;&#039;. It is then used as prefix of automatically generated functions and variables (&#039;&#039;canopen_Data&#039;&#039; is for example object dictionary used by CanFestival). &lt;br /&gt;
Header &#039;&#039;canfestival.h&#039;&#039; has to be included. For start using CanFestival it is necessary to load dynamic library with CAN bus driver API created while compiling CanFestival source. In the example SocketCan driver is used to access CAN bus. &lt;br /&gt;
 if(!LoadCanDriver(&amp;quot;libcanfestival_can_socket.so&amp;quot;)) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
Then you have to open CAN device. Parameters of the communication have to be prepared in structure of type &#039;&#039;s_Board&#039;&#039;. In this case CAN is set to use device &#039;&#039;can1&#039;&#039; and baudrate 1Mbps. Handler of the bus is then stored to variable of type &#039;&#039;CAN_HANDLE&#039;&#039;.&lt;br /&gt;
 /**&lt;br /&gt;
  * CAN board definition.&lt;br /&gt;
  * Device name can1, baudrate 1M&lt;br /&gt;
  */&lt;br /&gt;
 s_BOARD canopen_board = {&amp;quot;1&amp;quot;, &amp;quot;1000&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
 CAN_HANDLE canopen_handle;&lt;br /&gt;
 &lt;br /&gt;
 if(!(canopen_handle = canOpen(&amp;amp;canopen_board, &amp;amp;canopen_Data))) {&lt;br /&gt;
 	exit -1;&lt;br /&gt;
 }&lt;br /&gt;
CanFestival implements callbacks to some events like change of state or message reception. There are pointers to callback functions in &#039;&#039;canopen_Data&#039;&#039; structure. You can assign your own functions to these pointers or leave them unused.&lt;br /&gt;
 canopen_Data.initialisation = canopen_initialisation;&lt;br /&gt;
 canopen_Data.preOperational = canopen_preOperational; &lt;br /&gt;
 canopen_Data.operational = canopen_operational; &lt;br /&gt;
 canopen_Data.post_sync = canopen_post_sync; &lt;br /&gt;
 canopen_Data.post_TPDO = canopen_post_TPDO; &lt;br /&gt;
 canopen_Data.stopped = canopen_stopped; &lt;br /&gt;
After setting up these few things you have to call function &#039;&#039;StartTimerLoop&#039;&#039; which initializes CanFestival timers. As an argument you have to insert pointer to the first function you want to proceed after starting the timers. &lt;br /&gt;
 StartTimerLoop(&amp;amp;initNode); &lt;br /&gt;
Here is an example of such a function. It sets local node ID to 1 and bring the node to operation state. Callback functions are called after changing state if used.&lt;br /&gt;
 void initNode(CO_Data * d, UNS32 id)&lt;br /&gt;
 {&lt;br /&gt;
 	setNodeId(&amp;amp;canopen_Data, 0x01);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Initialisation);&lt;br /&gt;
	setState(&amp;amp;canopen_Data, Operational);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Stopping CanFestival===&lt;br /&gt;
&lt;br /&gt;
After finishing work with CANopen it is good to stop the communication and timers and close the device. It is done by these few functions.&lt;br /&gt;
 setState(&amp;amp;canopen_Data, Stopped);&lt;br /&gt;
 StopTimerLoop();&lt;br /&gt;
 canClose(&amp;amp;canopen_Data);&lt;br /&gt;
 canopen_handle = NULL;&lt;br /&gt;
&lt;br /&gt;
===Writing to Object dictionary===&lt;br /&gt;
&lt;br /&gt;
CANopen devices and all network services of each node are configured by writing to device object dictionary (OD). It is different while writing to local OD or OD of some network device.&lt;br /&gt;
====Writing to local OD====&lt;br /&gt;
Function &#039;&#039;WriteLocalDict&#039;&#039; is used for writing to OD of local node managed by CanFestival.&lt;br /&gt;
 UNS32 writeLocalDict( CO_Data* d, &lt;br /&gt;
 UNS16 wIndex, &lt;br /&gt;
 UNS8 bSubindex, &lt;br /&gt;
 void * pSourceData, &lt;br /&gt;
 UNS8 * pExpectedSize, &lt;br /&gt;
 UNS8 checkAccess);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;wIndex&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;bSubindex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this   index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;pbSourceData&#039;&#039;&#039; - pointer to the variable that holds the value that should be copied into the object dictionary&lt;br /&gt;
 &#039;&#039;&#039;pExpectedSize&#039;&#039;&#039; - pointer to variable with size of the data to be written&lt;br /&gt;
 &#039;&#039;&#039;CheckAccess&#039;&#039;&#039; - if other than 0, do not read if the data is Read Only or Constant&lt;br /&gt;
&lt;br /&gt;
====Writing to network OD====&lt;br /&gt;
&lt;br /&gt;
It is necessary to use SDO service for writing data to OD of some network device. Each CANopen device has at least one SDO server. It means that it is able to receive SDOs with one ID and answer by SDOs with another ID. It is usual that the server listen for SDOs with ID 0x600 + ID of the node and transmits SDOs of ID 0x580 + node ID. Each SDO we want to use has to be defined while creating node configuration by &#039;&#039;objdictedit&#039;&#039;. Then the SDO is sent by calling appropriate function. The best is to use function &#039;&#039;writeNetworkDictCallBack&#039;&#039; which syntax is shown below.&lt;br /&gt;
 UNS8 writeNetworkDictCallBack (CO_Data* d, &lt;br /&gt;
 UNS8 nodeId, &lt;br /&gt;
 UNS16 index,&lt;br /&gt;
 UNS8 subIndex, &lt;br /&gt;
 UNS8 count, &lt;br /&gt;
 UNS8 dataType, &lt;br /&gt;
 void *data, &lt;br /&gt;
 SDOCallback_t Callback);&lt;br /&gt;
Meaning of function arguments:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we want to send SDO&lt;br /&gt;
 &#039;&#039;&#039;index&#039;&#039;&#039; - the index in the object dictionary where you want to write an entry&lt;br /&gt;
 &#039;&#039;&#039;subIndex&#039;&#039;&#039; - the subindex of the Index. e.g. mostly subindex 0 is used to tell you how many valid entries you can find in this index. Look at the canopen standard for further information&lt;br /&gt;
 &#039;&#039;&#039;count&#039;&#039;&#039; - number of bytes to be written&lt;br /&gt;
 &#039;&#039;&#039;dataType&#039;&#039;&#039; - type of the data, use 0 for integers, real numbers and other values&lt;br /&gt;
 &#039;&#039;&#039;data&#039;&#039;&#039; - pointer to the data&lt;br /&gt;
 &#039;&#039;&#039;Callback&#039;&#039;&#039; - pointer to a function which is called after finishing the transfer&lt;br /&gt;
The SDO service is by definition confirmed. It means that SDO server sends response with result of the transfer after each SDO reception. This response has to be read by client to be sure that the data were written correctly. The result should be read in your function which pointer is given to the function &#039;&#039;writeNetworkDictCallBack&#039;&#039; as parameter &#039;&#039;callback&#039;&#039;. The result of SDO transfer in such a function is read by CanFestival function &#039;&#039;getWriteResultNetworkDict&#039;&#039;. This function has to be called after each SDO transmission because it releases line used to transfer. Header of this function is:&lt;br /&gt;
 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;nodeId&#039;&#039;&#039; - ID of the device we have sent SDO&lt;br /&gt;
 &#039;&#039;&#039;abortCode&#039;&#039;&#039; - pointer to the variable where error code is written in case of error&lt;br /&gt;
The function can return one of these values according to the SDO transfer state:&lt;br /&gt;
 &#039;&#039;&#039;SDO_FINISHED&#039;&#039;&#039; - data is available&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_RCV&#039;&#039;&#039; - Transfer failed. (abort SDO received)&lt;br /&gt;
 &#039;&#039;&#039;SDO_ABORTED_INTERNAL&#039;&#039;&#039; - Transfer failed. Internal abort.&lt;br /&gt;
 &#039;&#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;&#039; - Data not yet available&lt;br /&gt;
The function can be used in cycle waiting while return value is &#039;&#039;SDO_DOWNLOAD_IN_PROGRESS&#039;&#039;. But the better solution is calling it in callback function from &#039;&#039;writeNetworkDictCallBack&#039;&#039;. The callback is call after finishing the transfer.&lt;br /&gt;
&lt;br /&gt;
===Using PDO service===&lt;br /&gt;
&lt;br /&gt;
Using PDO service for data exchange is very easy in CanFestival. The most usual transmission type of PDOs is that they are transmitted after SYNC message. In this case it just has to be set up in objdictedit configuration and then it works, reads and stores values into mapped variables. After each PDO reception or transmission &#039;&#039;post_TPDO&#039;&#039; callback is called if used. &lt;br /&gt;
Sometimes it is necessary to send PDO from code without SYNC message reception. This is very inconsistent in CanFestival version 3. There are some functions which should solve this situation but they are commented and some other solution is promised to be done in the future. For now I have done it by using function sendPDO which syntax is:&lt;br /&gt;
 UNS8 sendPDO (CO_Data* d, s_PDO pdo, UNS8 request);&lt;br /&gt;
And meaning of function arguments is:&lt;br /&gt;
 &#039;&#039;&#039;d&#039;&#039;&#039; - pointer to local object dictionary structure&lt;br /&gt;
 &#039;&#039;&#039;pdo&#039;&#039;&#039; - structure with PDO message&lt;br /&gt;
 &#039;&#039;&#039;request&#039;&#039;&#039; - REQUEST (request for sending PDO) or NOT_A_REQUEST (normal PDO)&lt;br /&gt;
PDO message has to be created using structure s_PDO which meaning is clear:&lt;br /&gt;
 typedef struct struct_s_PDO {&lt;br /&gt;
   	UNS32 cobId;	  	/* COB-ID */&lt;br /&gt;
   	UNS8 len;	  	/* Number of data transmitted (in data[]) */&lt;br /&gt;
   	UNS8 data[8]; 	/* Contain the data */&lt;br /&gt;
 } s_PDO;&lt;br /&gt;
&lt;br /&gt;
===Generating SYNC message===&lt;br /&gt;
&lt;br /&gt;
If you want to set up local node to become the SYNC server you have to write some information to local OD. Here is an example of function which set up the SYNC messages generation:&lt;br /&gt;
 /**&lt;br /&gt;
  * This function initializes local canopen node to send SYNC message&lt;br /&gt;
  * with given period. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param period - period of the SYNC message in us&lt;br /&gt;
  */&lt;br /&gt;
 void synchro_setup(CO_Data *d, unsigned long period)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 SYNC_COBID = 0x40000080;&lt;br /&gt;
 	UNS32 SYNC_INTER = period;&lt;br /&gt;
 	UNS8 size = sizeof(UNS32); &lt;br /&gt;
 	writeLocalDict(d, 0x1006, 0x0, &amp;amp;SYNC_INTER, &amp;amp;size, RW);&lt;br /&gt;
 	writeLocalDict(d, 0x1005, 0x0, &amp;amp;SYNC_COBID, &amp;amp;size, RW);&lt;br /&gt;
 }&lt;br /&gt;
According to CANopen specification ID of the SYNC message is 0x80.&lt;br /&gt;
After the setup it can be started by command &#039;&#039;startSYNC(CO_Data *d)&#039;&#039; and stopped by command &#039;&#039;stopSYNC(CO_Data *d)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===SDO and PDO example===&lt;br /&gt;
&lt;br /&gt;
At the end I attach example of a function (&#039;&#039;cpd_start()&#039;&#039;) which starts some device communicating by CANopen. The ID of the device is given by the parameter. The other function (&#039;&#039;cpd_checkSDO_start()&#039;&#039;) is callback used to handle SDO transfer result. It is necessary to wait until one SDO transfer is finished before starting some other. Global variable &#039;&#039;cpd_init_step&#039;&#039; is used for counting actual step of SDO transfer. If some SDO transfer fails it is set to -1 and the startup process is terminated. &lt;br /&gt;
 /**&lt;br /&gt;
  * This function is given to the writeNetworkDict function as a callback.&lt;br /&gt;
  * It checks the result of SDO transmition and after finishing the transmition&lt;br /&gt;
  * it closes the transfer.&lt;br /&gt;
  * @param d - local object disctionary&lt;br /&gt;
  * @param nodeID - ID of the node which the local node is communicating with&lt;br /&gt;
  */ &lt;br /&gt;
 void cpd_checkSDO_start(CO_Data* d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS32 abortCode;	&lt;br /&gt;
 	if(getWriteResultNetworkDict (d, nodeId, &amp;amp;abortCode) != SDO_FINISHED) {&lt;br /&gt;
 		cpd_init_step = -1;&lt;br /&gt;
 	}&lt;br /&gt;
 	closeSDOtransfer(&amp;amp;canopen_Data, nodeId, SDO_CLIENT);&lt;br /&gt;
 	cpd_start(&amp;amp;canopen_Data, nodeId);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /**&lt;br /&gt;
  * This function switch canopen device into operational state. &lt;br /&gt;
  * @param d - local object dictionary&lt;br /&gt;
  * @param nodeId - ID of the device&lt;br /&gt;
  * return 0 - ok, -1 - failed&lt;br /&gt;
  */&lt;br /&gt;
 int cpd_start(CO_Data *d, UNS8 nodeId)&lt;br /&gt;
 {&lt;br /&gt;
 	UNS8 data8;&lt;br /&gt;
 	UNS16 data16;&lt;br /&gt;
 	UNS32 data32;&lt;br /&gt;
 	switch(cpd_init_step++) {&lt;br /&gt;
 		case 0:&lt;br /&gt;
 			masterSendNMTstateChange(d, nodeId, NMT_Start_Node);&lt;br /&gt;
 			s_PDO pdo;&lt;br /&gt;
 			cpd_controlword = 0;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			int i = 0;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 6;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 7;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 			cpd_controlword = 0x0F;&lt;br /&gt;
 			pdo.cobId = 0x200 + nodeId;&lt;br /&gt;
 			for(i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
 				pdo.data[i] = 0;&lt;br /&gt;
 			}&lt;br /&gt;
 			pdo.data[0] = 0xF;&lt;br /&gt;
 			pdo.data[1] = 0;&lt;br /&gt;
 			pdo.len = sizeof(pdo.data);&lt;br /&gt;
 			sendPDO(d, pdo, NOT_A_REQUEST);&lt;br /&gt;
 &lt;br /&gt;
 			// Start operational mode&lt;br /&gt;
 			data8 = 0xFC;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x6060, 0x00, 1, 0, &amp;amp;data8, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 1:&lt;br /&gt;
 			// Check operation status&lt;br /&gt;
 			readNetworkDictCallback(d, nodeId, 0x6061, 0x00, 0, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 2:&lt;br /&gt;
 			// Setpoint specification&lt;br /&gt;
 			data16 = 0x0002;&lt;br /&gt;
 			writeNetworkDictCallBack(d, nodeId, 0x301B, 0x11, 2, 0, &amp;amp;data16, cpd_checkSDO_start);&lt;br /&gt;
 			break;&lt;br /&gt;
 		case 3:&lt;br /&gt;
 			canopen_init_result = 0;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case -1:&lt;br /&gt;
 			canopen_init_result = -1;&lt;br /&gt;
 			cpd_init_step = 0;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 } &lt;br /&gt;
&lt;br /&gt;
===Emergency message===&lt;br /&gt;
&lt;br /&gt;
CanFestival version 3 does not support reception of emergency messages. I have worked it around by adding callback into CanFestival source just into function reading data from CAN bus. Function &#039;&#039;canReceive_driver&#039;&#039; is placed in file &#039;&#039;&amp;lt;canfestival_directory&amp;gt;/drivers/can_socket/can_socket.c&#039;&#039; (for SocketCan driver only!). I have created pointer to a function which is set by application.&lt;br /&gt;
 void (* emcy_callback)(Message *);&lt;br /&gt;
This code filters messages being received and all messages which ID agrees with EMCY service (0x80; 0x180) are sent to application function set as callback.&lt;br /&gt;
 if(m-&amp;gt;cob_id.w &amp;gt;= 0x81 &amp;amp;&amp;amp; m-&amp;gt;cob_id.w &amp;lt; 0x180) (*emcy_callback)(m);&lt;/div&gt;</summary>
		<author><name>Hamacl1</name></author>
	</entry>
</feed>