EDK OS and Libraries Reference Manual

Embedded Development Kit EDK 6.3i

UG114 (v3.0) August 20, 2004

R R

"Xilinx" and the Xilinx logo shown above are registered trademarks of Xilinx, Inc. Any rights not expressly granted herein are reserved. CoolRunner, RocketChips, Rocket IP, Spartan, StateBENCH, StateCAD, Virtex, XACT, XC2064, XC3090, XC4005, and XC5210 are registered trademarks of Xilinx, Inc.

The shadow X shown above is a trademark of Xilinx, Inc. ACE Controller, ACE Flash, A.K.A. Speed, Alliance Series, AllianceCORE, Bencher, ChipScope, Configurable Logic Cell, CORE Generator, CoreLINX, Dual Block, EZTag, Fast CLK, Fast CONNECT, Fast FLASH, FastMap, Fast Zero Power, Foundation, Gigabit Speeds...and Beyond!, HardWire, HDL Bencher, IRL, J Drive, JBits, LCA, LogiBLOX, Logic Cell, LogiCORE, LogicProfessor, MicroBlaze, MicroVia, MultiLINX, NanoBlaze, PicoBlaze, PLUSASM, PowerGuide, PowerMaze, QPro, Real-PCI, RocketIO, SelectIO, SelectRAM, SelectRAM+, Silicon Xpresso, Smartguide, Smart-IP, SmartSearch, SMARTswitch, System ACE, Testbench In A Minute, TrueMap, UIM, VectorMaze, VersaBlock, VersaRing, Virtex-II Pro, Virtex-II EasyPath, Wave Table, WebFITTER, WebPACK, WebPOWERED, XABEL, XACT- Floorplanner, XACT-Performance, XACTstep Advanced, XACTstep Foundry, XAM, XAPP, X-BLOX +, XC designated products, XChecker, XDM, XEPLD, Xilinx Foundation Series, Xilinx XDTV, Xinfo, XSI, XtremeDSP and ZERO+ are trademarks of Xilinx, Inc. The Programmable Logic Company is a service mark of Xilinx, Inc. All other trademarks are the property of their respective owners. Xilinx, Inc. does not assume any liability arising out of the application or use of any product described or shown herein; nor does it convey any license under its patents, copyrights, or maskwork rights or any rights of others. Xilinx, Inc. reserves the right to make changes, at any time, in order to improve reliability, function or design and to supply the best product possible. Xilinx, Inc. will not assume responsibility for the use of any circuitry described herein other than circuitry entirely embodied in its products. Xilinx provides any design, code, or information shown or described herein "as is." By providing the design, code, or information as one possible implementation of a feature, application, or standard, Xilinx makes no representation that such implementation is free from any claims of infringement. You are responsible for obtaining any rights you may require for your implementation. Xilinx expressly disclaims any warranty whatsoever with respect to the adequacy of any such implementation, including but not limited to any warranties or representations that the implementation is free from claims of infringement, as well as any implied warranties of merchantability or fitness for a particular purpose. Xilinx, Inc. devices and products are protected under U.S. Patents. Other U.S. and foreign patents pending. Xilinx, Inc. does not represent that devices shown or products described herein are free from patent infringement or from any other third party right. Xilinx, Inc. assumes no obligation to correct any errors contained herein or to advise any user of this text of any correction if such be made. Xilinx, Inc. will not assume any liability for the accuracy or correctness of any engineering or software support or assistance provided to a user. Xilinx products are not intended for use in life support appliances, devices, or systems. Use of a Xilinx product in such applications without the written consent of the appropriate Xilinx officer is prohibited. The contents of this manual are owned and copyrighted by Xilinx. Copyright 1994-2004 Xilinx, Inc. All Rights Reserved. Except as stated herein, none of the material may be copied, reproduced, distributed, republished, downloaded, displayed, posted, or transmitted in any form or by any means including, but not limited to, electronic, mechanical, photocopying, recording, or otherwise, without the prior written consent of Xilinx. Any unauthorized use of any material contained in this manual may violate copyright laws, trademark laws, the laws of privacy and publicity, and communications regulations and statutes.

EDK OS and Libraries Reference Manual www.xilinx.com UG114 (v3.0) August 20, 2004 1-800-255-7778 EDK OS and Libraries Reference Manual UG114 (v3.0) August 20, 2004

The following table shows the revision history for this document.

Version Revision 01/30/04 1.0 Initial release for EDK 6.2i. 03/12/04 Updated for service pack release. 03/19/04 2.0 Updated for service pack release. 08/20/04 3.0 Updated for EDK 6.3i.

UG114 (v3.0) August 20, 2004 www.xilinx.com EDK OS and Libraries Reference Manual 1-800-255-7778 EDK OS and Libraries Reference Manual www.xilinx.com UG114 (v3.0) August 20, 2004 1-800-255-7778 R Preface

About This Guide

This book describes the software packages provided by the Embedded Development Kit (EDK).

Guide Contents This book contains the following chapters. x Chapter 1, “Introduction” x Chapter 2, “Xilinx Microkernel (XMK)” x Chapter 3, “LibXil Standard C Libraries” x Chapter 4, “Standalone Board Support Package” x Chapter 5, “Xilkernel” x Chapter 6, “LibXil Net (v2.00.a)” x Chapter 7, “LibXil File” x Chapter 8, “LibXil FATFile System (FATfs)” x Chapter 9, “LibXil Memory File System (MFS)” x Chapter 10, “LibXil Profile” x Chapter 11, “lwIP Library”

Additional Resources For additional information, go to http://support.xilinx.com. The following table lists some of the resources you can access from this website. You can also directly access these resources using the provided URLs.

Resource Description/URL EDK Home Embedded Development Kit home page, FAQ and tips. http://www.xilinx.com/edk EDK Examples A set of complete EDK examples. http://www.xilinx.com/ise/embedded/edk_examples.htm Tutorials Tutorials covering Xilinx design flows, from design entry to verification and debugging http://support.xilinx.com/support/techsup/tutorials/index.htm

EDK OS and Libraries Reference Guide www.xilinx.com 5 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Preface: About This Guide

Resource Description/URL Answer Browser Database of Xilinx solution records http://support.xilinx.com/xlnx/xil_ans_browser.jsp Application Notes Descriptions of device-specific design techniques and approaches http://www.xilinx.com/xlnx/xweb/xil_publications_index.jsp?c ategory=Application+Notes Data Sheets Device-specific information on Xilinx device characteristics, including readback, boundary scan, configuration, length count, and debugging http://support.xilinx.com/xlnx/xweb/xil_publications_index.jsp Problem Solvers Interactive tools that allow you to troubleshoot your design issues http://support.xilinx.com/support/troubleshoot/psolvers.htm Tech Tips Latest news, design tips, and patch information for the Xilinx design environment http://www.support.xilinx.com/xlnx/xil_tt_home.jsp GNU Manuals The entire set of GNU manuals http://www.gnu.org/manual

Conventions This document uses the following conventions. An example illustrates each convention.

Typographical The following typographical conventions are used in this document:

Convention Meaning or Use Example Messages, prompts, and Courier font program files that the system speed grade: - 100 displays

Courier bold Literal commands that you ngdbuild design_name enter in a syntactical statement Commands that you select File o Open Helvetica bold from a menu Keyboard shortcuts Ctrl+C

6 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Conventions R

Convention Meaning or Use Example Variables in a syntax statement for which you must ngdbuild design_name supply values See the Development System Italic font References to other manuals Reference Guide for more information. If a wire is drawn so that it Emphasis in text overlaps the pin of a symbol, the two nets are not connected. An optional entry or parameter. However, in bus ngdbuild [ option_name] Square brackets [ ] specifications, such as design_name bus[7:0], they are required. A list of items from which you Braces { } lowpwr ={on|off} must choose one or more Separates items in a list of Vertical bar | lowpwr ={on|off} choices IOB #1: Name = QOUT’ Vertical ellipsis IOB #2: Name = CLKIN’ . Repetitive material that has . . been omitted . . .

Repetitive material that has allow block block_name Horizontal ellipsis . . . been omitted loc1 loc2 ... locn;

Online Document The following conventions are used in this document:

Convention Meaning or Use Example See the section “Additional Cross-reference link to a Resources” for details. Blue text location in the current document Refer to “Title Formats” in Chapter 1 for details. Cross-reference link to a See Figure 2-5 in the Virtex-II Red text location in another document Handbook. Go to http://www.xilinx.com Blue, underlined text Hyperlink to a website (URL) for the latest speed files.

EDK OS and Libraries Reference Guide www.xilinx.com 7 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Preface: About This Guide

8 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Table of Contents

Preface: About This Guide Guide Contents ...... 5 Additional Resources ...... 5 Conventions ...... 6 Typographical...... 6 Online Document ...... 7

Chapter 1: Introduction

Chapter 2: Xilinx Microkernel (XMK) Overview ...... 15 XMK Organization ...... 15

Chapter 3: LibXil Standard C Libraries Overview ...... 19 Standard C Library (libc.a) ...... 19 Xilinx C Library (libxil.a) ...... 20 Input/Output Functions ...... 20 Memory Management Functions ...... 21 MicroBlaze Processor ...... 21 PowerPC 405 Processor ...... 21 Arithmetic Operations ...... 21 MicroBlaze Processor ...... 21 Integer Arithmetic...... 21 Floating Point Arithmetic ...... 22 PowerPC 405 Processor ...... 22 Integer Arithmetic...... 22 Floating Point Arithmetic ...... 22

Chapter 4: Standalone Board Support Package MicroBlaze BSP ...... 23 Function Summary ...... 23 Interrupt Handling ...... 24 Exception Handling ...... 25 Instruction Cache Handling ...... 26 Data Cache Handling ...... 27 Fast Simplex Link Interface Macros ...... 28 PowerPC BSP ...... 29 Function Summary ...... 29 Boot Code ...... 30 boot.S ...... 30 crt0.S ...... 31

EDK OS and Libraries Reference Guide www.xilinx.com 9 UG114 (v3.0) August 20, 2004 1-800-255-7778 R

eabi.S...... 31 Cache ...... 31 Exception Handling ...... 33 Files ...... 35 Memory Management ...... 36 Process ...... 36 Processor-Specific Include Files ...... 36 Time ...... 37 typedef unsigned long long XTime; ...... 37

Chapter 5: Xilkernel Overview ...... 41 Why Use a Kernel? ...... 42 Key Features ...... 42 Xilkernel Organization ...... 43 Building Xilkernel Applications...... 43 Xilkernel Process Model...... 45 Xilkernel Scheduling Model...... 45 POSIX Interface...... 47 Function Summary ...... 48 Xilkernel API ...... 50 Management ...... 50 Semaphores ...... 59 Message Queues ...... 67 Shared Memory ...... 71 Mutex Locks ...... 75 Dynamic Buffer Memory Management ...... 79 Software Timers ...... 81 Interrupt Handling...... 82 Other Interfaces...... 85 Hardware Requirements and BSP ...... 85 System Initialization ...... 86 Kernel Customization ...... 87 Configuring STDIN and STDOUT ...... 88 Configuring Scheduling ...... 88 Configuring Thread Management ...... 89 Configuring Semaphores ...... 89 Configuring Message Queues ...... 90 Configuring Shared Memory ...... 90 Configuring Pthread Mutex Locks ...... 91 Configuring Buffer Memory Allocation ...... 91 Configuring Software Timers...... 92 Configuring Enhanced Interfaces ...... 92 Configuring System Timer ...... 92 Configuring Interrupt Handling ...... 93 Configuring Debug Messages ...... 93 Copy Kernel Source Files ...... 93 Debugging Xilkernel...... 93 Memory Footprint...... 94

10 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R

Xilkernel File Organization ...... 94 Modifying Xilkernel ...... 94 Advanced Features ...... 95 ELF Process Management ...... 95 Configuring ELF Process Management ...... 96 User Guide...... 96

Chapter 6: LibXil Net (v2.00.a) Overview ...... 99 LibXilNet Functions...... 100 Function Summary ...... 100 Protocols Supported...... 101 Library Architecture...... 101 Protocol Function Description ...... 103 Media Access Layer (MAC) Drivers Wrapper...... 103 Ethernet Drivers ...... 103 ARP (RFC 826) ...... 103 IP (RFC 791) ...... 103 ICMP (RFC 792) ...... 103 UDP (RFC 768) ...... 103 TCP (RFC 793) ...... 104 Sockets API ...... 104 Buffer Management ...... 104 Current Restrictions ...... 104 Functions of LibXilNet ...... 104 Configuring XilNet v2.00.a in EDK ...... 118 Using XilNet in Application ...... 119

Chapter 7: LibXil File Overview ...... 121 Module Usage ...... 121 Function Summary ...... 121 Module Routines...... 122 Libgen Support ...... 124 LibXil File Instantiation ...... 124 System Initialization ...... 125 Limitations ...... 125

Chapter 8: LibXil FATFile System (FATfs) Overview ...... 127 XilFatfs Functions ...... 128 Detailed Description of XilFatfsFunctions ...... 128 LibGen Customization ...... 131

Chapter 9: LibXil Memory File System (MFS) Overview ...... 133

EDK OS and Libraries Reference Guide www.xilinx.com 11 UG114 (v3.0) August 20, 2004 1-800-255-7778 R

MFS Functions ...... 133 Summary of MFS Functions ...... 133 Detailed Summary of MFS Functions ...... 135 Utility Functions ...... 142 Additional Utilities ...... 144 C-like access ...... 144 LibGen Customization ...... 145

Chapter 10: LibXil Profile Overview ...... 147 Features...... 147 Profiling Model ...... 148 Customizing xilprofile ...... 148 Building Applications...... 148 Application Memory Requirements ...... 149 Generating GPROF Files ...... 149 XilProfile Code Description ...... 150 Limitations ...... 151

Chapter 11: lwIP Library Overview ...... 153 PowerPC System ...... 153 MicroBlaze System...... 154 Memory Management ...... 155 Setting Up lwIP in EDK ...... 155 libgen Customization ...... 156 Designing an lwIP Application...... 156 Initializing lwIP ...... 157 lwIP Raw API ...... 157 Function Summary ...... 158 Raw API Functions for TCP ...... 158 Example lwIP Application...... 160 PowerPC based Echo Server...... 160 C Program...... 160 MicroBlaze-Based Echo Server...... 175 C Program...... 175

12 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 1

Introduction

This book describes the software packages that are provided by the Embedded Development Kit. EDK supplies libraries, board support packages, and complete operating systems, in addition to the drivers for the peripherals, to help the user develop a software platform. The following is the distribution of the software packages available for the user to include in his platform: x Xilinx Micro-Kernel (XMK) - XMK is the entity representing the collective software system formed by the following components, i Standard C Libraries (libc, libm) i Xilkernel - An embedded kernel i Standalone Board Support Package (BSP) i LibXil Net - A networking library i LibXil MFS - A Memory File System i LibXil File - A file I/O library i LibXil Drivers - Device drivers for supported peripherals x VxWorks The software platform can be defined using XPS’s Software Platform Settings dialog box. Figure 1-1 shows a snapshot of the dialog box. In this example, the user is choosing the Xilnet and Xilfile libraries, along with the Xilkernel operating system. This guide documents the Xilinx Micro-kernel, its constituent libraries and the Standalone board-support package. Documentation for the other operating systems can be found in their respective reference guides. Device drivers are documented along with the corresponding peripheral’s documentation.

EDK OS and Libraries Reference Guide www.xilinx.com 13 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 1: Introduction

Figure 1-1: Software Platform Settings in XPS

14 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 2

Xilinx Microkernel (XMK)

This chapter describes the organization of Xilinx Microkernel, its constituent component libraries and the interactions between them and the user application. The chapter contains the following sections. x “Overview” x “XMK Organization”

Overview There are three distinct software entities in XMK, with which user applications can interface - Standard C and Math libraries, LibXil libraries and Xilkernel or Standalone operating systems. The Standard C support library consists of the newlib libc, which contains the standard C functions such as stdio, stdlib and string routines. The math library is an enhancement over the newlib math library libm and provides the standard math routines. The LibXil libraries consist of, x LibXil Driver - Xilinx device drivers x LibXil Net - Xilinx networking support x LibXil File - Xilinx file I/O functions x LibXil MFS - Xilinx memory file system x LibXil Profile - Xilinx profiling support The Xilinx Standalone Board Support Package (BSP) and Xilkernel are the two operating system choices that are provided, in XMK, that can be included in the user application’s software platform. Most of the routines in the library are written in C and can be ported to any platform. The Library Generator (LibGen) configures the libraries for an embedded processor, using the attributes defined in the Microprocessor Software Specification (MSS) file.

XMK Organization The structure of XMK is outlined in Figure 2-1. As shown in the figure, the user application can interface with the XMK components in a variety of ways. The libraries are independent of each other, except for a few interactions and dependencies between each other. For example, Xilkernel internally uses the standalone BSP and LibXil File can optionally work with the LibXil MFS. The LibXil Drivers and the standalone BSP form the lowermost hardware abstraction layer. All the library and OS components of XMK rely on standard C library components. The math library, libm.a is also available for linking with the user

EDK OS and Libraries Reference Guide www.xilinx.com 15 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 2: Xilinx Microkernel (XMK)

applications. Users can mix and match the component libraries, but there may be some restrictions and implications. This will be described in the reference guides of each component.

User Application libc

stdio

stdlib

LibXil Xil Kernel LibXil Net LibXil File LibXil Mfs string Profile Other

libm

Standalone BSP LibXil Driver

Hardware X10143 Figure 2-1: XMK Structure

The Standalone Board Support Package (BSP) is a bare-bones kernel. It provides a very thin interface to the hardware, offering minimal functionality that will be required by applications. Some typical functions offered by the standalone BSP include setting up the interrupt system, exception system, configuring caches and other hardware specific functions. Certain standalone board support files such as the crt0.S, boot.S and eabi.S are required for the powerpc processor. These files are provided in the EDK. For a detailed description, refer to Chapter 4, “Standalone Board Support Package.” LibXil Driver refers to the device drivers that are included in the software platform to provide an interface to the peripherals in the system. These drivers are provided along with EDK and are configured by libgen. This book contains a chapter that briefly discusses the concept of device drivers and the way they fit in with the software platform, in EDK. Refer to the “Device Drivers Programmer Guide” chapter in the Processor IP Reference Guide for this documentation. Device Drivers are documented in further detail, with information about functionality, interface, configuration and headers file information, in the Xilinx Device Drivers Reference Guide. Xilkernel(1) is a simple embedded processor kernel, which can be customized to a great degree for a given system. Xilkernel has the key features of an embedded kernel like multi- tasking, priority-driven preemptive scheduling, inter-process communication, synchronization facilities, interrupt handling etc. It is small, modular, user customizable and can be used in different system configurations. It is different from the other libraries, (as indicated in Figure 2-1 in that, it can be in a separate executable file from the user application. The user application can dynamically link with Xilkernel through a system call interface. Applications can also statically link with Xilkernel, in a different mode, and form a single executable. Complete details are available in Chapter 5, “Xilkernel.” LibXil Net provides networking support using a simple TCP/IP stack based library, which can be used for network related projects. For complete details, refer to Chapter 6, “LibXil Net (v2.00.a).”

1. Previous EDK releases supported the library version of Xilkernel, which is now deprecated. Refer to Chapter 5, “Xilkernel” for documentation on LibXilkernel.

16 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 XMK Organization R

LibXil File provides stream based file system and device access through interfaces such as open, close, read and write. The standard newlib libc contains dummy functions for most of the operating system specific function calls such as open, close, read, write. These routines are included in the libgloss component of the standard libc library. The LibXil File module contains routines to overwrite these dummy functions. The routines interact with file systems such as Xilinx Memory File System and peripheral devices such as UART, UARTLITE and GPIO. For complete details refer to Chapter 7, “LibXil File.” LibXil MFS provides a simple memory based file system, which allows easy access to data using file based input-output. This system can be easily configured to meet project requirements by changing the source provided in the installation area. This module is discussed in detail in Chapter 9, “LibXil Memory File System (MFS).” LibXil Profile provides a mechanism to perform call-graph and histogram profiling and produces the profile data in a format that can be analyzed using GNU gprof. For details refer to Chapter 10, “LibXil Profile.” User applications will need to include appropriate headers and link with required libraries for proper compilation and inclusion of required functionality. These libraries and their corresponding include files are created in the processor’s lib and include directories, under the current project, respectively. The -I and -L options of the compiler being used should be leveraged to add these directories to the search paths. Libgen is used to tailor the compilation of each software component described above. Refer to the chapters on Libgen and Microprocessor Software Specification in the Embedded Systems Tools Reference Guide for more information.

EDK OS and Libraries Reference Guide www.xilinx.com 17 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 2: Xilinx Microkernel (XMK)

18 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 3

LibXil Standard C Libraries

This chapter describes the software libraries available for the embedded processors. The chapter contains the following sections. x “Overview” x “Standard C Library (libc.a)” x “Xilinx C Library (libxil.a)” x “Input/Output Functions” x “Memory Management Functions” x “Arithmetic Operations”

Overview The Embedded Processor Design Kit (EDK) libraries and device drivers provide standard C library functions, as well as functions to access peripherals. The EDK libraries are automatically configured by libgen for every project based upon the Microprocessor Software Specification file. These libraries and include files are saved in the current project’s lib and include directories respectively. The -I and -L options of mb-gcc should be used to add these directories to its library search paths.

Standard C Library (libc.a) The standard C library libc.a contains the standard C functions compiled for MicroBlaze or PowerPC. For a list of all the supported functions refer to the following files in XILINX_EDK/gnu/processor/platform/include where x processor = powerpc-eabi or microblaze x platform = sol, nt or lin x XILINX_EDK = Installation directory _ansi.h fastmath.h machine/ reent.h stdlib.h utime.h _syslist.h fcntl.h malloc.h regdef.h string.h utmp.h ar.h float.h math.h setjmp.h sys/ assert.h grp.h paths.h signal.h termios.h ctype.h ieeefp.h process.h stdarg.h time.h dirent.h limits.h pthread.h stddef.h unctrl.h errno.h locale.h pwd.h stdio.h unistd.h

EDK OS and Libraries Reference Guide www.xilinx.com 19 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 3: LibXil Standard C Libraries

Programs accessing standard C library functions must be compiled as follows: For MicroBlaze mb-gcc C files For PowerPC powerpc-eabi-gcc C files The libc library is included automatically. The -lm option should be specified for programs that access libm math functions. Refer to “MicroBlaze Application Binary Interface,” (ABI) in the MicroBlaze Processor Reference Guide for information on the C Runtime Library

Xilinx C Library (libxil.a) The Xilinx C library libxil.a contains the following functions for the MicroBlaze embedded processor: _exception_handler.o _interrupt_handler.o _program_clean.o _program_init.o xil_malloc.o xil_sbrk.o Default exception and interrupt handlers are provided. A memory management targeted for embedded systems is provided in the xil_malloc.o file. The libxil.a library is included automatically. Programs accessing Xilinx C library functions must be compiled as follows: mb-gcc C files

Input/Output Functions The EDK libraries contains standard C functions for I/O, such as printf and scanf. These are large and may not be suitable for embedded processors. In addition, the EDK processors (MicroBlaze and PowerPC405) library provides the following smaller I/O functions: void print (char *) This function prints a string to the peripheral designated as standard output in the MSS file. This function outputs the passed string as is and there is no interpretation of the string passed. For example, a “\n” passed is interpreted as a new line character and not as a carriage return and a new line as is the case with ANSI C printf function. void putnum (int) This function converts an integer to a hexadecimal string and prints it to the peripheral designated as standard output in the MSS file. void xil_printf (const *char ctrl1, ...) This function is similar to printf but much smaller in size (only 1KB). It does not have support for floating point numbers. xil_printf also does not support printing of long long (i.e 64 bit numbers). The prototypes for these functions are in stdio.h.

20 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Memory Management Functions R

Please refer to the “Microprocessor Software Specification (MSS)” chapter in the Embedded System Tools Guide for information on setting the standard input and standard output devices for a system.

Memory Management Functions

MicroBlaze Processor Memory management routines such as malloc, calloc and free can run the gamut of high functionality (with associated large size) to low functionality (and small size). By default, the MicroBlaze processor library only supports a simple, small malloc, and a dummy free. Hence when memory is allocated using malloc, this memory cannot be reused. In addition to the simple version, we have now extended the standalone BSP to include xil_malloc, xil_free and xil_calloc function. In the Standalone OS block, if the PARAMETER need_xil_malloc is set to TRUE, calls to malloc result in a call to xil_malloc and the same for free and calloc. These functions are a lighter version of the newlib based malloc and free, but have the same functionality. The _STACK_SIZE option to mb-gcc specifies the total memory allocated to stack and heap. The stack is used for function calls, register saves, and local variables. All calls to malloc allocate memory from heap. The stack pointer initially points to the bottom (high end) of memory, and grows toward low memory; the heap pointer starts at low memory and grows toward high memory. The size of the heap cannot be increased at runtime. The return value of malloc must always be checked to ensure that it could actually allocate the memory requested. Please note that whereas malloc checks that the memory it allocates does not overwrite the current stack pointer, updates to the stack pointer do not check if the heap is being overwritten. Increasing the _STACK_SIZE may be one way to solve unexpected program behavior. Refer to “Linker Options” in the “GNU Compiler Tools” chapter of the Embedded System Tools Guide for more information on increasing the stack size.

PowerPC 405 Processor PowerPC 405 processor supports all standard C library memory management functions such as malloc(), calloc(), free().Similar to MicroBlaze, the lighter version of malloc and free i.e xil_malloc and xil_free can be used for PowerPC when the standalone BSP package is used.

Arithmetic Operations

MicroBlaze Processor

Integer Arithmetic

Integer addition and subtraction operations are provided in hardware. By default, integer multiplication is done in software using the library function mulsi3_proc. Integer multiplication is done in hardware if the mb-gcc option -mno-xl-soft-mul is specified.

EDK OS and Libraries Reference Guide www.xilinx.com 21 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 3: LibXil Standard C Libraries

Integer divide and mod operations are done in software using the library functions divsi3_proc and modsi3_proc. MicroBlaze processor can also be customized to use a hard divider, in which case the div instruction is used in place of the divsi3_proc library routine. Double precision multiplication, division and mod functions are carried out by the library functions muldi3_proc, divdi3_proc and moddi3_proc respectively.

Floating Point Arithmetic

All floating point addition, subtraction, multiplication and division operations are also implemented using software functions in the C library.

PowerPC 405 Processor

Integer Arithmetic

Integer addition and subtraction operations are provided in hardware. Hence no specific software library is available for the PowerPC processor.

Floating Point Arithmetic

The PowerPC processor supports all floating point arithmetic implemented in the standard C library.

22 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 4

Standalone Board Support Package

The Board Support Package (BSP) is a the lowest layer of software modules used to access processor specific functions. The standalone BSP is used when an application accesses board/processor features directly and is below the operating system layer. This chapter contains the following sections. x “MicroBlaze BSP” x “PowerPC BSP”

MicroBlaze BSP When the user system contains a MicroBlaze processor and no Operating System, the Library Generator automatically builds the standalone BSP in the project library libxil.a.

Function Summary The following table contains a list of all MicroBlaze BSP functions:

Table 4-1: BSP Function Summary Functions void microblaze_enable_interrupts(void) void microblaze_disable_interrupts(void) void microblaze_register_handler(XInterruptHandler Handler, void *DataPtr) void microblaze_disable_exceptions(void) void microblaze_enable_exceptions(void) void microblaze_register_exception_handler (Xuint8 ExceptionId, XExceptionHandler Handler, void *DataPtr) void microblaze_enable_icache(void) void microblaze_disable_icache(void) void microblaze_update_icache (int tag, int instr, int lock_valid) void microblaze_init_icache_range (int cache_addr, int cache_size) void microblaze_enable_dcache(void) void microblaze_disable_dcache(void) void microblaze_update_dcache (int tag, int data, int lock_valid)

EDK OS and Libraries Reference Guide www.xilinx.com 23 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

Table 4-1: BSP Function Summary (Continued) Functions void microblaze_init_dcache_range (int cache_addr, int cache_size) microblaze_bread_datafsl(val, id) microblaze_bwrite_datafsl(val, id) microblaze_nbread_datafsl(val, id) microblaze_nbwrite_datafsl(val, id) microblaze_bread_cntlfsl(val, id) microblaze_bwrite_cntlfsl(val, id) microblaze_nbread_cntlfsl(val, id) microblaze_nbwrite_cntlfsl(val, id)

Interrupt Handling The microblaze_enable_interrupts.s and microblaze_disable_interrupts.s files contain functions to enable and disable interrupts on the MicroBlaze.

void microblaze_enable_interrupts(void) This function enables interrupts on the MicroBlaze. When the MicroBlaze starts up, interrupts are disabled. Interrupts must be explicitly turned on using this function.

void microblaze_disable_interrupts(void) This function disables interrupts on the MicroBlaze. This function may be called when entering a critical section of code where a context switch is undesirable.

void microblaze_register_handler(XInterruptHandler Handler, void *DataPtr) This function allows one to register the interrupt handler for the MicroBlaze processor. This handler will be invoked in turn, by the first level interrupt handler that is present in the BSP. The first level interrupt handler takes care of saving and restoring registers, as necessary for interrupt handling and hence the function that you register with this handler can concentrate on the other aspects of interrupt handling, without worrying about saving registers.

24 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 MicroBlaze BSP R

Exception Handling This section describes the exception handling functionality available on the MicroBlaze processor. Note: This feature and hence the corresponding interfaces are available only on the MicroBlaze v3.00.a processor. The handlers for the various exceptions can be specified in the parameter exception_vectors, in the XPS software platform settings GUI. Specify the name of the routine that you wish to handle a particular exception, in the field corresponding to the exception type.

void microblaze_disable_exceptions(void) Disable hardware exceptions from the MicroBlaze processor. This routine clears the appropriate "exceptions enable" bit in he MSR of the processor.

void microblaze_enable_exceptions(void) Enable hardware exceptions from the MicroBlaze processor. This routine sets the appropriate "exceptions enable" bit in he MSR of the processor.

void microblaze_register_exception_handler (Xuint8 ExceptionId, XExceptionHandler Handler, void *DataPtr) Register a handler for the specified exception type. Handler is the function that handles the specified exception. DataPtr is a callback data value that is passed to the exception handler at run-time. The valid exception IDs are defined in microblaze_exceptions_i.h. These are as shown in Table 4-2.

Table 4-2: Exception IDs Exception ID Value Description XEXC_ID_UNALIGNED_ACCESS 1 Unaligned access exceptions. XEXC_ID_IOPB_EXCEPTION 2 Exception due to a timeout from the IOPB bus. XEXC_ID_ILLEGAL_OPCODE 3 Exception due to an attempt to execute an illegal opcode. XEXC_ID_DOPB_EXCEPTION 4 Exception due to a timeout on the DOPB bus. XEXC_ID_DIV_BY_ZERO 5 Divide by zero exceptions from the hardware divide.

By default, the BSP provides empty handlers for all the exceptions except the unaligned exceptions. A default, fast unaligned access exception handler is provided for by the BSP. An unaligned exception can be handled by making the corresponding aligned access on or to the appropriate bytes in memory. User software is not required to be aware of the

EDK OS and Libraries Reference Guide www.xilinx.com 25 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

unaligned access at all and it is invisibly handled by the default handler. However, you should note that, software that involves a significant amount of unaligned accesses, will see its effects at run-time. This is because the software exception handler takes longer to satisfy the unaligned access request as compared to a purely aligned one. Therefore, in some cases, user software might wish to use the provision for unaligned exceptions, just to trap the exception and be aware of software causing the exception. In this case, you should specify your own exception handler for unaligned exceptions. Note: Note: Because of the way the first level handler stores volatile and temporary registers on the stack, by the time your custom unaligned access handler is invoked, critical information will be lost to the handler. Therefore, you cannot handle the unaligned access yourself easily, but rather, can just trap it (for e.g by setting a breakpoint in your handler). It is not recommended that you register your own handler and try to handle the unaligned access yourself. Similarly, your custom handlers for the other exceptions must be aware of the fact that the first level exception handler would have saved some state on the stack, before invoking your handler. The other exceptions are very useful in conjunction with an OS of some kind. For e.g. on a divide by zero, the OS might determine the process that caused the exception and the terminate it. The same applies for the other exceptions. Nested exceptions are allowed by MicroBlaze and the exception handler, in its prologue, re-enables exceptions. Thus, exceptions within exception handlers are allowed and handled.

Instruction Cache Handling The microblaze_enable_icache.s and microblaze_disable_icache.s files contain functions to enable and disable the instruction cache on MicroBlaze.

void microblaze_enable_icache(void) This functions enables the instruction cache on MicroBlaze. When MicroBlaze starts up, the instruction cache is disabled. The ICache must be explicitly turned on using this function.

void microblaze_disable_icache(void) This function disables the instruction cache on MicroBlaze.

void microblaze_update_icache (int tag, int instr, int lock_valid) This function updates the cache tag with the appropriate instr. The function disables the cache before updating the tag line. The MSR is restored back to its original value after the cache is updated.

26 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 MicroBlaze BSP R

This function can also be used to invalidate and lock the cache depending on the value of the lock_valid parameter. The effect of this parameter is summarized in Table 4-3.

Table 4-3: Effect of lock_valid Parameter Lock Valid lock_valid Effect 0 0 0 Invalidate Cache 0 1 1 Valid, but unlocked cacheline. The same cacheline can be used for more than one addresses, if required.The previous address will be swapped out of the cache and written to the memory. 1 0 2 Invalidate Cache; No effect of lock bit. 1 1 3 Valid cache and locked cacheline. The cacheline is now locked to a particular address. Other addresses cannot use this cacheline.

void microblaze_init_icache_range (int cache_addr, int cache_size) The icache can be initialized using the function microblaze_init_icache_range. This function can be used for initializing the entire icache or only a part of it. The parameter cache_addr indicate the beginning of the cache location, which is to be initialized. The cache_size represents the size from cache_addr, which needs to be initialized. For example, microblaze_init_icache_range (0x00000300, 0x100) will initialize the instruction cache region between 0x300 to 0x3ff (0x100 bytes of cache memory is cleared starting from 0x300).

Data Cache Handling The microblaze_enable_dcache.s and microblaze_disable_dcache.s files contain functions to enable and disable the data cache on MicroBlaze.

void microblaze_enable_dcache(void) This functions enables the data cache on MicroBlaze. When MicroBlaze starts up, the data cache is disabled. The Dcache must be explicitly turned on using this function.

void microblaze_disable_dcache(void) This function disables the instruction cache on MicroBlaze.

EDK OS and Libraries Reference Guide www.xilinx.com 27 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

void microblaze_update_dcache (int tag, int data, int lock_valid) This function updates the cache tag with the appropriate data. The function disables the cache before updating the tag line. The MSR is restored back to its original value after the cache is updated. This function can also be used to invalidate and lock the cache, depending on the value of the lock_valid parameter. The effect of this parameter is summarized in Table 4-3.

void microblaze_init_dcache_range (int cache_addr, int cache_size) The icache can be initialized using the function microblaze_init_dcache_range. This function can be used for initializing the entire icache or only a part of it. The parameter cache_addr indicate the beginning of the cache location, which is to be initialized. The cache_size represents the size from cache_addr, which needs to be initialized. For example, microblaze_init_dcache_range (0x00000300, 0x100) will initialize the data cache region between 0x300 to 0x3ff (0x100 bytes of cache memory is cleared starting from 0x300).

Fast Simplex Link Interface Macros The Fast Simplex Link (FSL) interfaces on MicroBlaze can be used in several ways.

microblaze_bread_datafsl(val, id) This macro performs a blocking data get function on an input FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

microblaze_bwrite_datafsl(val, id) This macro performs a blocking data put function on an output FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

microblaze_nbread_datafsl(val, id) This macro performs a non-blocking data get function on an input FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

28 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 PowerPC BSP R

microblaze_nbwrite_datafsl(val, id) This macro performs a non- blocking data put function on an output FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

microblaze_bread_cntlfsl(val, id) This macro performs a blocking control get function on an input FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

microblaze_bwrite_cntlfsl(val, id) This macro performs a blocking control put function on an output FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

microblaze_nbread_cntlfsl(val, id) This macro performs a non-blocking control get function on an input FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

microblaze_nbwrite_cntlfsl(val, id) This macro performs a non-blocking data control function on an output FSL of MicroBlaze; id is the FSL identifier and can range from 0 to 7.

PowerPC BSP When the user system contains a PowerPC, and no Operating System, the Library Generator automatically builds the Stand-Alone BSP in the project library libxil.a. The Stand-Alone BSP contains boot code, cache, file and memory management, configuration, exception handling, time and processor specific include functions.

Function Summary

Table 4-4: Function Summary void XCache_WriteCCR0(unsigned int val); void XCache_EnableDCache(unsigned int regions); void XCache_DisableDCache(void);

EDK OS and Libraries Reference Guide www.xilinx.com 29 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

Table 4-4: Function Summary (Continued) void XCache_FlushDCacheLine(unsigned int adr); void XCache_StoreDCacheLine(unsigned int adr); void XCache_EnableICache(unsigned int regions); void XCache_EnableICache(unsigned int regions); void XCache_DisableICache(void); void XCache_InvalidateICache(void); void XCache_InvalidateICacheLine(unsigned int adr); void XExc_Init(void); void XExc_RegisterHandler(Xuint8 ExceptionId, XExceptionHandler Handler, void *DataPtr); void XExc_RemoveHandler(Xuint8 ExceptionId) void XExc_mEnableExceptions (EnableMask); void XExc_mDisableExceptions (DisableMask); int read(int fd, char *buf, int nbytes); int write(int fd, char *buf, int nbytes); int isatty(int fd); char *sbrk(int nbytes); void XTime_SetTime(XTime xtime); void XTime_GetTime(XTime *xtime); void XTime_TSRClearStatusBits(unsigned long Bitmask); void XTime_PITSetInterval(unsigned long interval); void XTime_PITEnableInterrupt(void); void XTime_PITDisableInterrupt(void); void XTime_PITEnableAutoReload(void); void XTime_PITDisableAutoReload(void); void XTime_PITClearInterrupt(void); unsigned int usleep(unsigned int __useconds); unsigned int sleep(unsigned int __seconds); int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

Boot Code The boot.S, crt0.S, and eabi.S files contain a minimal set of code for initializing the processor and starting an application.

boot.S

Code in the boot.S consists of the two sections boot and boot0. The boot section contains only one instruction that is labeled with _boot. During the link process, this

30 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 PowerPC BSP R

instruction is mapped to the reset vector and the _boot label marks the application’s entry point. The boot instruction is a jump to the _boot0 label. The _boot0 label must reside within a ±23-bit address space of the _boot label. It is defined in the boot0 section. The code in the boot0 section calculates the 32-bit address of the _start label and jumps to it.

crt0.S

Code in the crt0.S file starts executing at the _start label. It initializes the .sbss and .bss sections to zero, as required by the ANSI C specification, sets up the stack, initializes some processor registers, and calls the main( ) function. The program remains in an endless loop on return from main( ).

eabi.S

When an application is compiled and linked with the -msdata=eabi option, GCC inserts a call to the __eabi label at the beginning of the main( ) function. This is the place where register R13 must be set to point to the .sdata and .sbss data sections and register R2 must be set to point to the .sdata2 read-only data section. Code in eabi.S sets these two registers to the correct values. The _SDA_BASE_ and _SDA2_BASE_ labels are generated by the linker.

Cache The xcache_l.c file and corresponding xcache_l.h include file provide access to cache and cache-related operations.

void XCache_WriteCCR0(unsigned int val); The XCache_WriteCCR0( ) function writes an integer value to the CCR0 register. Below is a sample code sequence. Before writing to this register, the instruction cache must be enabled to prevent a lockup of the processor core. After writing the CCR0, the instruction cache can be disabled, if not needed. ... XCache_EnableICache(0x80000000) /* enable instruction cache for first 128 MB memory region */ XCache_WriteCCR0(0x2700E00) /* enable 8 word pre-fetching */ XCache_DisableICache() /* disable instruction cache */ ...

void XCache_EnableDCache(unsigned int regions); The XCache_EnableDCache( ) function enables the data cache for a specific memory region. Each bit in the regions parameter represents 128 MB of memory. A value of 0x80000000 enables the data cache for the first 128 MB of memory (0 - 0x7FFFFFF). A value of 0x1 enables the data cache for the last 128 MB of memory (0xF8000000 - 0xFFFFFFFF).

EDK OS and Libraries Reference Guide www.xilinx.com 31 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

void XCache_DisableDCache(void); The XCache_DisableDCache( ) function disables the data cache for all memory regions.

void XCache_FlushDCacheLine(unsigned int adr); The XCache_FlushDCacheLine( ) function flushes and invalidates the data cache line that contains the address specified by the adr parameter. A subsequent data access to this address results in a cache miss and a cache line refill.

void XCache_StoreDCacheLine(unsigned int adr); The XCache_StoreDCacheLine( ) function stores in memory the data cache line that contains the address specified by the adr parameter. A subsequent data access to this address results in a cache hit if the address was already cached; otherwise, it results in a cache miss and cache line refill.

void XCache_EnableICache(unsigned int regions); The XCache_EnableICache( ) function enables the instruction cache for a specific memory region. Each bit in the regions parameter represents 128 MB of memory. A value of 0x80000000 enables the instruction cache for the first 128 MB of memory (0 - 0x7FFFFFF). A value of 0x1 enables the instruction cache for the last 128 MB of memory (0xF8000000 - 0xFFFFFFFF).

void XCache_DisableICache(void); The XCache_DisableICache( ) function disables the instruction cache for all memory regions.

void XCache_InvalidateICache(void); The XCache_InvalidateICache( ) function invalidates the whole instruction cache. Subsequent instructions produce cache misses and cache line refills.

32 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 PowerPC BSP R

void XCache_InvalidateICacheLine(unsigned int adr); The XCache_InvalidateICacheLine( ) function invalidates the instruction cache line that contains the address specified by the adr parameter. A subsequent instruction to this address produces a cache miss and a cache line refill.

Exception Handling This section documents the exception handling API that is provided in the Board Support Package. For an in-depth explanation on how exceptions and interrupts work on the PPC405, please refer to the chapter “Exceptions and Interrupts” in the PPC User’s Manual. The exception handling API consists of a set of the files xvectors.S, xexception_l.c, and the corresponding header file xexception_l.h.

void XExc_Init(void); This function sets up the interrupt vector table and registers a “do nothing” function for each exception. This function has no parameters and does not return a value. This function must be called before registering any exception handlers or enabling any interrupts. When using the exception handler API, this function should be called at the beginning of your main( ) routine. IMPORTANT: If you are not using the default linker script, you need to reserve memory space for storing the vector table in your linker script. The memory space must begin on a 64k boundary. The linker script entry should look like this example: .vectors : { . = ALIGN(64k); *(.vectors) } For further information on linker scripts, please refer to the Linker documentation.

EDK OS and Libraries Reference Guide www.xilinx.com 33 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

void XExc_RegisterHandler(Xuint8 ExceptionId, XExceptionHandler Handler, void *DataPtr); This function is used to register an exception handler for a specific exception. It does not return a value. Please refer to Table 4-5 for a list of parameters.

Table 4-5: Exception Handler Parameters Parameter Name Parameter Type Description ExceptionId Xuint8 Exception to which this handler should be registered. The type and the values are defined in the header file xexception_l.h. Please refer to Table 4-6 for possible values. Handler XExceptionHandler Pointer to the exception handling function. DataPtr void * User value to be passed when the handling function is called.

Table 4-6: Registered Exception Types and Values Exception Type Value XEXC_ID_JUMP_TO_ZERO 0 XEXC_ID_MACHINE_CHECK 1 XEXC_ID_CRITICAL_INT 2 XEXC_ID_DATA_STORAGE_INT 3 XEXC_ID_INSTUCTION_STORAGE_INT 4 XEXC_ID_NON_CRITICAL_INT 5 XEXC_ID_ALIGNMENT_INT 6 XEXC_ID_PROGRAM_INT 7 XEXC_ID_FPU_UNAVAILABLE_INT 8 XEXC_ID_SYSTEM_CALL 9 XEXC_ID_APU_AVAILABLE 10 XEXC_ID_PIT_INT 11 XEXC_ID_FIT_INT 12 XEXC_ID_WATCHDOG_TIMER_INT 13 XEXC_ID_DATA_TLB_MISS_INT 14 XEXC_ID_INSTRUCTION_TLB_MISS_INT 15 XEXC_ID_DEBUG_INT 16

34 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 PowerPC BSP R

The function provided as the Handler parameter must have the following function prototype: typedef void (*XExceptionHandler)(void * DataPtr); This prototype is declared in the xexception_l.h header file. When this exception handler function is called, the parameter DataPtr will contain the same value as you provided when you registered the handler.

void XExc_RemoveHandler(Xuint8 ExceptionId) This function is used to deregister a handler function for a given exception. For possible values of parameter ExceptionId, please refer to Table 4-6.

void XExc_mEnableExceptions (EnableMask); This macro is used to enable exceptions. It must be called after initializing the vector table with function exception_Init and registering exception handlers with function XExc_RegisterHandler. The parameter EnableMask is a bitmask for exceptions to be enabled. The EnableMask parameter may have the values XEXC_CRITICAL, XEXC_NON_CRITICAL or XEXC_ALL.

void XExc_mDisableExceptions (DisableMask); This macro is called to disable exceptions. The parameter DisableMask is a bitmask for exceptions to be disabled.The DisableMask parameter may have the values XEXC_CRITICAL, XEXC_NON_CRITICAL or XEXC_ALL.

Files File support is limited to the stdin and stdout streams. In such an environment, the following functions do not make much sense: x open( ) (in open.c) x close( ) (in close.c) x fstat( ) (in fstat.c) x unlink( ) (in unlink.c) x lseek( ) (in lseek.c) These files are included for completeness and because they are referenced by the C library.

EDK OS and Libraries Reference Guide www.xilinx.com 35 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

int read(int fd, char *buf, int nbytes); The read( ) function in read.c reads nbytes bytes from the standard input by calling inbyte( ). It blocks until all characters are available, or the end of line character is read. Read( ) returns the number of characters read. The parameter fd is ignored.

int write(int fd, char *buf, int nbytes); The write( ) function in write.c writes nbytes bytes to the standard output by calling outbyte( ). It blocks until all characters have been written. Write( ) returns the number of characters written. The parameter fd is ignored.

int isatty(int fd); The isatty( ) function in isatty.c reports if a file is connected to a tty. This function always returns 1, since only the stdin and stdout streams are supported.

Memory Management

char *sbrk(int nbytes); The sbrk( ) function in the sbrk.c file allocates nbytes of heap and returns a pointer to that piece of memory. This function is called from the memory allocation functions of the C library.

Process The functions getpid() in getpid.c and kill() in kill.c are included for completeness and because they are referenced by the C library.

Processor-Specific Include Files The xreg405.h include file contains the register numbers and the register bits for the PPC 405 processor. The xpseudo-asm.h include file contains the definitions for the most often used inline assembler instructions. These inline assembler instructions can be used from drivers and user applications written in C.

36 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 PowerPC BSP R

Time The xtime_l.c file and corresponding xtime_l.h include file provide access to the 64- bit time base counter inside the PowerPC core. The counter increases by one at every processor cycle. The sleep.c file and corresponding sleep.h include file implement functions for tired programs. All sleep functions are implemented as busy loops.

typedef unsigned long long XTime;

The XTime type in xtime_l.h represents the Time Base register. This struct consists of the Time Base Low (TBL) and Time Base High (TBH) registers, each of which is a 32-bit wide register. The definition of XTime is as follows: typedef unsigned long long XTime;

void XTime_SetTime(XTime xtime); The XTime_SetTime( ) function in xtime_l.c sets the time base register to the value in xtime.

void XTime_GetTime(XTime *xtime); The XTime_GetTime( ) function in xtime_l.c writes the current value of the time base register to variable xtime.

void XTime_TSRClearStatusBits(unsigned long Bitmask); The XTime_TSRClearStatusBits() function in xtime_l.c is used to clear bits in the Timer Status Register (TSR). The parameter Bitmask designates the bits to be cleared. A one in any position of the Bitmask parameter clears the corresponding bit in the TSR. This function does not return a value. The header file xreg405.h defines the following values for the Bitmask parameter:

Table 4-7: Bitmask Parameter Values Name Value Description XREG_TSR_WDT_ENABLE_NEXT_WATCHDOG 0x80000000 Clearing this bit disables the watchdog timer event. XREG_TSR_WDT_INTERRUPT_STATUS 0x40000000 Clears the Watchdog Timer Interrupt Status bit. This bit is set after a watchdog interrupt occurred, or could have occurred had it been enabled.

EDK OS and Libraries Reference Guide www.xilinx.com 37 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

Table 4-7: Bitmask Parameter Values Name Value Description XREG_TSR_WDT_RESET_STATUS_11 0x30000000 Clears the Watchdog Timer Reset Status bits. These bits Specify the kind of reset that occurred as a result of a watchdog timer event. XREG_TSR_PIT_INTERRUPT_STATUS 0x08000000 Clears the Programmable Interval Timer Status bit. This bit is set after a PIT interrupt has occurred. XREG_TSR_FIT_INTERRUPT_STATUS 0x04000000 Clears the Fixed Interval Timer Status bit. This bit is set after a FIT interrupt has occurred. XREG_TSR_CLEAR_ALL 0xFFFFFFFF Clears all bits in the TSR. After a Reset, the content of the TSR is not specified. Use this Bitmask to clear all bits in the TSR.

Example: XTime_TSRClearStatusBits(TSR_CLEAR_ALL);

void XTime_PITSetInterval(unsigned long interval); The XTime_PITSetInterval( ) function in xtime_l.c is used to load a new value into the Programmable-Interval Timer Register. This register is a 32-bit decrementing counter clocked at the same frequency as the time-base register. Depending on the AutoReload setting the PIT is automatically reloaded with the last written value or has to be reloaded manually. This function does not return a value.

Example: XTime_PITSetInterval(0x00ffffff);

void XTime_PITEnableInterrupt(void); The XTime_PITEnableInterrupt() function in xtime_l.c enables the generation of PIT interrupts. An interrupt occurs when the PIT register contains a value of 1, and is then decremented. This function does not return a value. XExc_Init() must be called, the PIT interrupt handler must be registered, and exceptions must be enabled before calling this function.

Example: XTime_PITEnableInterrupt();

38 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 PowerPC BSP R

void XTime_PITDisableInterrupt(void); The XTime_PITDisableInterrupt() function in xtime_l.c disables the generation of PIT interrupts. It does not return a value.

Example: XTime_PITDisableInterrupt();

void XTime_PITEnableAutoReload(void); The XTime_PITEnableAutoReload( ) function in xtime_l.c enables the auto-reload function of the PIT Register. When auto-reload is enabled the PIT Register is automatically reloaded with the last value loaded by calling the XTime_PITSetInterval function when the PIT Register contains a value of 1 and is decremented. When auto- reload is enabled, the PIT Register never contains a value of 0. This function does not return a value.

Example: XTime_PITEnableAutoReload();

void XTime_PITDisableAutoReload(void); The XTime_PITDisableAutoReload() function in xtime_l.c disables the auto-reload feature of the PIT Register. When auto-reload is disabled the PIT decrements from 1 to 0. If it contains a value of 0 it stops decrementing until it is loaded with a non-zero value. This function does not return a value.

Example: XTime_PITDisableAutoReload();

void XTime_PITClearInterrupt(void); The XTime_PITClearInterrupt() function in xtime_l.c is used to clear PIT- Interrupt-Status bit in the Timer-Status Register. This bit specifies whether a PIT interrupt occurred. You must call this function in your interrupt-handler to clear the Status bit, otherwise another PIT interrupt will occur immediately after exiting the interrupt – handler function. This function does not return a value. Calling this function is equivalent to calling XTime_TSRClearStatusBits(XREG_TSR_PIT_INTERRUPT_STATUS.

Example: XTime_PITClearInterrupt();

EDK OS and Libraries Reference Guide www.xilinx.com 39 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 4: Standalone Board Support Package

unsigned int usleep(unsigned int __useconds); The usleep() function in sleep.c delays the execution of a program by __useconds microseconds. It always returns zero. This function requires that the processor frequency (in Hz) is defined. The default value of this variable is 400MHz. This value can be overwritten in the MSS file as follows: BEGIN PROCESSOR PARAMETER HW_INSTANCE = PPC405_i PARAMETER DRIVER_NAME = cpu_ppc405 PARAMETER DRIVER_VER = 1.00.a PARAMETER CORE_CLOCK_FREQ_HZ = 20000000 END The file xparameters.h can also be modified with the correct value, as follows: #define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 20000000

unsigned int sleep(unsigned int __seconds); The sleep() function in sleep.c delays the execution of a program by __seconds seconds. It always returns zero.This function requires that the processor frequency (in Hz) is defined. The default value of this variable is 400MHz. This value can be overwritten in the MSS file as follows: BEGIN PROCESSOR PARAMETER HW_INSTANCE = PPC405_i PARAMETER DRIVER_NAME = cpu_ppc405 PARAMETER DRIVER_VER = 1.00.a PARAMETER CORE_CLOCK_FREQ_HZ = 20000000 END The file xparameters.h can also be modified with the correct value, as follows: #define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 20000000

int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); The nanosleep() function in sleep.c is currently not implemented. It is a placeholder for linking applications against the C library. It always returns zero.

40 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 5

Xilkernel

This chapter describes Xilkernel, a kernel for the Xilinx embedded processors. The chapter contains the following sections. x “Overview” x “Why Use a Kernel?” x “Key Features” x “Xilkernel Organization” x “Building Xilkernel Applications” x “Xilkernel Process Model” x “Xilkernel Scheduling Model” x “POSIX Interface” x “Function Summary” x “Xilkernel API” x “Interrupt Handling” x “Other Interfaces” x “Hardware Requirements and BSP” x “System Initialization” x “Kernel Customization” x “Debugging Xilkernel” x “Memory Footprint” x “Xilkernel File Organization” x “Modifying Xilkernel” x “Advanced Features” x “User Guide”

Overview Xilkernel is a small, robust, and modular kernel. It is highly integrated with the Platform Studio framework and is a free software library that you get with EDK. It allows a very high degree of customization, letting users tailor the kernel to an optimal level both in terms of size and functionality. It supports the core features required in an embedded, real- time kernel, with a POSIX API. Xilkernel works on both the MicroBlaze and PowerPC405 processors. Xilkernel IPC services can be used to implement higher level services (such as networking, video, and audio) and subsequently run applications using these services.

EDK OS and Libraries Reference Guide www.xilinx.com 41 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

The Xilkernel user guide is an excellent resource for quickly getting started with Xilkernel and includes a walk through of complete kernel configuration and deployment scenario for both Microblaze and PPC405 processors. It is strongly recommended that you use the user guide to see the kernel in action. Note: This chapter applies to Xilkernel v3.00.a. Xilkernel v2.00.a has been deprecated. Refer to “Xilkernel v2.00.a Reference Guide” for complete documentation on that version of the kernel.

Why Use a Kernel? x Embedded control loop like applications are very hard to develop, when the number of control tasks involved is large. The responsiveness and the capability of such an application decreases dramatically when the complexity is increased x Breaking down tasks as individual applications and implementing them on an OS is much more intuitive, especially as the application’s complexity increases. x Many common and legacy applications rely on OS services such as file systems, time management etc. Xilkernel is a thin library that provides these essential services. x Porting or using common/open source libraries (such as graphics or network protocols) require some form of kernel support. These are just a few deciding factors that might influence your use of a kernel in your next project.

Key Features Xilkernel includes the following key features: x A POSIX API targeting embedded kernels. x Core kernel features such as: i POSIX threads with round-robin or strict priority scheduling i POSIX synchronization services - semaphores and mutex locks i POSIX IPC services - message queues and shared memory i Dynamic buffer pool memory allocation i Software timers i User level interrupt handling API x Highly robust kernel, with all system calls protected by parameter validity checks and proper return of POSIX error codes. x Highly scalable kernel that can be accommodated into a given system through the inclusion or exclusion of functionality as required. x Complete kernel configuration, deployment within minutes from inside of platform studio x Statically creating threads that startup with the kernel. x System call interface to the kernel. x Support for creating processes out of separate executable ELF files.

42 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel Organization R

Xilkernel Organization The kernel is highly modular in design. You can select and customize the kernel modules that are needed for the application at hand. Customizing the kernel is discussed in detail in the “Kernel Customization” section(1). Figure 5-1 shows the various modules of Xilkernel.

Xilkernel Modules

User Application

User level interrupt handling

Xilkernel

Interrupt and Exception System Call Handler Scheduler Handler

Software Thread Semaphores Timers Management

Message Shared Dynamic Buffer Queue Memory Management

X10226

Figure 5-1: Xilernel Modules

Building Xilkernel Applications This section describes how to compile your applications on Xilkernel. Xilkernel is organized in the form of a library of kernel functions. This leads to a simple model of kernel linkage. To build Xilkernel, you must include Xilkernel in your software platform, configure it appropriately, and run LibGen to generate the Xilkernel library. Your application sources can be edited/developed separately, or as a software application project from inside of XPS. Once you are done developing your application, to build the final kernel image, you must link with the Xilkernel library, thus pulling in all the kernel functionality. The Xilkernel library is generated as libxilkernel.a. Figure 5-2 shows this development flow. Internally, Xilkernel also supports the much more powerful, traditional OS like method of linkage - separate executables. Conventional operating systems have the kernel image as a separate file and each application that executes on the kernel as a separate file. However, we recommend that you use the simpler, more elegant library linkage mode. This mode is fully supported within Platform Studio and will provide maximum ease of use. It is also the best mode for debugging, downloading and bootloading. The separate executable mode is required only by those who have really advanced requirements in the form of separate executables. The separate executable mode and its caveats are documented in the “Advanced Features” section.

1. Some of these features might not be fully supported in a given release of Xilkernel

EDK OS and Libraries Reference Guide www.xilinx.com 43 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Here are the steps you must follow for the kernel linkage mode of application development., x Application source C files should include the file xmk.h as the first file among other includes. For example, #include “xmk.h” Defining this flag makes available certain definitions and declarations from the GNU include files that are required by Xilkernel and applications. x Your application software project should link with the library libxilkernel.a. You can do this by including “xilkernel” in the list of libraries to link with. This will translate to appending a -lxilkernel on your compile line. This library contains the actual kernel functions. Your application links with this and forms the final kernel + application image. x Xilkernel is responsible for all first level interrupt and exception handling on both the Microblaze and PowerPC processors. Therefore, you should not directly attempt to use any of the methods of handling interrupts documented for standalone programs. Instead refer to the section on interrupt handling for how to handle user level interrupts and exceptions. x You can control the memory map of the kernel by using the linker script feature of the final software application project that links with the kernel. Automatic linker script generation will help you here. x Your application must provide a main() which is the starting point of execution for your kernel image. Inside your main(), you can do any initialization and setup that you need to do. The kernel remains unstarted and dormant. At the point where your application setup is complete and you want the kernel to start, you must invoke, xilkernel_main() which starts off the kernel, enables interrupts and transfers control to your application processes, as configured. Note: Your linker script must be aware of the kernel’s requirements. For e.g on PPC405 systems, there is a .vectors section that contains all first level exception handling code. Your final linker script must make sure that this section receives proper memory assignment. Please refer to the Xilkernel user guide and the accompanying design examples for specific illustrations of the above concepts.

44 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel Process Model R

XPS

Include and Generate configure libraries libxilkernel.a Xilkernel in with libgen SW platform link

Include in SW Application Executable project set Build Project Kernel Image compile parameter Application Sources

X10228

Figure 5-2: Building Applications for Xilkernel

Xilkernel Process Model Xilkernel’s units of execution are called process contexts. Scheduling is done at the process context level. There is no concept of thread groups combining to form, what is conventionally called a process. Instead, all the threads are peers and compete equally for resources. The POSIX threads API is the primary user visible interface to using these process contexts. There are a few other useful additional interfaces provided, that are not a part of POSIX. The interfaces allow creating, destroying and manipulating created application threads. The actual interfaces are described in detail in the “Xilkernel API” section. Threads are manipulated with thread identifiers. The underlying process context is identified with a process identifier pid_t.

Xilkernel Scheduling Model Xilkernel supports either of priority-driven preemptive scheduling (SCHED_PRIO) or round-robin scheduling (SCHED_RR). This is a global scheduling policy and cannot be changed on a per-thread basis. This must be configured statically at kernel generation time. In SCHED_RR, there is a single ready queue and each process context executes for a configured time slice before yielding execution to the next process context in the queue. In SCHED_PRIO there are as many ready queues as there are priority levels. Priority 0 is the highest priority in the system and higher values mean lower priority. As shown in Figure 5-3, the process that is at the head of the highest priority ready queue is always scheduled to execute next. Within the same priority level, scheduling is round robin and time-sliced. If a ready queue level is empty, it is skipped and the next ready queue level examined for schedulable processes. Blocked processes are off their ready queues and in their appropriate wait queues. The number of priority levels can be configured for SCHED_PRIO. For both the scheduling models, the length of the ready queue can also be configured. If there are wait queues inside the kernel (in semaphores, message queues

EDK OS and Libraries Reference Guide www.xilinx.com 45 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

etc.), they are configured as priority queues if scheduling mode is SCHED_PRIO. Otherwise, they are configured as simple FIFO queues.

Active 0 A

1 B C D 2 (Blocked) Priority

13 E

14 F G 15 (Blocked)

X10132

Figure 5-3: Priority Driven Scheduling

Each process context is in any of the following six states: x PROC_NEW - A newly created process x PROC_READY - A process ready to execute x PROC_RUN - A process that is running x PROC_WAIT - A process that is blocked on a resource x PROC_DELAY - A process that is waiting for a timeout x PROC_TIMED_WAIT - A process that is blocked on a resource and has an associated timeout When a process terminates it enters a dead state called PROC_DEAD. The process context state diagram is shown in Figure 5-4.

46 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 POSIX Interface R

PROC_NEW ACTIVATED

SCHEDULED OUT TIMEOUT PROC_RUN SCHEDULED IN BLOCKED BLOCKED BLOCKED UNBLOCKED UNBLOCKED/TIMEOUT

PROC_TIMED PROC_READY PROC_WAIT PROC_DELAY EXIT _WAIT

killed

killed killed killed

PROC_DEAD

X10227

Figure 5-4: Process Context States

POSIX Interface As described earlier, Xilkernel provides a POSIX interface to the kernel. However, not all the concepts and interfaces defined by POSIX are available. Instead, a carefully chosen subset, covering the most useful interfaces and concepts have been implemented. Xilkernel programs can run almost equivalently on your desktop OS, like Linux or SunOS. This makes for easy application development, portability and legacy software support. The programming model will appeal to those who have worked on equivalent POSIX interfaces on traditional operating systems. For those interfaces that have been provided, POSIX is rigorously adhered to in almost all cases. For cases that do differ, the differences are clearly specified. Refer to the “Xilkernel API” section for the actual interfaces and their description.

EDK OS and Libraries Reference Guide www.xilinx.com 47 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Function Summary Table 5-1 provides a Xilkernel function summary with links to a detailed description of each.

Table 5-1: Xilkernel Function Summary int pthread_create (pthread_t thread, pthread_attr_t* attr, void* (*start_func)(void*), void* param) void pthread_exit (void *value_ptr) int pthread_join (pthread_t thread, void **value_ptr) pthread_t pthread_self (void) int pthread_detach (pthread_t target) int pthread_equal (pthread_t t1, pthread_t t2) int pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param). int pthread_setschedparam (pthread_t thread, int policy, const struct sched_param *param). int pthread_attr_init (pthread_attr_t* attr) int pthread_attr_destroy (pthread_attr_t* attr) int pthread_attr_setdetachstate (pthread_attr_t* attr, int dstate) int pthread_attr_getdetachstate (pthread_attr_t* attr, int *dstate) int pthread_attr_setschedparam (pthread_attr_t* attr, struct sched_param *schedpar) int pthread_attr_getschedparam (pthread_attr_t* attr, struct sched_param* schedpar). int pthread_attr_setstack (const pthread_attr_t *attr, void *stackaddr, size_t stacksize). int pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, size_t *stacksize). pid_t get_currentPID (void) int kill (pid_t pid) int process_status (pid_t pid, p_stat *ps) int yield (void) int sem_init (sem_t *sem, int pshared, unsigned value) int sem_destroy (sem_t* sem) int sem_getvalue (sem_t* sem, int* value) int sem_wait (sem_t* sem) int sem_trywait (sem_t* sem)

48 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Function Summary R

Table 5-1: Xilkernel Function Summary (Continued) int sem_timedwait (sem_t* sem, unsigned ms) int sem_post (sem_t* sem) sem_t* sem_open (const char* name, int oflag, ...) int sem_close (sem_t* sem) int sem_unlink (const char* name) int msgget(key_t key, int msgflg) int msgctl (int msqid, int cmd, struct msqid_ds* buf) int msgsnd (int msqid, const void *msgp, size_t nbytes, int msgflg) ssize_t msgrcv (int msqid, void *msgp, size_t nbytes, long msgtyp, int msgflg) int shmget (key_t key, size_t size, int shmflg) int shmctl (int shmid, int cmd, struct shmid_ds *buf) void* shmat (int shmid, const void *shmaddr, int flag) int shm_dt (void *shmaddr) int pthread_mutex_init pthread_mutex_t* mutex, const pthread_mutexattr_t* attr) int pthread_mutex_destroy (pthread_mutex_t* mutex) int pthread_mutex_lock (pthread_mutex_t* mutex) int pthread_mutex_trylock (pthread_mutex_t* mutex) int pthread_mutex_unlock (pthread_mutex_t* mutex) int pthread_mutexattr_init (pthread_mutexattr_t* attr) int pthread_mutexattr_destroy (pthread_mutexattr_t* attr) int pthread_mutexattr_settype (pthread_mutexattr_t* attr, int type) int pthread_mutexattr_gettype (pthread_mutexattr_t* attr, int * type) int bufcreate (membuf_t *mbuf, void *memptr, int nblks, size_t blksiz) int bufdestroy (membuf_t mbuf). void* bufmalloc (membuf_t mbuf, size_t siz) void buffree (membuf_t mbuf, void* mem). unsigned int xget_clock_ticks (). time_t time (time_t *timer) unsigned sleep (unsigned int ms ) unsigned int register_int_handler (int_id_t id, void (*handler)(void*), void *callback) void unregister_int_handler (int_id_t id) void enable_interrupt (int_id_t id)

EDK OS and Libraries Reference Guide www.xilinx.com 49 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Table 5-1: Xilkernel Function Summary (Continued) void disable_interrupt (int_id_t id) void acknowledge_interrupt (int_id_t id) int elf_process_create (void* start_addr, int prio) int elf_process_exit (void)

Xilkernel API

Thread Management Xilkernel supports the basic POSIX threads API. Thread creation and manipulation is done in the exact same way as defined in POSIX. Threads are identified by a unique thread identifier. The thread identifier is of type pthread_t. This thread identifier is to used to uniquely identify a thread for an operation. Threads created in the system have a kernel wrapper to which they return control to when they terminate. Therefore a specific exit function is not required at the end of the thread’s code. Thread stack is allocated automatically on behalf of the thread from a pool of BSS memory that is statically allocated depending on the maximum number of threads in the system. The user can also assign a custom piece of memory as the stack, for each thread that they create dynamically. The entire thread module is optional and can be configured in or out as a part of the software specification. See the “Configuring Thread Management” section for more details on customizing this module. The thread management interface is summarized below:

int pthread_create (pthread_t thread, pthread_attr_t* attr, void* (*start_func)(void*), void* param)

Parameters thread is the location to store the created thread’s identifier. attr is the pointer to thread creation attributes structure. start_func is the start address of the function from which the thread needs to execute param is the pointer argument to the thread function Returns Returns 0 and thread identifier of the created thread in *thread, on success. Returns -1 if thread refers to an invalid location. Returns EINVAL if attr refers to invalid attributes. Returns EAGAIN if resources unavailable to create the thread.

50 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The pthread_create() function creates a new thread, with attributes specified by attr, within a process. If attr is NULL, the default attributes are used. If the attributes specified by attr are modified later, the thread’s attributes will not be affected. Upon successful completion, pthread_create() stores the ID of the created thread in the location referenced by thread. The thread is created executing start_routine with arg as its sole argument. If the start_routine returns, the effect is as if there was an implicit call to pthread_exit() using the return value of start_routine as the exit status. This is explained in the pthread_exit description. You can control various attributes of a thread during its creation. See the pthread_attr routines for a description of the kinds of thread creation attributes that you can control. Includes pthread.h

void pthread_exit (void *value_ptr)

Parameters value_ptr is a pointer to the return value of the thread. Returns None Description The pthread_exit() function will terminate the calling thread and make the value value_ptr available to any successful join with the terminating thread. Thread termination releases process context resources, including, but not limited to, memory and attributes. An implicit call to pthread_exit() is made when a thread returns from the start routine that was used to create it. The function’s return value serves as the thread’s exit status. Therefore no explicit pthread_exit() is required at the end of a thread. Includes pthread.h

int pthread_join (pthread_t thread, void **value_ptr)

Parameters value_ptr is a pointer to the return value of the thread. Returns 0 on success Returns ESRCH if the target thread is not in a joinable state or is an invalid thread. Returns EINVAL if the target thread already has someone waiting to join with it.

EDK OS and Libraries Reference Guide www.xilinx.com 51 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated. On return from a successful pthread_join() call with a non-NULL value_ptr argument, the value passed to pthread_exit() by the terminating thread is made available in the location referenced by value_ptr. When a pthread_join() returns successfully, the target thread has been terminated. The results of multiple simultaneous calls to pthread_join() specifying the same target thread are that only one thread succeeds and the others fail with EINVAL. Note: No deadlock detection is provided. Includes pthread.h

pthread_t pthread_self (void)

Parameters None Returns On success, returns thread identifier of current thread. Error behavior not defined. Description The pthread_self() function returns the thread ID of the calling thread. Includes pthread.h

int pthread_detach (pthread_t target)

Parameters target is the target thread to detach. Returns Returns 0 on success. Returns ESRCH if target thread cannot be found. Description The pthread_detach() function indicates to the implementation that storage for the thread thread can be reclaimed when that thread terminates. If thread has not terminated, pthread_detach() will not cause it to terminate. The effect of multiple pthread_detach() calls on the same target thread is unspecified. Includes pthread.h

52 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

int pthread_equal (pthread_t t1, pthread_t t2)

Parameters t1 and t2 are the two thread identifiers to compare. Returns Returns 1 if t1 and t2 refer to threads that are equal. Returns 0 otherwise. Description The pthread_equal() function returns a non-zero value if t1 and t2 are equal; otherwise, zero is returned.If either t1 or t2 are not valid thread IDs, zero is returned. Includes pthread.h

int pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param).

Parameters thread is the identifier of the thread to perform the operation on. policy is a pointer to the location where the global scheduling policy is stored in. param is a pointer to the scheduling parameters structure. Returns Returns 0 on success. Returns ESRCH if the value specified by thread does not refer to an existing thread. Returns EINVAL if param or policy refer to invalid memory. Description The pthread_getschedparam() function shall get the scheduling policy and parameters of an individual thread. For SCHED_RR there are no scheduling parameters. Hence, this routine is not defined for SCHED_RR. For SCHED_PRIO, the only required member of the sched_param structure is the priority sched_priority. The priority value returned from pthread_getschedparam() shall be the value specified by the most recent pthread_setschedparam() or pthread_create() call affecting the target thread. It shall not reflect any temporary adjustments to its priority as a result of any priority inheritance or ceiling functions. Note: This routine is defined only if scheduling type is SCHED_PRIO Includes pthread.h

EDK OS and Libraries Reference Guide www.xilinx.com 53 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

int pthread_setschedparam (pthread_t thread, int policy, const struct sched_param *param).

Parameters thread is the identifier of the thread to perform the operation on. policy is ignored. param is a pointer to the scheduling parameters structure. Returns Returns 0 on success. Returns ESRCH if thread does not refer to a valid thread. Returns EINVAL if the scheduling parameters are invalid. Description The pthread_setschedparam() function shall set the scheduling policy and parameters of individual threads to be retrieved. For SCHED_RR there are no scheduling parameters. Hence, this routine is not defined for SCHED_RR. For SCHED_PRIO, the only required member of the sched_param structure is the priority sched_priority. The priority value should be a valid value as configured in the scheduling parameters of the kernel. The policy parameter is ignored. Note: This routine is defined only if scheduling type is SCHED_PRIO. Includes pthread.h

int pthread_attr_init (pthread_attr_t* attr)

Parameters attr is a pointer to the attribute structure to be initialized. Returns Returns 0 on success, 1 on failure. Returns EINVAL on invalid attr parameter. Description The pthread_attr_init() function initializes a thread attributes object attr with the default value for all of the individual attributes used by a given implementation. The contents of pthread_attr_t are defined in the header. Note: This does not make a call into the kernel. Includes pthread.h

int pthread_attr_destroy (pthread_attr_t* attr)

Parameters attr is a pointer to the thread attributes that have to be destroyed. Returns Returns 0 on success. Returns EINVAL on errors.

54 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The pthread_attr_destroy() function destroys a thread attributes object. The implementation causes pthread_attr_destroy() to set attr to an implementation- defined invalid value. A destroyed attr attributes object can be re- initialized using pthread_attr_init(); the results of otherwise referencing the object after it has been destroyed are undefined. Note: This does not make a call into the kernel. Includes pthread.h

int pthread_attr_setdetachstate (pthread_attr_t* attr, int dstate)

Parameters attr is the attribute structure on which the operation is to be performed. dstate is the detachstate required. Returns Returns 0 on success. Returns EINVAL on invalid parameters. Description The detachstate attribute controls whether the thread is created in a detached state. If the thread is created detached, then when the thread exits, the thread’s resources are detached without requiring a pthread_join() or a call pthread_detach().The application can set detachstate to either PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE. Note: This does not make a call into the kernel. Includes pthread.h

int pthread_attr_getdetachstate (pthread_attr_t* attr, int *dstate)

Parameters attr is the attribute structure on which the operation is to be performed. dstate is the location to store the detachstate in. Returns Returns 0 on success. Returns EINVAL on invalid parameters.

EDK OS and Libraries Reference Guide www.xilinx.com 55 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description The implementation stores either PTHREAD_CREATE_DETACHED or PTHREAD_CREATE_JOINABLE in dstate, if the value of detachstate was valid in attr. Note: This does not make a call into the kernel. Includes pthread.h

int pthread_attr_setschedparam (pthread_attr_t* attr, struct sched_param *schedpar)

Parameters attr is the attribute structure on which the operation is to be performed. schedpar is the location of the structure that contains the scheduling parameters. Returns Returns 0 on success. Returns EINVAL on invalid parameters. Returns ENOTSUP for invalid scheduling parameters. Description The pthread_attr_setschedparam() functions sets the scheduling parameter attributes in the attr argument. The contents of the sched_param structure are defined in the header. Note: This does not make a call into the kernel. Includes pthread.h

int pthread_attr_getschedparam (pthread_attr_t* attr, struct sched_param* schedpar).

Parameters attr is the attribute structure on which the operation is to be performed. schedpar is the location to store the sched_param structure in. Returns Returns 0 on success. Returns EINVAL on invalid parameters. Description The pthread_attr_getschedparam() gets the scheduling parameter attributes in the attr argument. The contents of the param structure are defined in the header. Note: This does not make a call into the kernel. Includes pthread.h

56 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

int pthread_attr_setstack (const pthread_attr_t *attr, void *stackaddr, size_t stacksize).

Parameters attr is the attributes structure to perform the operation on. stackaddr is base address of the stack memory. stacksize is the size of the memory block in bytes. Returns 0 on success. EINVAL if the attr param is invalid or if stackaddr is not aligned appropriately. Description The pthread_attr_setstack() function shall set the thread creation stack attributes stackaddr and stacksize in the attr object. The stack attributes specify the area of storage to be used for the created thread’s stack. The base (lowest addressable byte) of the storage shall be stackaddr, and the size of the storage shall be stacksize bytes. The stackaddr shall be aligned appropriately according to the processor EABI, to be used as a stack; for example, pthread_attr_setstack() may fail with EINVAL if (stackaddr & 0x3) is not 0. For PPC405 processors, the alignment required is 8 bytes. For Microblaze, the alignment required is 4 bytes. Includes pthread.h

int pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, size_t *stacksize).

Parameters attr is the attributes structure to perform the operation on. stackaddr is the location to store the base address of the stack memory. stacksize is the location to store the size of the memory block in bytes. Returns Returns 0 on success. Returns EINVAL on invalid attr. Description The pthread_attr_getstack() function shall retrieve the thread creation attributes related to stack of the specified attributes structure and store it in stackaddr and stacksize. Includes pthread.h

EDK OS and Libraries Reference Guide www.xilinx.com 57 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

pid_t get_currentPID (void)

Parameters None Returns Returns the process identifier associated with the current thread or elf process. Description Gets the underlying process identifier of the process context that is executing currently. The process identifier is needed to perform certain operations like kill() on both processes and threads. Includes sys/process.h

int kill (pid_t pid)

Parameters pid is the PID of process to kill Returns Returns 0 on success. Returns -1 on failure. Description Removes the process context specified by pid from the system. If pid refers to the current executing process context, then it is equivalent to the current process context terminating. A kill can be invoked on processes that are suspended on wait queues or on a timeout. No indication is given to other processes that are dependant on this process context. Note: This function is defined only if CONFIG_KILL is true. This can be configured in with the enhanced features category of the kernel. Includes sys/process.h

int process_status (pid_t pid, p_stat *ps)

Parameters pid is the PID of process. ps is the buffer where the process status is returned. Returns Returns process status in ps on success. Returns NULL in ps on failure. Description Get the status of the process or thread, whose pid is pid. The status is returned in structure p_stat which has the following fields: i pid is the process ID. i state is the current scheduling state of the process. The contents of p_stat are defined in the header. Includes sys/process.h

58 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

int yield (void)

Parameters None Returns None Description Yields the processor to the next process context that is ready to execute. The current process is put back in the appropriate ready queue. Note: This function is optional and included only if CONFIG_YIELD is defined. This can be configured in with the enhanced features category of the kernel. Includes sys/process.h

Semaphores Xilkernel supports kernel allocated POSIX semaphores that can be used for synchronization. POSIX semaphores are counting semaphores that also count below zero (a negative value indicates the number of processes blocked on the semaphore). Xilkernel also supports a few interfaces for working with named semaphores. The number of semaphores allocated in the kernel and the length of semaphore wait queues can be configured during system initialization. Refer to the “Configuring Semaphores” section for more details.The semaphore module is optional and can be configured in or out during system initialization. The message queue module, described later on in this document, uses semaphores. Therefore this module needs to be included if message queues are to be used. The Xilkernel semaphore interface is described below.

int sem_init (sem_t *sem, int pshared, unsigned value)

Parameters sem is the location to store the created semaphore’s identifier. pshared indicates sharing status of the semaphore, between processes. value is the initial count of the semaphore. Note: pshared is unused currently. Returns Returns 0 on success. Returns -1 on failure and sets errno appropriately. errno is set to, x ENOSPC if the system does not have any more semaphore resources left.

EDK OS and Libraries Reference Guide www.xilinx.com 59 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description The sem_init() function initializes the unnamed semaphore referred to by sem. The value of the initialized semaphore is value. Following a successful call to sem_init(), the semaphore may be used in subsequent calls to sem_wait(), sem_trywait(), sem_post(), and sem_destroy(). This semaphore remains usable until the semaphore is destroyed. Only sem itself may be used for performing synchronization. The result of referring to copies of sem in calls to sem_wait(), sem_trywait(), sem_post(), and sem_destroy() is undefined. Attempting to initialize an already initialized semaphore results in undefined behavior. Includes semaphore.h

int sem_destroy (sem_t* sem)

Parameters sem is the semaphore to be destroyed. Returns Returns 0 on success. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL if the semaphore identifier does not refer to a valid semaphore x EBUSY if the semaphore is currently locked, and processes are blocked on it. Description The sem_destroy() function destroys the unnamed semaphore indicated by sem. Only a semaphore that was created using sem_init() may be destroyed using sem_destroy(); the effect of calling sem_destroy() with a named semaphore is undefined. The effect of subsequent use of the semaphore sem is undefined until sem is reinitialized by another call to sem_init(). Includes semaphore.h

int sem_getvalue (sem_t* sem, int* value)

Parameters sem is the semaphore identifier value is the location where the semaphore value is stored. Returns Returns 0 on success and value appropriately filled in. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL if the semaphore identifier refers to an invalid semaphore.

60 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The sem_getvalue() function updates the location referenced by the sval argument to have the value of the semaphore referenced by sem without affecting the state of the semaphore. The updated value represents an actual semaphore value that occurred at some unspecified time during the call, but it need not be the actual value of the semaphore when it is returned to the calling process. If sem is locked, then the object to which sval points is set to a negative number whose absolute value represents the number of processes waiting for the semaphore at some unspecified time during the call. Includes semaphore.h

int sem_wait (sem_t* sem)

Parameters sem is the semaphore identifier. Returns Returns 0 on success and the semaphore in a locked state. Returns -1 on failure and errno is set appropriately. errno can be set to, x EINVAL if the semaphore identifier is invalid. x EIDRM if the semaphore was forcibly removed. Description The sem_wait() function locks the semaphore referenced by sem by performing a semaphore lock operation on that semaphore. If the semaphore value is currently zero, then the calling thread does not return from the call to sem_wait() until it either locks the semaphore or the semaphore is forcibly destroyed. Upon successful return, the state of the semaphore is locked and remains locked until the sem_post() function is executed and returns successfully. Note: When a process is unblocked within the sem_wait call, where it blocked due to unavailability of the semaphore, the semaphore may have been destroyed forcibly. In such a case, -1 is returned. Semaphores maybe forcibly destroyed due to destroying message queues which internally use semaphores. No deadlock detection is provided. Includes semaphore.h

EDK OS and Libraries Reference Guide www.xilinx.com 61 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

int sem_trywait (sem_t* sem)

Parameters sem is the semaphore identifier. Returns Returns 0 on success. Returns -1 on failure and errno is set appropriately. errno can be set to, x EINVAL if the semaphore identifier is invalid. x EAGAIN if the semaphore could not be locked immediately. Description The sem_trywait() function locks the semaphore referenced by sem only if the semaphore is currently not locked; that is, if the semaphore value is currently positive. Otherwise, it does not lock the semaphore and returns -1. Includes semaphore.h

int sem_timedwait (sem_t* sem, unsigned ms)

Parameters sem is the semaphore identifier. Returns Returns 0 on success and the semaphore in a locked state. Returns -1 on failure and errno is set appropriately. errno can be set to, x EINVAL - If the semaphore identifier does not refer to a valid semaphore x ETIMEDOUT - The semaphore could not be locked before the specified timeout expired. x EIDRM - If the semaphore was forcibly removed from the system

62 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The sem_timedwait() function locks the semaphore referenced by sem by performing a semaphore lock operation on that semaphore. If the semaphore value is currently zero, then the calling thread does not return from the call to sem_timedwait() until it either locks the semaphore or the semaphore is forcibly destroyed or if the timeout specified has elapsed. Upon successful return, the state of the semaphore is locked and remains locked until the sem_post() function is executed and returns successfully. Note: When a process is unblocked within the sem_wait call, where it blocked due to unavailability of the semaphore, the semaphore may have been destroyed forcibly. In such a case, -1 is returned. Semaphores maybe forcibly destroyed due to destroying message queues which internally use semaphores. No deadlock detection is provided. Note: This routine depends on software timers support being present in the kernel and is defined only if CONFIG_TIME is true. Note: This routine is slightly different from the POSIX equivalent. The POSIX version specifies the timeout as absolute wall-clock time. Since there is no concept of absolute time in Xilkernel, we use relative time specified in milliseconds. Includes semaphore.h

int sem_post (sem_t* sem)

Parameters sem is the semaphore identifier Returns Returns 0 on success. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL if the semaphore identifier is invalid. Description The sem_post() function unlocks the semaphore referenced by sem by performing a semaphore unlock operation on that semaphore. If the semaphore value resulting from this operation is positive, then no threads were blocked waiting for the semaphore to become unlocked; the semaphore value is simply incremented. If the value of the semaphore resulting from this operation is zero or negative, then one of the threads blocked waiting for the semaphore is allowed to return successfully from its call to sem_wait(). This is either the first thread on the queue, if scheduling mode is SCHED_RR or, it is the highest priority thread in the queue, if scheduling mode is SCHED_PRIO. Note: If an unlink operation had been requested on the semaphore, the unlink is performed if the post operation sees that no more processes are waiting on the semaphore. Includes semaphore.h

EDK OS and Libraries Reference Guide www.xilinx.com 63 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

sem_t* sem_open (const char* name, int oflag, ...)

Parameters name points to a string naming a semaphore object. oflag is the flag that controls the semaphore creation. Returns Returns a pointer to the created/existing semaphore identifier. Returns SEM_FAILED on failures and errno is set appropriately. errno can be set to, x ENOSPC - If the system is out of resources to create a new semaphore (or mapping) x EEXIST if O_EXCL has been requested and the named semaphore already exists. x EINVAL if the parameters are invalid.

64 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The sem_open() function establishes a connection between a named semaphore and a process. Following a call to sem_open() with semaphore name name, the process may reference the semaphore associated with name using the address returned from the call. This semaphore may be used in subsequent calls to sem_wait(), sem_trywait(), sem_post(), and sem_close(). The semaphore remains usable by this process until the semaphore is closed by a successful call to sem_close(). The oflag argument controls whether the semaphore is created or merely accessed by the call to sem_open(). The following flag bits may be set in oflag: O_CREAT This flag is used to create a semaphore if it does not already exist. If O_CREAT is set and the semaphore already exists, then O_CREAT has no effect, except as noted under O_EXCL. Otherwise, sem_open() creates a named semaphore. The O_CREAT flag requires a third and a fourth argument: mode, which is of type mode_t, and value, which is of type unsigned. The semaphore is created with an initial value of value. After the semaphore named name has been created by sem_open() with the O_CREAT flag, other processes can connect to the semaphore by calling sem_open() with the same value of name. O_EXCL If O_EXCL and O_CREAT are set, sem_open() fails if the semaphore name exists. The check for the existence of the semaphore and the creation of the semaphore if it does not exist are atomic with respect to other processes executing sem_open() with O_EXCL and O_CREAT set. If O_EXCL is set and O_CREAT is not set, the effect is undefined. If flags other than O_CREAT and O_EXCL are specified in the oflag parameter, an error is signalled. If a process makes multiple successful calls to sem_open() with the same value for name, the same semaphore address is returned for each such successful call, provided that there have been no calls to sem_unlink() for this semaphore. Note: The mode argument is unused currently. This interface is optional and is defined only if CONFIG_NAMED_SEMA is true. Includes semaphore.h

EDK OS and Libraries Reference Guide www.xilinx.com 65 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

int sem_close (sem_t* sem)

Parameters sem is the semaphore identifier. Returns Returns 0 on success. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL - If the semaphore identifier is invalid. x ENOTSUP - If the semaphore is currently locked and/or processes are blocked on the semaphore. Description The sem_close() function indicates that the calling process is finished using the named semaphore sem. The sem_close() function deallocates (that is, make available for reuse by a subsequent sem_open() by this process) any system resources allocated by the system for use by this process for this semaphore. The effect of subsequent use of the semaphore indicated by sem by this process is undefined. The name mapping for this named semaphore is also destroyed. The call fails if the semaphore is currently locked. Note: This interface is optional and is defined only if CONFIG_NAMED_SEMA is true. Includes semaphore.h

int sem_unlink (const char* name)

Parameters name is the name that refers to the semaphore Returns Returns 0 on success. Returns -1 on failure and errno is set appropriately. errno can be set to, x ENOENT - If an entry for name cannot be located. Description The sem_unlink() function removes the semaphore named by the string name. If the semaphore named by name has processes blocked on it, then sem_unlink() has no immediate effect on the state of the semaphore. The destruction of the semaphore is postponed until all blocked and locking processes relinquish the semaphore. Calls to sem_open() to recreate or reconnect to the semaphore refer to a new semaphore after sem_unlink() is called. The sem_unlink() call does not block until all references relinquish the semaphore; it returns immediately. Note: If an unlink operation had been requested on the semaphore, the unlink is performed on a post operation that sees that no more processes waiting on the semaphore. This interface is optional and is defined only if CONFIG_NAMED_SEMA is true. Includes semaphore.h

66 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Message Queues Xilkernel supports kernel allocated XSI message queues. XSI is the X/Open System Interface which is a set of optional interfaces under POSIX. Message queues can be used as an IPC mechanism. The message queues can take in arbitrary sized messages. However, buffer memory allocation must be configured appropriately for the memory blocks required for the messages, as a part of system buffer memory allocation initialization.The number of message queue structures allocated in the kernel and the length of the message queues can be also be configured during system initialization. The message queue module is optional and can be configured in/out. Refer to the “Configuring Message Queues” section for more details. This module depends on the semaphore module and the dynamic buffer memory allocation module being present in the system. There is also a larger, but more powerful message queue functionality that can be configured. When the enhanced message queue interface is chosen, then xil_malloc and xil_free are used to allocate and free space for the messages. Therefore, arbitrary sized messages can be passed around without having to make sure that buffer memory allocation can handle requests for arbitrary size. The Xilkernel message queue interface is described below.

int msgget(key_t key, int msgflg)

Parameters key is a unique identifier for referring to the message queue. msgflg specifies the message queue creation options. Returns Returns a unique non-negative integer message queue identifier. Returns -1 on failure and sets errno appropriately. errno can be set to, x EEXIST - If a message queue identifier exists for the argument key but ((msgflg & IPC_CREAT) && msgflg & IPC_EXCL)) is non-zero. x ENOENT - A message queue identifier does not exist for the argument key and (msgflg & IPC_CREAT) is 0. x ENOSPC - If the message queue resources are exhausted

EDK OS and Libraries Reference Guide www.xilinx.com 67 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description The msgget() function returns the message queue identifier associated with the argument key. A message queue identifier, associated message queue, and data structure (see ), are created for the argument key if the argument key does not already have a message queue identifier associated with it, and (msgflg & IPC_CREAT) is non-zero. Upon creation, the data structure associated with the new message queue identifier is initialized as follows: x msg_qnum, msg_lspid, msg_lrpid are set equal to 0. x msg_qbytes is set equal to the system limit (MSGQ_MAX_BYTES). The msgget() function fails if a message queue identifier exists for the argument key but ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) is non-zero. Note: IPC_PRIVATE is not supported. Also, messages in the message queue are not required to be of the form shown below. There is no support for message type based message receives and sends in this implementation. struct mymsg { long mtype; /* Message type. */ char mtext[some_size]; /* Message text. */ }

Includes sys/msg.h sys/ipc.h

int msgctl (int msqid, int cmd, struct msqid_ds* buf)

Parameters msqid is the message queue identifier. cmd is the command. buf is the data buffer Returns Returns 0 on success. Status is returned in buf for IPC_STAT Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL - If msgid parameter refers to an invalid message queue or if cmd is invalid or if buf contains invalid parameters.

68 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The msgctl() function provides message control operations as specified by cmd. The following values for cmd, and the message control operations they specify, are: IPC_STAT Place the current value of each member of the msqid_ds data structure associated with msqid into the structure pointed to by buf. The contents of this structure are defined in . IPC_SET - Unsupported IPC_RMID Remove the message queue identifier specified by msqid from the system and destroy the message queue and msqid_ds data structure associated with it. The remove operation forcibly destroys the semaphores used internally and unblocks processes that are blocked on the semaphore. It also deallocates memory allocated for the messages in the queue. Includes sys/msg.h sys/ipc.h

int msgsnd (int msqid, const void *msgp, size_t nbytes, int msgflg)

Parameters msqid is the message queue identifier. msgp is a pointer to the message buffer. nbytes is the size of the message msgflg is used to specify message send options. Returns Returns 0 on success. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL - The value of msgid is not a valid message queue identifier. x ENOSPC - The system could not allocate space for the message. x EIDRM - The message queue was removed from the system during the send operation.

EDK OS and Libraries Reference Guide www.xilinx.com 69 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description The msgsnd() function sends a message to the queue associated with the message queue identifier specified by msqid. The argument msgflg specifies the action to be taken if the message queue is full: If (msgflg & IPC_NOWAIT) is non-zero, the message is not sent and the calling thread returns immediately. If (msgflg & IPC_NOWAIT) is 0, the calling thread suspends execution until one of the following occurs: x The condition responsible for the suspension no longer exists, in which case the message is sent. x The message queue identifier msqid is removed from the system; when this occurs -1 is returned. The send fails if it is unable to allocate memory to store the message inside the kernel. On a successful send operation, the msg_lspid and msg_qnum members of the message queues are appropriately set. Includes sys/msg.h sys/ipc.h

ssize_t msgrcv (int msqid, void *msgp, size_t nbytes, long msgtyp, int msgflg)

Parameters msqid is the message queue identifier. msgp is the buffer where the received message is to be copied. nbytes specifies the size of the message that the buffer can hold. msgtyp is unsupported currently. msgflg is used to control the message receive operation. Returns Returns 0 on success and stores received message in user buffer. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL - If msgid is not a valid message queue identifier. x EIDRM - If the message queue was removed from the system. x ENOMSG - nbytes is smaller than the size of the message in the queue.

70 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The msgrcv() function reads a message from the queue associated with the message queue identifier specified by msqid and places it in the user-defined buffer pointed to by msgp. The argument nbytes specifies the size in bytes of the message. The received message is truncated to nbytes bytes if it is larger than nbytes and (msgflg & MSG_NOERROR) is non-zero. The truncated part of the message is lost and no indication of the truncation is given to the calling process. If MSG_NOERROR is not specified and the received message is larger than nbytes, -1 is returned signalling error. The argument msgflg specifies the action to be taken if a message is not on the queue. These are as follows: If (msgflg & IPC_NOWAIT) is non-zero, the calling thread returns immediately with a return value of -1. If (msgflg & IPC_NOWAIT) is 0, the calling thread suspends execution until one of the following occurs: i A message is placed on the queue. i The message queue identifier msqid is removed from the system; when this occurs -1 is returned. Upon successful completion, the following actions are taken with respect to the data structure associated with msqid: i msg_qnum is decremented by 1. i msg_lrpid is set equal to the process ID of the calling process. Includes sys/msg.h sys/ipc.h

Shared Memory Xilkernel supports kernel allocated XSI shared memory. XSI is the X/Open System Interface which is a set of optional interfaces under POSIX. Shared memory is a common, low-latency IPC mechanism. Shared memory blocks required during run-time must be identified and specified during the system configuration.From this specification, buffer memory is allocated to each shared memory region. Shared memory is currently not allocated dynamically at run-time. This module is optional and can be configured in or out during system specification. Refer to the “Configuring Shared Memory” section for more details. The Xilkernel shared memory interface is described below. Caution! The memory buffers allocated by the shared memory API might not be aligned at word boundaries. Therefore, structures should not be arbitrarily mapped to shared memory segments, without checking if alignment requirements are met.

EDK OS and Libraries Reference Guide www.xilinx.com 71 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

int shmget (key_t key, size_t size, int shmflg)

Parameters key is used to uniquely identify the shared memory region. size is the requested size of the shared memory segment shmflg is used to specify segment creation options Returns Returns unique non-negative shared memory identifier on success. Returns -1 on failure and sets errno appropriately. errno can be set to, x EEXIST - A shared memory identifier exists for the argument key but (shmflg &IPC_CREAT) && (shmflg &IPC_EXCL) is non-zero. x ENOTSUP - Unsupported shmflg. x ENOENT - A shared memory identifier does not exist for the argument key and (shmflg &IPC_CREAT) is 0 Description The shmget() function returns the shared memory identifier associated with key. A shared memory identifier, associated data structure, and shared memory segment of at least size bytes (see ) are created for key if one of the following is true: x The argument key is equal to IPC_PRIVATE. x The argument key does not already have a shared memory identifier associated with it and (shmflg &IPC_CREAT) is non- zero. Upon creation, the data structure associated with the new shared memory identifier shall be initialized.The value of shm_segsz is set equal to the value of size.The values of shm_lpid, shm_nattch, shm_cpid are all initialized appropriately.When the shared memory segment is created, it is initialized with all zero values Note: At least one of the shared memory segments available in the system must match exactly the requested size for the call to succeed. Key IPC_PRIVATE is not supported. Includes sys/shm.h sys/ipc.h

72 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

int shmctl (int shmid, int cmd, struct shmid_ds *buf)

Parameters shmid is the shared memory segment identifier. cmd is the command to the control function. buf is the buffer where the status is returned. Returns Returns 0 on success. Status is returned in buffer for IPC_STAT. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL if shmid refers to an invalid shared memory segment or cmd or other params are invalid. Description The shmctl() function provides a variety of shared memory control operations as specified by cmd. The following values for cmd are available: IPC_STAT - Place the current value of each member of the shmid_ds data structure associated with shmid into the structure pointed to by buf. The contents of the structure are defined in IPC_SET is not supported IPC_RMID Remove the shared memory identifier specified by shmid from the system and destroy the shared memory segment and shmid_ds data structure associated with it. No notification is sent to processes still attached to the segment. Includes sys/shm.h sys/ipc.h

void* shmat (int shmid, const void *shmaddr, int flag)

Parameters shmid is the shared memory segment identifier. shmaddr is used to specify the location, to attach shared memory segment. This is unused currently. flag is used to specify SHM attach options. Returns Returns the start address of the shared memory segment on success. Returns NULL on failure and sets errno appropriately. errno can be set to, x EINVAL if shmid refers to an invalid shared memory segment

EDK OS and Libraries Reference Guide www.xilinx.com 73 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description shmat() increments the value of shm_nattch in the data structure associated with the shared memory ID of the attached shared memory segment and returns the segment’s start address. shm_lpid is also appropriately set. Note: shmaddr and flag arguments are not used. Includes sys/shm.h sys/ipc.h

int shm_dt (void *shmaddr)

Parameters shmaddr is the shared memory segment address that is to be detached. Returns Returns 0 on success. Returns -1 on failure and sets errno appropriately. errno can be set to, x EINVAL if shmaddr is not within any of the available shared memory segments. Description The shmdt() function detaches the shared memory segment located at the address specified by shmaddr from the address space of the calling process.The value of shm_nattch is also decremented.The memory segment is not removed from the system and can be attached to again. Includes sys/shm.h sys/ipc.h

74 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Mutex Locks Xilkernel provides support for kernel allocated POSIX thread mutex locks. This synchronization mechanism can be used alongside of the pthread_ API. The number of mutex locks and the length of the mutex lock wait queue can be configured during system specification. PTHREAD_MUTEX_DEFAULT and PTHREAD_MUTEX_RECURSIVE type mutex locks are supported. This module is also optional and can be configured in or out during system specification. Please refer to the “Configuring Shared Memory”section for more details.

int pthread_mutex_init pthread_mutex_t* mutex, const pthread_mutexattr_t* attr)

Parameters mutex is the location where the newly created mutex lock’s identifier is to be stored. attr is the mutex creation attributes structure. Returns Returns 0 on success and mutex identifier in *mutex. Returns EAGAIN if system out of resources. Description The pthread_mutex_init() function initializes the mutex referenced by mutex with attributes specified by attr. If attr is NULL, the default mutex attributes are used; the effect shall be the same as passing the address of a default mutex attributes object. Refer to pthread_mutexattr_ routines to determine what kind of mutex creation attributes can be changed. Upon successful initialization, the state of the mutex becomes initialized and unlocked. Only mutex itself may be used for performing synchronization. The result of referring to copies of mutex in calls to pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(), and pthread_mutex_destroy() is undefined. Attempting to initialize an already initialized mutex results in undefined behavior. In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are statically allocated. The effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed. For example, static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER; Note: The mutex locks allocated by Xilkernel by default, follow the semantics of PTHREAD_MUTEX_DEFAULT mutex locks. i.e attempting to recursively lock the mutex results in undefined behavior. Attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior. Attempting to unlock the mutex if it is not locked results in undefined behavior. Includes pthread.h

EDK OS and Libraries Reference Guide www.xilinx.com 75 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

int pthread_mutex_destroy (pthread_mutex_t* mutex)

Parameters mutex is the mutex identifier. Returns Returns 0 on success. Returns EINVAL if mutex refers to an invalid identifier. Description The pthread_mutex_destroy() function destroys the mutex object referenced by mutex; the mutex object becomes, in effect, uninitialized. A destroyed mutex object can be reinitialized using pthread_mutex_init(); the results of otherwise referencing the object after it has been destroyed are undefined. Note: Mutex lock/unlock state disregarded during destroy. No consideration is given for waiting processes. Includes pthread.h

int pthread_mutex_lock (pthread_mutex_t* mutex)

Parameters mutex is the mutex identifier. Returns Returns 0 on success and mutex in a locked state. Returns EINVAL on invalid mutex reference and -1 on unhandled errors. Description The mutex object referenced by mutex is locked by the thread calling pthread_mutex_lock(). If the mutex is already locked, the calling thread blocks until the mutex becomes available. If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex shall maintain the concept of a lock count. When a thread successfully acquires a mutex for the first time, the lock count shall be set to one. Every time a thread relocks this mutex, the lock count shall be incremented by one. Each time the thread unlocks the mutex, the lock count shall be decremented by one. . If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to recursively lock the mutex results in undefined behavior. If successful, this operation returns with the mutex object referenced by mutex in the locked state. Includes pthread.h

76 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

int pthread_mutex_trylock (pthread_mutex_t* mutex)

Parameters mutex is the mutex identifier. Returns Returns 0 on success and mutex in a locked state. Returns EINVAL on invalid mutex reference, EBUSY if mutex is already locked and -1 on unhandled errors. Description The mutex object referenced by mutex is locked by the thread calling pthread_mutex_trlock(). If the mutex is already locked, the calling thread returns immediately with EBUSY. If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex shall maintain the concept of a lock count. When a thread successfully acquires a mutex for the first time, the lock count shall be set to one. Every time a thread relocks this mutex, the lock count shall be incremented by one. Each time the thread unlocks the mutex, the lock count shall be decremented by one. . If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to recursively lock the mutex results in undefined behavior. If successful, this operation returns with the mutex object referenced by mutex in the locked state. Includes pthread.h

int pthread_mutex_unlock (pthread_mutex_t* mutex)

Parameters mutex is the mutex identifier. Returns Returns 0 on success. Returns EINVAL on invalid mutex reference and -1 on undefined errors.

EDK OS and Libraries Reference Guide www.xilinx.com 77 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description The pthread_mutex_unlock() function shall release the mutex object referenced by mutex. If there are threads blocked on the mutex object referenced by mutex when pthread_mutex_unlock() is called, resulting in the mutex becoming available, the scheduling policy shall determine which thread shall acquire the mutex. If it is SCHED_RR, then the thread that is at the head of the mutex wait queue is unblocked and allowed to lock the mutex. If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex shall maintain the concept of a lock count. When the lock count reaches zero, the mutex shall become available for other threads to acquire. If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, an error shall be returned. If the mutex type is PTHREAD_MUTEX_DEFAULT attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior. Attempting to unlock the mutex if it is not locked results in undefined behavior. If successful, this operation returns with the mutex object referenced by mutex in the unlocked state. Includes pthread.h

int pthread_mutexattr_init (pthread_mutexattr_t* attr)

Parameters attr is the location of the attributes structure. Returns Returns 0 on success. Returns EINVAL if attr refers to an invalid location. Description The pthread_mutexattr_init() function initializes a mutex attributes object attr with the default value for all of the attributes defined by the implementation. Note: Refer to for the contents of the pthread_mutexattr structure.This routine does not involve a call into the kernel. Includes pthread.h

int pthread_mutexattr_destroy (pthread_mutexattr_t* attr)

Parameters attr is the location of the attributes structure. Returns Returns 0 on success. Returns EINVAL if attr refers to an invalid location.

78 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

Description The pthread_mutexattr_destroy() function destroys a mutex attributes object; the object becomes, in effect, uninitialized. Note: This routine does not involve a call into the kernel. Includes pthread.h

int pthread_mutexattr_settype (pthread_mutexattr_t* attr, int type)

Parameters attr is the location of the attributes structure. type is the type to set the mutex to Returns Returns 0 on success. Returns EINVAL if attr refers to an invalid location or if type is an unsupported type. Description The pthread_mutexattr_settype() function sets the type of a mutex in a mutex attributes structure to the specified type. Only PTHREAD_MUTEX_DEFAULT and PTHREAD_MUTEX_RECURSIVE are supported. Note: This routine does not involve a call into the kernel. Includes pthread.h

int pthread_mutexattr_gettype (pthread_mutexattr_t* attr, int * type)

Parameters attr is the location of the attributes structure. type is a pointer to the location to store the mutex type in Returns Returns 0 on success. Returns EINVAL if attr refers to an invalid location. Description The pthread_mutexattr_gettype() function gets the type of a mutex in a mutex attributes structure and stores it in the location pointed to by type. Includes pthread.h

Dynamic Buffer Memory Management The kernel provides a buffer memory allocation scheme, which can be used by applications that need dynamic memory allocation. These interfaces are alternatives to the standard C memory allocation routines - malloc, free which are much slower and bigger, though more powerful. The allocation routines hand off pieces of memory from a pool of memory that the user passes to the buffer memory manager. Basically, the buffer memory manager manages the pool of memory for the user. The user can dynamically create new

EDK OS and Libraries Reference Guide www.xilinx.com 79 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

pools of memory. The user can also statically specify the different memory blocks sizes and number of such memory blocks required for his applications. Refer to the “Configuring Buffer Memory Allocation” section for more details. This method of buffer management is relatively simple, small and a fast way of allocating memory. The following are the buffer memory allocation interfaces. This module is optional and can be included during system initialization. Caution! The buffer memory allocation API internally uses the memory pool handed down the by the user to store a free-list in-place within the memory pool. As a result, only memory sizes greater than or equal to 4 bytes long are supported by the buffer memory allocation APIs. Also, since there is a free-list being built in-place within the memory pool, requests in which memory block sizes are not multiples of 4 bytes will cause misalignment at run-time. This is o.k if your software platform can handle misalignment natively or through exceptions. Note that the memory buffers allocated and returned by the buffer memory allocation API might also not be aligned at word boundaries. Therefore, your application should not arbitrarily map structures to memory allocated this way, without checking if alignment and padding requirements are met.

int bufcreate (membuf_t *mbuf, void *memptr, int nblks, size_t blksiz)

Parameters mbuf is location to store the identifier of the memory pool created. memptr is the pool of memory to use. nblks is the number of memory blocks that this pool should support. blksiz is the size of each memory block in bytes. Returns Returns 0 on success and stores the identifier of the created memory pool in the location pointed to by mbuf. Returns -1 on errors. Description This function creates a memory pool out of the memory block specified in memptr. nblks number of chunks of memory are defined within the pool, each of size blksiz. Therefore, memptr must point to at least (nblks * blksiz) bytes of memory. blksiz must be greater than or equal to 4. Includes sys/bufmalloc.h

int bufdestroy (membuf_t mbuf).

Parameters mbuf is the identifier of the memory pool to destroy. Returns 0 on success and -1 on errors. Description This routine destroys the memory pool identified by mbuf. Includes sys/bufmalloc.h

80 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Xilkernel API R

void* bufmalloc (membuf_t mbuf, size_t siz)

Parameters mbuf is the identifier of the memory pool to allocate memory from. size is the size of memory block requested. Returns Returns the start address of the memory block on success. Return NULL on failure and sets errno appropriately. errno is set to, x EINVAL if mbuf refers to an invalid memory buffer. x EAGAIN if the request cannot be satisfied. Description Allocate a chunk of memory from the memory pool specified by mbuf. If mbuf is MEMBUF_ANY, then all available memory pools are searched for the request and the first pool that has a free block of size siz, is used and allocated from. Includes sys/bufmalloc.h

void buffree (membuf_t mbuf, void* mem).

Parameters mbuf is the identifier of the memory pool. mem is the address of the memory block. Returns None Description Free the memory allocated by a corresponding call to bufmalloc. If mbuf is MEMBUF_ANY, return the memory to the pool that satisfied this request. If not, return the memory to specified pool. Behavior is undefined if arbitrary values are specified for mem. Includes sys/bufmalloc.h

Software Timers Xilkernel provides software timer functionality, for time relating processing. This module is optional and can be configured in or out. Refer to “Configuring Software Timers” for more information on customizing this module. The following interfaces are available with the software timers module,

unsigned int xget_clock_ticks ().

Parameters None Returns Number of kernel ticks elapsed since the kernel was started.

EDK OS and Libraries Reference Guide www.xilinx.com 81 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description A single tick is counted, every time the kernel timer delivers an interrupt. This is stored in a 32-bit integer and hence will eventually overflow. The call to xget_clock_ticks () returns this tick information, without conveying the overflows that have occurred. Includes sys/timer.h

time_t time (time_t *timer)

Parameters timer points to the memory location to store the requested time information in. Returns Number of seconds elapsed since the kernel was started Description This routine time elapsed since kernel start in units of seconds. This is also subject to overflow. Includes sys/timer.h

unsigned sleep (unsigned int ms)

Parameters ms is the number of milliseconds to sleep. Returns Number of seconds that were not slept for. Returns 0 on complete success. Description This routine causes the invoking process to enter a sleep state for the specified number of milliseconds. Includes sys/timer.h

Interrupt Handling Xilkernel abstracts away primary interrupt handling requirements from the user application. Even though the kernel will be functional without any interrupts, it makes sense for the system to be at least driven by a single timer interrupt for scheduling. In this case the kernel handles the main timer interrupt, using it as the kernel tick to perform scheduling. The timer interrupt is initialized and tied to the vectoring code during system initialization. This kernel pulse is also used to provide software timer facilities and time

82 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Interrupt Handling R

related routines. Xilkernel can also handle multiple interrupts when connected through an interrupt controller. Xilkernel can work with the opb_intc interrupt controller core.

IE = 1

Executing process gets interrupted

IE = 0 -Save complete context; -Switch to kernel IRQ stack; -Execute next level of Execute user level interrupt handling. interrupts if any -If rescheduling is required, invoke the scheduler. -Restore context of the IE = 1 currently selected process.

Resumed process proceeds

IE = 1 X10229

Figure 5-5: Basic Interrupt Service in Xilkernel

The entire interrupt handling scenario is sketched in Figure 5-5. Upon an interrupt, the entire context of the currently executing process is saved into the context save area. Interrupts are disabled from this point in time onwards, till they are enabled at the end of interrupt handling. The execution stack is switched a separate kernel stack. This alleviates the stack burden of the process, as the execution within interrupt, will now, not use the user application stack. This ends the first level of interrupt handling by the kernel. At this point, the kernel transfers control to the second level interrupt handler. This will be the main interrupt handler routine of the interrupt controller. From this point, the interrupt controller’s handler invokes the user specified interrupt handlers for the various interrupting peripherals. In Microblaze kernels, if the system timer is connected through the interrupt controller, then the kernel invisibly handles the main timer interrupt (kernel tick), by registering itself as the handler for that interrupt. The user’s interrupt handlers can perform any kind of interrupt handling action they require, including making system calls. However, the handlers must never invoke blocking system calls. If a system call from an interrupt handler blocks, then the entire kernel will be blocked and the system will come to a suspended state. Use your handlers wisely to do minimum processing upon interrupts. Caution! User level interrupt handlers must not make any blocking system calls. System calls made, if any, should be non-blocking. After all of the user-level interrupt handlers are serviced, the kernel’s first level interrupt handler gets control again. It determines if the preceding interrupt handling caused a rescheduling requirement in the kernel. If there is such a requirement, it invokes the kernel scheduler and performs the appropriate rescheduling. After the scheduler has determined the next process to execute, the context of the new process is restored to and interrupts are enabled again. Note: Currently, Xilkernel only supports an interrupt controller tied to the external interrupt pin of the PPC405. It does not support interrupt controllers tied to the critical input pin of the processor. When Xilkernel is used with multiple-interrupts in the system, the Xilkernel user-level interrupt handling API becomes available. It is described below:

EDK OS and Libraries Reference Guide www.xilinx.com 83 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

unsigned int register_int_handler (int_id_t id, void (*handler)(void*), void *callback)

Parameters id is the zero-based numeric id of the interrupt. handler is the user-level handler. callback is a callback value that can be delivered to the user- level handler. Returns Returns XST_SUCCESS on success. Returns error codes defined in . Description The register_int_handler() function registers the specified user level interrupt handler as the handler for a specified interrupt. The user level routine will be invoked asynchronously upon being serviced by an interrupt controller in the system. The routine returns an error on MicroBlaze systems, if id is the identifier for the system timer interrupt. PPC systems have a dedicated hardware timer interrupt that exists separately from the other interrupts in the system. Therefore, this check is not performed for a PPC system. Includes sys/intr.h

void unregister_int_handler (int_id_t id)

Parameters id is the zero-based numeric id of the interrupt. Returns None Description The unregister_int_handler() function unregisters the registered user level interrupt handler as the handler for the specified interrupt. The routine does nothing and fails silently on MicroBlaze systems, if id is the identifier for the system timer interrupt. Includes sys/intr.h

void enable_interrupt (int_id_t id)

Parameters id is the zero-based numeric id of the interrupt. Returns None

84 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Other Interfaces R

Description The enable_interrupt() function enables the specified interrupt in the interrupt controller. The routine does nothing and fails silently on MicroBlaze systems, if id is the identifier for the system timer interrupt. Includes sys/intr.h

void disable_interrupt (int_id_t id)

Parameters id is the zero-based numeric id of the interrupt. Returns None Description The disable_interrupt() function disables the specified interrupt in the interrupt controller. The routine does nothing and fails silently on MicroBlaze systems, if id is the identifier for the system timer interrupt. Includes sys/intr.h

void acknowledge_interrupt (int_id_t id)

Parameters id is the zero-based numeric id of the interrupt. Returns None Description The acknowledge_interrupt() function acknowledges handling the specified interrupt to the interrupt controller. The routine does nothing and fails silently on MicroBlaze systems, if id is the identifier for the system timer interrupt. Includes sys/intr.h

Other Interfaces Xilkernel, internally, depends on the Standalone BSP. Therefore, all the interfaces that the standalone BSP presents are inherited by Xilkernel. Refer to Chapter 4, “Standalone Board Support Package” for documentation on available interfaces. For e.g to add your own custom handlers for the various exceptions that PPC405 supports, you would use the exception handling interface provided by the Standalone BSP for the PPC405. Xilkernel also inherits the software platform settings parameters of Standalone BSP, including stdin, stdout, exception_vectors for Microblaze v3.00.a. Refer to the Standalone BSP documentation for information on how to use these parameters.

Hardware Requirements and BSP Xilkernel has been designed to closely work with the EDK hardware & software flow. It is completely integrated with the software platform configuration and automatic

EDK OS and Libraries Reference Guide www.xilinx.com 85 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

library/BSP generation mechanism. As a result, a software platform based on Xilkernel can be configured and built in a matter of minutes. However, some services in the kernel require support from the hardware. Scheduling and all the dependant features require a periodic kernel tick and typically some kind of timer is used. Xilkernel has been designed to be able to work with either the Xilinx fit_timer IP core or the opb_timer IP core. By specifying the instance name of the timer device in the software platform configuration, Xilkernel is able to automatically initialize and use the timer cores and timer related services. Refer to “Configuring System Timer” for more information on how to specify the timer device. Xilkernel on the PPC405, uses the internal programmable timer of the processor and hence does not need these external timer cores for kernel functionality. However, on PPC405 systems, you will still need to specify values for the system timer frequency and system timer interval. Xilkernel has also been designed to work in scenarios involving multiple-interrupting peripherals. The user would be using the opb_intc IP core to handle the hardware interrupts and then feed a single IRQ line from the controller to the processor. Just by specifying the name of the interrupt controller peripheral in the software platform configuration, the user would be getting kernel awareness of multiple interrupts. Xilkernel would then, automatically, as a part of its startup, initialize the hardware cores, interrupt system and the second level of software handlers. The user will not have to do this manually. Xilkernel can handle only non-cascaded interrupt controllers. Cascaded interrupt controllers are not supported.

System Initialization The entry point for the kernel is the xilkernel_main( ) routine defined in main.c. The first action performed is hardware specific initialization. This includes registering the interrupt handlers and configuring the system timer. This portion of the initialization depends upon the kind of hardware that is present in the system. Interrupts/exceptions are not enabled after completing hw_init( ). If the user has required user_init( ) to be invoked as a part of the system initialization, then user_init( ) is invoked next (This applies only if the user_init routine is within the symbolic scope of the rest of the kernel). The sys_init( ) routine is entered next. This routine performs initialization of each module such as processes, threads, etc. Specifically, it initializes the following things, in order. 1. Internal process context structures. 2. Ready queues. 3. pthread module. 4. Semaphore module. 5. Message Queue module. 6. Shared memory module. 7. Memory allocation module. 8. Software timers module 9. Idle task creation. 10. Static pthread creation. 11. Static elf process creation. After these steps, interrupts and exceptions are enabled, and the kernel loops infinitely in the idle task, enabling the scheduler to start scheduling processes.

86 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Kernel Customization R

Kernel Customization Xilkernel is highly customizable. As described in previous sections, modules and individual parameters can be changed to suit the user application. The XPS software platform settings dialog provides excellent support for easy configuration of parameters of Xilkernel. Refer to Chapter 2, “Xilinx Platform Studio (XPS)” in the Embedded Systems Tools Guide for more details. In order to customize a module in the kernel, a parameter with the name of the category set to true must be defined in the MSS. For example, to customize the pthread module: parameter config_pthread_support = true is required in the OS specification. Not defining a configurable module’s config_ parameter will mean that the module will be configured out. You do not have to manually key in these parameters and values. Keying in information in the software platform settings GUI, will auto-generate the corresponding MSS snippets. An MSS snippet for configuring OS Xilkernel for a PPC system is given below:

BEGIN OS PARAMETER OS_NAME = xilkernel PARAMETER OS_VER = 3.00.a PARAMETER STDIN = RS232 PARAMETER STDOUT = RS232 PARAMETER proc_instance = ppc405_0 PARAMETER config_debug_support = true PARAMETER verbose = true PARAMETER systmr_spec = true PARAMETER systmr_freq = 100000000 PARAMETER systmr_interval = 80 PARAMETER sysintc_spec = system_intc PARAMETER config_sched = true PARAMETER sched_type = SCHED_PRIO PARAMETER n_prio = 6 PARAMETER max_readyq = 10 PARAMETER config_pthread_support = true PARAMETER max_pthreads = 10 PARAMETER config_sema = true PARAMETER max_sem = 4 PARAMETER max_sem_waitq = 10 PARAMETER config_msgq = true PARAMETER num_msgqs = 1 PARAMETER msgq_capacity = 10 PARAMETER config_bufmalloc = true PARAMETER config_pthread_mutex = true PARAMETER config_time = true PARAMETER max_tmrs = 10 PARAMETER enhanced_features = true PARAMETER config_kill = true PARAMETER mem_table = ((4,30),(8,20)) PARAMETER static_pthread_table = ((shell_main,1)) END The values in the snippet show above are only sample values, targeting a hypothetical board. The configuration directives in the MSS specification have the corresponding implication on memory and code size of the resultant Xilkernel image. This is especially true for kernel allocated structures, whose count can be configured through the MSS. For example, the maximum number of process context structures allocated in the kernel is

EDK OS and Libraries Reference Guide www.xilinx.com 87 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

determined by the sum of two parameters; max_procs and max_pthreads. If a process context structures occupies x bytes of bss memory, then the total bss memory requirement for process contexts will be (max_pthreads*x) bytes. Therefore, such parameters should be carefully tuned, and the final kernel image should be examined with the GNU size utility to make sure that memory requirements are met. To get an idea of the contribution of each kernel allocated structures memory requirements, please take a look at the corresponding header file. The specification in the MSS gets translated by LibGen and the Xilkernel TCL files into C-language configuration directives in two header files: os_config.h and config_init.h. Interested users should take a look at these two files, which are generated in the main processor include directory, to get an idea of how the specification gets translated.

Configuring STDIN and STDOUT The standard input and output peripherals can be configured for Xilkernel. Xilkernel can work without a standard input and output too. These peripherals are the targets of input- output API like print, outbyte, inbyte, etc. Table 5-2: STDIN/STDOUT Configuration Parameters

Attribute Description Type Defaults stdin Instance name of stdin string none peripheral stdout Instance name of string none stdout peripheral

Configuring Scheduling You can configure the scheduling policy followed by the kernel by controlling the following parameters given in Table 5-3.

Table 5-3: Scheduling Parameters Attribute Description Type Defaults config_sched Configure scheduler boolean true module. sched_type Type of Scheduler to be enum SCHED_RR used. Allowed values: x 2 - SCHED_RR x 3 - SCHED_PRIO n_prio Number of priority numeric 32 levels if scheduling is SCHED_PRIO. max_readyq Length of each ready numeric 10 queue. This is the maximum number of processes that can be active in a ready queue at any instant in time.

88 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Kernel Customization R

Configuring Thread Management Threads are the primary mechanism for creating process contexts. The configurable parameters of the thread module are given in Table 5-4.

Table 5-4: Thread Module Parameters Attribute Description Type Defaults config_pthread_support Need pthread module. boolean true max_pthreads Maximum number of numeric 10 threads that can be allocated at any point in time. pthread_stack_size Stack size for dynamically numeric 1000 created threads (in bytes) static_pthread_table Statically configure the array of none threads that startup when 2-tuples the kernel is started. This is defined to be an array with each element containing the parameters pthread_start_func and pthread_prio. pthread_start_func Thread start address. Function none name (string) pthread_prio Thread priority. numeric none

Configuring Semaphores You can configure the semaphores module, the maximum number of semaphores, and semaphore queue length. Table 5-5 shows the parameters used for configuration.

Table 5-5: Semaphore Module Parameters Attribute Description Type Defaults config_sema Need Semaphore module. boolean false max_sem Maximum number of numeric 10 Semaphores. max_sem_waitq Semaphore Wait Queue numeric 10 Length. config_named_sema Configure named boolean false semaphore support in the kernel.

EDK OS and Libraries Reference Guide www.xilinx.com 89 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Configuring Message Queues Optionally, you can configure the message queue module, number of message queues, and the size of each message queue. The message queue module depends on both the semaphore module and the buffer memory allocation module. Parameter definitions used for configuration are shown in Table 5-6. Memory for messages must be explicitly specified in the malloc customization or created at run-time.

Table 5-6: Message Queue Module Parameters Attribute Description Type Defaults config_msgq Need Message Queue module. boolean false num_msgqs Number of message queues in the numeric 10 system. msgq_capacity Maximum number of messages numeric 10 in the queue. use_xil_malloc Provide for more powerful boolean false message queues which use xil_malloc and xil_free to allocate memory for messages.

Configuring Shared Memory Optionally, you can configure the shared memory module and the size of each shared memory segment. All the shared memory segments that will ever be needed must be specified in these parameters.The parameters used for configuration are shown in Table 5-7 .

Table 5-7: Shared Memory Module Parameters Attribute Description Type Defaults config_shm Need Shared Memory module boolean false shm_table Shared Memory table. This is array of 1-tuples none defined as an array with each element having shm_size parameter shm_size Shared Memory size. numeric none num_shm Number of Shared Memories - numeric none Size of the shm_table array.

90 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Kernel Customization R

Configuring Pthread Mutex Locks Optionally, you can choose to include the pthread mutex module, number of mutex locks, and the size of the wait queue for the mutex locks. The parameters used for configuration are shown in Table 5-8.

Table 5-8: Pthread Mutex Module Parameters Attribute Description Type Defaults config_pthread_mutex Need pthread mutex boolean false module. max_pthread_mutex Maximum number numeric 10 of pthread mutex locks available in the system. max_pthread_mutex_ waitq Length of each the numeric 10 mutex lock wait queue.

Configuring Buffer Memory Allocation Optionally, you can configure the dynamic buffer memory management module, size of memory blocks, and number of memory blocks. The parameters used for configuration are shown in Table 5-9.

Table 5-9: Memory Management Module Parameters Attribute Description Type Defaults config_bufmalloc Need buffer memory boolean false management. max_bufs Maximum number of buffer numeric 10 pools that can be managed at any time by the kernel. mem_table Memory block table. This is array of 2-tuples none defined as an array with each element having mem_bsize, mem_nblks parameters. mem_bsize Memory block size. numeric none mem_nblks Number of memory blocks numeric none of a size.

EDK OS and Libraries Reference Guide www.xilinx.com 91 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Configuring Software Timers Optionally, you can configure the software timers module and the maximum number of timers supported. The parameters used for configuration are shown in Table 5-10.

Table 5-10: Software Timers Module Parameters Attribute Description Type Defaults config_time Need software timers and boolean false time management module. max_tmrs Maximum number of numeric 10 software timers in the kernel

Configuring Enhanced Interfaces Optionally, you can configure some enhanced features/interfaces using the following parameters shown in Table 5-11.

Table 5-11: Enhanced Features Attribute Description Type Defaults config_kill Include the ability to kill a boolean false process with the kill() function. config_yield Include the yield() boolean false interface.

Configuring System Timer You can configure the timer device in the system for MicroBlaze kernels. Additionally, you can configure the timer interval for PPC and PIT timer based Microblaze systems. The parameters used are shown in figure Table 5-12.

Table 5-12: Attributes for Copying Kernel Source Files Attribute Description Type Defaults systmr_dev Instance name of the system timer string none (MicroBlaze only) peripheral. systmr_freq Specify the clock frequency of the numeric 1000000 system timer device. For the 00 opb_timer, it is the OPB clock frequency. For the fit_timer, it is the clock given to the fit_timer. For PPC405, it is the frequency of the PPC405. systmr_interval Time interval per system timer numeric 10 interrupt. This is automatically (milliseconds) determined (and cannot be changed) for the fit_timer.

92 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Debugging Xilkernel R

Configuring Interrupt Handling You can configure the interrupt controller device in the system kernels. Adding this parameter automatically configures multiple interrupt support and the user-level interrupt handling API in the kernel. This also causes the kernel to automatically initialize the interrupt controller. The following parameters implemented are shown in Table 5-13.

Table 5-13: Attributes for Copying Kernel Source Files Attribute Description Type Defaults sysintc_spec Specify the instance name of the string null interrupt controller device connected to the external interrupt port.

Configuring Debug Messages You can configure that the kernel outputs debug/diagnostic messages through its execution flow. Enabling the following parameters makes available the DBG_PRINT macro and subsequently its output to the standard output device.

Table 5-14: Attribute for Debug Messages Attribute Description Type Defaults debug_mode Turn on debug messages boolean false from the kernel.

Copy Kernel Source Files You can copy the configured kernel source files to your repository for further editing and use them for building the kernel. The parameters implemented are shown in Table 5-15.

Table 5-15: Attributes for Copying Kernel Source Files Attribute Description Type Defaults copyoutfiles Need to Copy source files boolean false copytodir User repository directory. The path is relative to // path string "../copyoflib" libsrc/xilkernel_v3_00_a/ src directory

Debugging Xilkernel The entire kernel image is a single file that can serve as the target for debugging with the EDK GDB mechanism. User applications and the library must be compiled with -g. Refer to the EST guide for documentation on how to debug applications with GDB. Note: This method of debugging involves great visibility into the kernel and is intrusive. This debugging scheme is also not kernel-user application aware.

EDK OS and Libraries Reference Guide www.xilinx.com 93 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Memory Footprint The size of Xilkernel depends on the user configuration. It is small in size and can fit in different configurations. The following is the memory size output from GNU size utility for the kernel. Xilkernel has been tested with the GCC optimization flag of -O2, These numbers below are also from the same optimization level.

Table 5-16: User Configuration and Xilkernel Size Configuration MicroBlaze (in Kb) PPC (in Kb) Basic kernel functionality 716 with only multi-threading. Full kernel functionality with round-robin scheduling (no multiple 16 26 interrupt support and no enhanced features). Full kernel functionality with priority scheduling (no multiple interrupt 16.5 26.5 support and no enhanced features). Full kernel functionality with all modules ( threads, support for both elf processes, priority scheduling, IPC, synchronization constructs, 22 32 buffer malloc, multiple and user level interrupt handling, drivers for interrupt controller and timer, enhanced features).

Xilkernel File Organization Xilkernel sources are organized in the following manner. The root level contains the data and the src folders. The data folder contains the MLD and the TCL files, that determine the configuration of Xilkernel. The src folder contains all the sources. src has a sub-folder src, which contains non-header source files, categorized into arch, sys and ipc folders. arch contains architecture specific sources, while sys contains system-level sources. ipc contains all the sources implementing the IPC functionality. The header files are contained under the include folder of the top-level src folder. The header files are also organized in a way similar to src.

Modifying Xilkernel Users can further customize Xilkernel by changing the actual code base. To work with a custom copy of Xilkernel, users first copy the Xilkernel source folder (xilkernel_v3_00_a) from within the EDK installation and place it under the bsp folder of the project folder. For example, <..../myproject/bsp/xilkernel_v3_00_a>. LibGen now picks up this source folder of Xilkernel for compilation, since it looks for Xilkernel sources first under the bsp folder before picking it up from the standard installation. Refer to “Xilkernel File Organization”

94 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Advanced Features R

for more information on the organization of the Xilkernel sources. Xilkernel sources have been written in an elementary and intuitive style and include comment blocks above each significant function. Each source file also carries a comment block indicating its role.

Advanced Features

ELF Process Management Xilkernel supports the concept of creating execution contexts out of separate executable ELF files. Users might wish to do this, if they need to create processes out of executable files that lie on some kind of file system (for e.g. XilFatFS or XilMFS). Typically, this involves a loader of some kind. Xilkernel does not feature a loader currently. Assuming that the user application involves a loader of some kind, then given a entry point in memory, to the executable, Xilkernel can create a process out of it. The kernel does not allocate a separate stack for such processes. The stack is setup as a part of the separate executable’s CRT. Note: Such separate executable ELF files that are designed to run on top of Xilkernel, must be compiled with the compiler flag -xl-mode-xilkernel for Microblaze. For PPC405, the user must use a custom linker script, that does not include the .boot and the .vectors sections in the final ELF image. The reason that these modifications are required is that, by default, any program compiled with the EDK GNU tool flow, could potentially contain sections that overwrite the critical interrupt, exception and reset vectors section in memory. Xilkernel requires that its own ELF image initialize these sections and that they stay intact. Using these special compile flags and linker scripts, removes these sections from the output image for applications. The separate executable mode has some caveats, x Global pointer optimization is not supported. Note: This is supported in the default kernel linkage mode. It is not supported only in this separate executable mode. x Xilkernel does not feature a loader when creating new processes and threads. It creates process and thread contexts to start of from memory images assumed to be initialized. Therefore, if any ELF file depends on initialized data sections, then the next time the same memory image is used to create a process, the initialized sections will be invalid, unless some external mechanism is used to reload the ELF image before creating the process. This feature is optional and can be configured in/out. Refer to the “Configuring ELF Process Management” section for more details. An ELF process is created and handled using the following interfaces -

int elf_process_create (void* start_addr, int prio)

Parameters start_addr is the start address of the process prio is the starting priority of the process in the system. Returns Returns the PID of the new process on success. Returns -1 on failure.

EDK OS and Libraries Reference Guide www.xilinx.com 95 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

Description Creates a new process. Allocates a new PID and Process Control Block (PCB) for the process.The process is placed in the appropriate ready queue. Includes sys/process.h

int elf_process_exit (void)

Parameters None

Returns None Description Removes the process from the system. Caution! Do not use this to terminate a thread. Includes sys/process.h

Configuring ELF Process Management You can select the maximum number of processes in the system and the different functions needed to handle processes. The processes and threads that are present in the system on system startup can be configured statically.

Table 5-17: Process Management Parameters Attribute Description Type Defaults config_elf_process Need ELF process boolean true management. max_procs Maximum number of numeric 10 processes in the system. static_elf_process_table Configure startup processes array of 2- none that are separate executable tuples files. This is defined to be an array with each element containing the parameters process_start and process_prio. process_start_addr Process start address. address none process_prio Process priority. numeric none

User Guide It is highly recommend that you refer to the “Using Xilkernel” chapter in the Platform Studio User Guide for detailed steps on configuring and using Xilkernel. Information on how to develop, build, and download applications is also present in that chapter. Some

96 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 User Guide R

example systems and applications are illustrated. These design examples illustrate all the features of Xilkernel and therefore will be very useful for users who would like to quickly get started with Xilkernel.

EDK OS and Libraries Reference Guide www.xilinx.com 97 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 5: Xilkernel

98 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 6

LibXil Net (v2.00.a)

This chapter describes the network library for Embedded processors, libXilNet (v2.00.a). This library provides a new easy to use interface with the relevant parameters. The older libXilNet(v1.00.a) library is deprecated and is not MLD compatible with the new version (v2.00.a). The new xilnet v2.00.a library is code backwards compatible with the older version v1.00.a. Hence any application compile with xilnet v1.00.a will still compile and work the same under v2.00.a. The library includes functions to support the TCP/IP stack and the higher level application programming interface (Socket APIs). The chapter contains the following sections. x “Overview” x “Protocols Supported” x “Library Architecture” x “Protocol Function Description” x “Current Restrictions” x “Functions of LibXilNet” x “Configuring XilNet v2.00.a in EDK” x “Using XilNet in Application”

Overview The Embedded Development Kit (EDK) networking library, libXilNet, allows a processor to connect to the internet. LibXilNet includes functions for handling the TCP/IP stack protocols. It also provides a simple set of Sockets Application Programming Interface (APIs) functions enabling network programming. Lib Xil Net supports multiple connections (through Sockets interface) and hence enables multiple client support. This chapter describes the various functions of LibXilNet.

EDK OS and Libraries Reference Guide www.xilinx.com 99 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

LibXilNet Functions

Function Summary Table 6-1 provides a list of LibXilNet functions with links to detailed descriptions of each.

Table 6-1: LibXilNet Function Summary Functions int xilsock_init (void) void xilsock_rel_socket (int sd) int xilsock_socket (int domain, int type, int proto) int xilsock_bind (int sd, struct sockaddr* addr, int addrlen) int xilsock_accept (int sd, struct sockaddr* addr, int *addrlen) int xilsock_recvfrom (int s, unsigned char* buf, int len) int xilsock_sendto (int s, unsigned char* buf, int len) int xilsock_recv (int s, unsigned char* buf, int len) int xilsock_send (int s, unsigned char* buf, int len) void xilsock_close (int s) void xilnet_mac_init (unsigned int baseaddr) void xilnet_eth_init_hw_addr (unsigned char* addr) int xilnet_eth_recv_frame (unsigned char* frame, int len) void xilnet_eth_send_frame (unsigned char* frame, int len, unsigned char* dipaddr, void *dhaddr, unsigned short type) void xilnet_eth_update_hw_tbl (unsigned char* frame, int proto) void xilnet_eth_add_hw_tbl_entry (unsigned char* ip, unsigned char* hw) int xilnet_eth_get_hw_addr (unsigned char* ip) void xilnet_eth_init_hw_addr_tbl (void) int xilnet_arp (unsigned char* buf, int len) void xilnet_arp_reply (unsigned char* buf, int len) void xilnet_ip_init (unsigned char* ip_addr) int xilnet_ip (unsigned char* buf, int len) void xilnet_ip_header (unsigned char* buf, int len, int proto) unsigned short xilnet_ip_calc_chksum (unsigned char* buf, int len, int proto) int xilnet_udp (unsigned char* buf, int len)

100 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Protocols Supported R

Table 6-1: LibXilNet Function Summary (Continued) Functions void xilnet_udp_header (struct xilnet_udp_conn conn, unsigned char* buf, int len) unsigned short xilnet_udp_tcp_calc_chksum (unsigned char* buf, int len, unsigned char* saddr, unsigned char* daddr, unsigned short proto) void xilnet_udp_init_conns (void) int xilnet_udp_open_conn (unsigned short port) int xilnet_udp_close_conn (struct xilnet_udp_conn *conn) int xilnet_tcp (unsigned char* buf, int len) void xilnet_tcp_header (struct xilnet_tcp_conn conn, unsigned char* buf, int len) void xilnet_tcp_send_pkt (struct xilnet_tcp_conn conn, unsigned char* buf, int len, unsigned char flags) void xilnet_tcp_init_conns (void) int xilnet_tcp_open_conn (unsigned short port) int xilnet_tcp_close_conn (struct xilnet_tcp_conn *conn) int xilnet_icmp (unsigned char* buf, int len) void xilnet_icmp_echo_reply (unsigned char* buf, int len)

Protocols Supported LibXilNet supports drivers and functions for the Sockets API and protocols of TCP/IP stack. The following list enumerates them. x Ethernet Encapsulation (RFC 894) x Address Resolution Protocol (ARP - RFC 826) x Internet Protocol (IP - RFC 791) x Internet Control Management Protocol (ICMP - RFC 792) x Transmission Control Protocol (TCP - RFC 793) x User Datagram Protocol (UDP - RFC 768) x Sockets API

Library Architecture Figure 6-1 gives the architecture of libXilNet. Higher Level applications like HTTP server, TFTP (Trivial File Transfer Protocol), PING etc., uses API functions to use the libXilNet library

EDK OS and Libraries Reference Guide www.xilinx.com 101 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

PING Application HTTP Server Application TFTP Application

Xilinx Sockets Interface

Demultiplexing based on connections ICMP TCP UDP

Demultiplexing based on protocal value in IP Header ARP IP

Demultiplexing based on frame type in Ethernet Header

Ethernet Driver

Incoming Frame

MAC Driver

From PHY Interface

LibXilNet Architecture

UG111_07_111903

Figure 6-1: Schematic Diagram of LibXilNet Architecture

102 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Protocol Function Description R

Protocol Function Description A detailed description of the drivers and the protocols supported is given below.

Media Access Layer (MAC) Drivers Wrapper MAC drivers wrapper initializes the base address of the mac instance specified by the user.This base address is used to send and receive frames. This initialization must be done before using other functionalites of LibXil Net library. The details of the function prototype is defined in the section“Functions of LibXilNet.”

Ethernet Drivers Ethernet drivers perform the encapsulation/removal of ethernet headers on the payload in accordance with the RFC 894. Based on the type of payload (IP or ARP), the drivers call the corresponding protocol callback function. A Hardware Address Table is maintained for mapping 48-bits ethernet address to 32-bits IP address.

ARP (RFC 826) Functions are provided for handling ARP requests. An ARP request (for the 48-bit hardware address) is acknowledged with the 48-bit ethernet address in the ARP reply. Currently, ARP request generation for a desired IP address is not supported. The Hardware address table is updated with the new IP/Ethernet address pair if the ARP request is destined for the processor.

IP (RFC 791) IPv4 datagrams are used by the higher level protocols like ICMP, TCP, and UDP for receiving/sending data. A callback function is provided for ethernet drivers which is invoked whenever there is an IP datagram as a payload in an ethernet frame. Minimal processing of the source IP address check is performed before the corresponding higher level protocol (ICMP, TCP, UDP) is called. Checksum is calculated on all the outgoing IP datagrams before calling the ethernet callback function for sending the data. An IP address for a Embedded Processor needs to be programmed before using it for communication. An IP address initializing function is provided. Refer to the table describing the various routines for further details on the function. Currently no IP fragmentation is performed on the outgoing datagrams. The Hardware address table is updated with the new IP/Ethernet address pair if an IP packet was destined for the processor.

ICMP (RFC 792) ICMP functions handling only the echo requests (ping requests) are provided. Echo requests are issued as per the appropriate requirements of the RFC (Requests For Comments).

UDP (RFC 768) UDP is a connectionless protocol. The UDP callback function, called from the IP layer, performs the minimal check of source port and strips off the UDP header. It demultiplexes from the various open UDP connections. A UDP connection can be opened with a given source port number through Socket functions. Checksum calculation is performed on the

EDK OS and Libraries Reference Guide www.xilinx.com 103 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

outgoing UDP datagram. The number of UDP connections that can be supported simultaneously is configurable.

TCP (RFC 793) TCP is a connection-oriented protocol. Callback functions are provided for sending and receiving TCP packets. TCP maintains connections as a finite state machine. On receiving a TCP packet, minimal check of source port correctness is done, before demultiplexing the TCP packet from the various TCP connections. Necessary action for the demultiplexed connection is taken based on the current machine state. A status flag is returned to indicate the kind of TCP packet received to support connection management. Connection management has to be done at the application level using the status flag received from TCP. Checksum is calculated on all outgoing TCP packets. The number of TCP connections that can be supported simultaneously is configurable.

Sockets API Functions for creating sockets (TCP/UDP), managing sockets, sending and receiving data on UDP and TCP sockets are provided. High level network applications need to use these functions for performing data communication. Refer to Table 6-1 for further details.

Buffer Management XiNet stack is geared to work with smaller FPGA devices and hence minimal buffer management is provided. The stack uses two global buffers - sendbuf, recvbuf - to send and receive ethernet frames. User code can either allocate a buffer or use sendbuf to send packets from the application. When sendbuf is used to transmit packets, user code is responsible to place the application data at the right offset from start of sendbuf accounting for all layers of stack starting from ethernet header.

Current Restrictions Certain restrictions apply to the EDK libXilNet library software. These are x Only server functionalities for ARP. This means ARP requests are not being generated from the processor x Only server functionalities in libXilNet. This means no client application development support provided in libXilNet. x No timers in TCP. Since there are no timers used, every “send” over a TCP connection waits for an “ack” before performing the next “send”.

Functions of LibXilNet The following table gives the list of functions in libXilNet and their descriptions

104 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

int xilsock_init (void)

Parameters None Returns 1 for success and 0 for failure Description Initialize the xilinx internal sockets for use. Includes xilsock.h

void xilsock_rel_socket (int sd)

Parameters sd is the socket to be released. Returns None Description Free the system level socket given by the socket descriptor sd Includes xilsock.h

int xilsock_socket (int domain, int type, int proto)

Parameters domain: Socket Domain type: Socket Type proto: Protocol Family Returns On success, return socket descriptor On failure, return -1 Description Create a socket of type, domain and protocol proto and returns the socket descriptor. The type of sockets can be: SOCK_STREAM (TCP socket) SOCK_DGRAM (UDP socket) domain value currently is AF_INET proto refers to the protocol family which is typically the same as the domain. Includes xilsock.h

EDK OS and Libraries Reference Guide www.xilinx.com 105 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

int xilsock_bind (int sd, struct sockaddr* addr, int addrlen)

Parameters sd: Socket descriptor addr: Pointer to socket structure addrlen: Size of the socket structure Returns On success, return 1 On failure, return -1 Description Bind socket given the descriptor sd to the ip address/port number pair given in structure pointed to by addr of len addrlen. addr is the typical socket structure. Includes xilsock.h

int xilsock_accept (int sd, struct sockaddr* addr, int *addrlen)

Parameters sd: Socket descriptor addr: Pointer to socket structure addrlen: Pointer to the size of the socket structure Returns On success, return socket descriptor On failure, return -1 Description Accepts new connections on socket sd. If a new connection request arrives, it creates a new socket nsd, copies properties of sd to nsd, returns nsd. If a packet arrives for an existing connection, returns 0 and sets the xilsock_status_flag global variable. The various values of the is flag are: XILSOCK_NEW_CONN XILSOCK_CLOSE_CONN XILSOCK_TCP_ACK for new connection, closed a connection and acknowledgment for data sent for a connection respectively. This function implicitly polls/waits on a packet from MAC. Arguments addr and addrlen are in place to support the standard Socket accept function signature. At present, they are not used in the accept function. Includes xilsock.h

106 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

int xilsock_recvfrom (int s, unsigned char* buf, int len)

Parameters s: UDP socket descriptor buf: Buffer to receive data len: Buffer size Returns Number of bytes received Receives data (maximum length of len) from the UDP socket s in Description buf and returns the number of bytes received. Includes xilsock.h

int xilsock_sendto (int s, unsigned char* buf, int len)

Parameters s: UDP socket descriptor buf: Buffer containing data to be sent len: Buffer size Returns Number of bytes received Description Sends data of length len in buf on the UDP socket s and returns the number of bytes sent. Includes xilsock.h

int xilsock_recv (int s, unsigned char* buf, int len)

Parameters s: TCP socket descriptor buf: Buffer to receive data len: Buffer size Returns Number of bytes received Description Receives data (maximum length of len) from the TCP socket s in buf and returns the number of bytes received. Includes xilsock.h

EDK OS and Libraries Reference Guide www.xilinx.com 107 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

int xilsock_send (int s, unsigned char* buf, int len)

Parameters s: TCP socket descriptor buf: Buffer containing data to be sent len: Buffer size Returns Number of bytes received Description Sends data of length len in buf on the UDP socket s and returns the number of bytes sent. Includes xilsock.h

void xilsock_close (int s)

Parameters s: socket descriptor Returns None Description Closes the socket connection given by the descriptor s. This function has to be called from the application for a smooth termination of the connection after a connection is done with the communication. Includes xilsock.h

void xilnet_mac_init (unsigned int baseaddr)

Parameters baseaddr: Base address of the MAC instance used in a system Returns None Description Initialize the MAC base address used in the libXil Net library to baseaddr. This function has to be called at the start of a user program with the base address used in the MHS file for ethernet before starting to use other functions of libXil Net library. Includes mac.h

108 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

void xilnet_eth_init_hw_addr (unsigned char* addr)

Parameters addr: 48-bit colon separated hexa decimal ethernet address string Returns None Description Initialize the source ethernet address used in the libXil Net library to addr. This function has to be called at the start of a user program with a 48-bit, colon separated, hexa decimal ethernet address string for source ethernet address before starting to use other functions of libXil Net library. This address will be used as the source ethernet address in all the ethernet frames. Includes xilsock.h mac.h

int xilnet_eth_recv_frame (unsigned char* frame, int len)

Parameters frame: Buffer for receiving an ethernet frame len: Buffer size Returns Number of bytes received Description Receives an ethernet frame from the MAC, strips the ethernet header and calls either ip or arp callback function based on frame type. This function is called from accept /receive socket functions. The function receives a frame of maximum length len in buffer frame. Includes xilsock.h mac.h

EDK OS and Libraries Reference Guide www.xilinx.com 109 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

void xilnet_eth_send_frame (unsigned char* frame, int len, unsigned char* dipaddr, void *dhaddr, unsigned short type)

Parameters frame: Buffer for sending a ethernet frame len: Buffer size dipaddr: Pointer to the destination ip address dhaddr: Pointer to the destination ethernet address type: Ethernet Frame type (IP or ARP) Returns None Description Creates an ethernet header for payload frame of length len, with destination ethernet address dhaddr, and frame type, type. Sends the ethernet frame to the MAC. This function is called from receive/send (both versions) socket functions. Includes xilsock.h mac.h

void xilnet_eth_update_hw_tbl (unsigned char* frame, int proto)

Parameters frame: Buffer containing an ethernet frame proto: Ethernet Frame type (IP or ARP) Returns None Description Updates the hardware address table with ipaddress/hardware address pair from the ethernet frame pointed to by frame. proto is used in identifying the frame (ip/arp) to get the ip address from the ip/arp packet., Includes xilsock.h mac.h

110 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

void xilnet_eth_add_hw_tbl_entry (unsigned char* ip, unsigned char* hw)

Parameters ip: Buffer contains ip address hw: Buffer containing hardware address Returns None Description Add an ip/hardware pair entry given by ip/hw into the hardware address table Includes xilsock.h mac.h

int xilnet_eth_get_hw_addr (unsigned char* ip)

Parameters ip: Buffer containing ip address Returns Index of entry in the hardware address table that matches the ip address Description Receives an ethernet frame from the MAC, strips the ethernet header and calls either ip or arp callback function based on the frame type. This function is called from accept /receive socket functions. The function receives a frame of maximum length len in buffer frame. Includes xilsock.h mac.h

void xilnet_eth_init_hw_addr_tbl (void)

Parameters None Returns None Description Initializes Hardware Address Table. This function must be called in the user program before using other functions of LibXilNet. Includes xilsock.h mac.h

EDK OS and Libraries Reference Guide www.xilinx.com 111 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

int xilnet_arp (unsigned char* buf, int len)

Parameters buf: Buffer for holding the ARP packet len: Buffer size Returns 0 Description This is the arp callback function. It gets called by the ethernet driver for arp frame type. The arp packet is copied onto the buf of length len. Includes xilsock.h

void xilnet_arp_reply (unsigned char* buf, int len)

Parameters buf: Buffer containing the ARP reply packet len: Buffer size Returns None Description This function sends the arp reply, present in buf of length len, for arp requests. It gets called from the arp callback function for arp requests. Includes xilsock.h

void xilnet_ip_init (unsigned char* ip_addr)

Parameters ip_addr: Array of four bytes holding the ip address to be configured Returns None Description This function initializes the ip address for the processor to the address represented in ip_addr as a dotted decimal string. This function must be called in the application before any communication. Includes xilsock.h

112 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

int xilnet_ip (unsigned char* buf, int len)

Parameters buf: Buffer for holding the IP packet len: Buffer size Returns 0 Description This is the ip callback function. It gets called by the ethernet driver for ip frame type. The ip packet is copied onto the buf of length len. This function calls in the appropriate protocol callback function based on the protocol type. Includes xilsock.h

void xilnet_ip_header (unsigned char* buf, int len, int proto)

Parameters buf: Buffer for the ip packet len: Length of the ip packet proto: Protocol Type in IP packet Returns None Description This function fills in the ip header from the start of buf. The ip packet is of length len and proto is used to fill in the protocol field of ip header. This function is called from the receive/send (both versions) functions. Includes xilsock.h

unsigned short xilnet_ip_calc_chksum (unsigned char* buf, int len, int proto)

Parameters buf: Buffer containing ip packet len: Length of the ip packet Returns checksum calculated for the given ip packet Description This function calculates the checksum for the ip packet buf of length len. This function is called from the ip header creation function. Includes xilsock.h

EDK OS and Libraries Reference Guide www.xilinx.com 113 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

int xilnet_udp (unsigned char* buf, int len)

Parameters buf: Buffer containing the UDP packet len: Length of the UDP packet Returns Length of the data if packet is destined for any open UDP connections else returns 0 Description This is the udp callback function which is called when ip receives a udp packet. This function checks for a valid udp port, strips the udp header, and demultiplexes from the various UDP connections to select the right connection. Includes xilsock.h

void xilnet_udp_header (struct xilnet_udp_conn conn, unsigned char* buf, int len)

Parameters conn: UDP connection buf: Buffer containing udp packet len: Length of udp packet Description This function fills in the udp header from the start of buf for the UDP connection conn. The udp packet is of length len. This function is called from the receivefrom/sendto socket functions. Includes xilsock.h

114 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

unsigned short xilnet_udp_tcp_calc_chksum (unsigned char* buf, int len, unsigned char* saddr, unsigned char* daddr, unsigned short proto)

Parameters buf: Buffer containing UDP/TCP packet len: Length of udp/tcp packet saddr: IP address of the source daddr: Destination IP address proto: Protocol Type (UDP or TCP) Returns the Returns Checksum calculated for the given udp/tcp packet Description This function calculates and fills the checksum for the udp/tcp packet buf of length len. The source ip address (saddr), destination ip address(daddr) and protocol (proto) are used in the checksum calculation for creating the pseudo header. This function is called from either the udp header or the tcp header creation function. Includes xilsock.h

void xilnet_udp_init_conns (void)

Parameters None Returns None Description Initialize all UDP connections so that the states of all the connections specify that they are usable. Includes xilsock.h

int xilnet_udp_open_conn (unsigned short port)

Parameters port: UDP port number Returns Connection index if able to open a connection. If not returns -1. Description Open a UDP connection with port number port. Includes xilsock.h

EDK OS and Libraries Reference Guide www.xilinx.com 115 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

int xilnet_udp_close_conn (struct xilnet_udp_conn *conn)

Parameters conn: UDP connection Returns 1 if able to close else returns -1. Description Close a UDP connection conn. Includes xilsock.h

int xilnet_tcp (unsigned char* buf, int len)

Parameters buf: Buffer containing the TCP packet len: Length of the TCP packet Returns A status flag based on the state of the connection for which the packet has been received Description This is the tcp callback function which is called when ip receives a tcp packet. This function checks for a valid tcp port and strips the tcp header. It maintains a finite state machine for all TCP connections. It demultiplexes from existing TCP open/listening connections and performs an action corresponding to the state of the connection. It returns a status flag which identifies the type of TCP packet received (data or ack or fin). Includes xilsock.h

void xilnet_tcp_header (struct xilnet_tcp_conn conn, unsigned char* buf, int len)

Parameters conn: TCP connection buf: Buffer containing tcp packet len: Length of tcp packet Returns None Description This function fills in the tcp header from the start of buf for the TCP connection conn. The tcp packet is of length len. It sets the flags in the tcp header. Includes xilsock.h

116 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Functions of LibXilNet R

void xilnet_tcp_send_pkt (struct xilnet_tcp_conn conn, unsigned char* buf, int len, unsigned char flags)

Parameters conn: TCP connection buf: Buffer containing TCP packet len: Length of tcp packet Returns The checksum calculated for the given udp/tcp packet Description This function sends a tcp packet, given by buf of length len, with flags (ack/rst/fin/urg/psh) from connection conn. Includes xilsock.h

void xilnet_tcp_init_conns (void)

Parameters None Returns None Description Initialize all TCP connections so that the states of all the connections specify that they are usable. Includes xilsock.h

int xilnet_tcp_open_conn (unsigned short port)

Parameters port: TCP port number Returns Connection index if able to open a connection. If not returns -1. Description Open a TCP connection with port number port. Includes xilsock.h

int xilnet_tcp_close_conn (struct xilnet_tcp_conn *conn)

Parameters conn: TCP connection Returns 1 if able to close else returns -1. Description Close a TCP connection conn. Includes xilsock.h

EDK OS and Libraries Reference Guide www.xilinx.com 117 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

int xilnet_icmp (unsigned char* buf, int len)

Parameters buf: Buffer containing ICMP packet len: Length of the ICMP packet Returns 0 Description This is the icmp callback function which is called when ip receives a icmp echo request packet (ping request). This function checks only for a echo request and sends in an icmp echo reply. Includes xilsock.h

void xilnet_icmp_echo_reply (unsigned char* buf, int len)

Parameters buf: Buffer containing ICMP echo reply packet len: Length of the ICMP echo reply packet Returns None Description This functions fills in the icmp header from the start of buf. The icmp packet is of length len. It sends the icmp echo reply by calling the ip, ethernet send functions. This function is called from the icmp callback function. Includes xilsock.h

Configuring XilNet v2.00.a in EDK In EDK, the XilNet library is configured through XPS (Platform Studio) GUI. From the tree view of XPS, right click on any peripheral and select S/W Settings... option. This launches the Software Platform Settings dialog. The bottom half of the Software Platform panel displays the libraries available in EDK. Select xilnet library version 2.00.a in this panel. Click on the Library/OS Parameters tab to configure xilnet library. Table 6-2 lists the configurable parameters for xilnet library.

Table 6-2: Configurable Parameters for XilNet in MSS Parameter Description emac_instaname Name of the the EMAC instance to be used with xilnet no_of_tcp_conn Number of Open TCP Connections s

no_of_udp_conn Number of Open UDP Connections s

The emac_instname parameter should be set to the ethernet core (regular ethernet core of the lite version, ethernetlite) that is to be used with xilnet library. Setting no_of_tcp_conns

118 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Using XilNet in Application R

lets the stack reserve space for the number of open TCP connections. Similarly, no_of_udp_conns will let the stack reserve space for the number of open UDP connections. Configuring the xilnet library in XPS for the above parameters will result in the following snippet in the MSS file. BEGIN LIBRARY PARAMETER LIBRARY_NAME = xilnet PARAMETER LIBRARY_VER = 2.00.a PARAMETER emac_instname = Ethernet_MAC PARAMETER no_of_tcp_conns = 5 PARAMETER no_of_udp_conns = 5 END

Using XilNet in Application Libgen generates configuration files xilnet_config.h, xilnet_config.c based on the parameter selection in MSS file. These files are built into the xilnet library when libgen is run. In order to use the XilNet functions in your application, you need to do the following initialization: x Define “#include ” in your C-file. x Initialize Ethernet Hardware Table by calling the following function in the application: xilnet_eth_init_hw_addr_tbl(); x Setup MAC and IP addresses using the following functions : xilnet_eth_init_hw_addr(“00:00:00:00:22:38”); xilnet_ip_init(“149.199.6.108”); x Initialize Ethernet/EthernetLite drivers as instructed in the driver. For example, the emac driver call for initialization would be: XEmac_mSetMacAddress(XPAR_ETHERNET_MAC_BASEADDR, mb_hw_addr); where hw_addr is a character array representing the 48 bit MAC address XEmac_mEnable(XPAR_ETHERNET_MAC_BASEADDR);

EDK OS and Libraries Reference Guide www.xilinx.com 119 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 6: LibXil Net (v2.00.a)

120 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 7

LibXil File

Xilinx libraries provide block access to file systems and devices using standard calls such as open, close, read, and write. These routines form the LibXil File module of the libraries. A system can be configured to use the LibXil File module, using the Library Generator (libgen). This chapter contains the following sections. x “Overview” x “Module Usage” x “Module Routines” x “Libgen Support” x “Limitations”

Overview The LibXil library provides block access to files and devices through the LibXil File module. This module provides standard routines such as open, close, read, and write to access file systems and devices. The module LibXil File can also be easily modified to incorporate additional file systems and devices. This module implements a subset of operating system level functions.

Module Usage A file or a device is opened for read and write using the open call in the library. The library maintains a list of open files and devices. Read and write commands can be issued to access blocks of data from the open files and devices.

Function Summary

Table 7-1: LibXil Function Summary Functions int open (const char *name, int flags, int mode) int close (int fd) int read (int fd, char* buf, int nbytes)

EDK OS and Libraries Reference Guide www.xilinx.com 121 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 7: LibXil File

Table 7-1: LibXil Function Summary (Continued) Functions int write (int fd, char* buf, int nbytes) long lseek (int fd, long offset, int whence) int chdir (char* newdir) const char* getcwd (void)

Module Routines

int open (const char *name, int flags, int mode)

Parameters name refers to the name of the device/file. flags refers to the permissions of the file. This field does not have any meaning for a device. mode indicates whether the stream is opened in read, write or append mode. Returns file/device descriptor fd assigned by LibXil File Description This call registers the device or the file in the local device table and calls the underlying open function for that particular file or a device. Includes xilfile.h xparameters.h

int close (int fd)

Parameters fd refers to the file descriptor assigned during by open() Returns If a file is being closed, returns the status returned by the underlying file system. For devices, it returns 1, since devices can not be closed. 0 indicates success in closing a file. Any other value indicates error Description Close the file/device with the fd. Includes xilfile.h xparameters.h

122 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Module Routines R

int read (int fd, char* buf, int nbytes)

Parameters fd refers to the file descriptor assigned by open() buf refers to the destination buffer where the contents of the stream should be copied nbytes: Number of bytes to be copied Returns The number of bytes read. Description Read nbytes from the file/device pointed by the file descriptor fd and store it in the destination pointed by buf. Includes xilfile.h xparameters.h

int write (int fd, char* buf, int nbytes)

Parameters fd: refers to the file descriptor assigned by open() buf: refers to the source buffer nbytes: Number of bytes to be copied Returns The number of bytes written to the file. Description Write nbytes from the buffer, buf to the file pointed by the file descriptor fd Includes xilfile.h xparameters.h

long lseek (int fd, long offset, int whence)

Parameters fd: file descriptor returned by open offset: Number of bytes to seek whence: Location to seek from. This parameter depends on the underlying File System being used. Returns New file pointer location Description The lseek( ) system call moves the file pointer for fd by offset bytes from whence. Includes xilfile.h xparameters.h

EDK OS and Libraries Reference Guide www.xilinx.com 123 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 7: LibXil File

int chdir (char* newdir)

Parameters newdir: Destination directory Returns The same value as returned by the underlying file system. -1 for failure. Description Change the current directory to newdir Includes xilfile.h xparameters.h

const char* getcwd (void)

Parameters None Returns The current working directory. Description Get the absolute path for the current working directory. Includes xilfile.h xparameters.h

Libgen Support

LibXil File Instantiation The users can write application to either interact directly with the underlying file systems and devices or make use of the LibXil File module to integrate with file systems and devices. In order to instantiate LibXil File module in your system, use the following code in your MSS file. BEGIN LIBRARY PARAMETER LIBRARY_NAME = xilfile PARAMETER LIBRARY_VER = 1.00.a PARAMETER peripherals = ( ("", "") , ("", "") ) PARAMETER filesys = (( "" , "" ), ( "" , "" )) END where i : Instance name of the peripheral you need to access through XilFile. i : Mount name for the or i : Name of the filesystem, you need to access through XilFile. (1)

124 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Limitations R

For example, to access two uarts ( myuart1 and myuart2) and the memory file system ( xilmfs ) , use the following code snippet. BEGIN LIBRARY PARAMETER LIBRARY_NAME = xilfile PARAMETER LIBRARY_VER = 1.00.a PARAMETER peripherals = ( ("myuart", "/dev/myuart") , ("myuart2", "/dev/myuart2") ) PARAMETER filesys = (( "xilmfs" , "/dev/mfs" )) END

System Initialization LibGen also generates the system initialization file, which is compiled into the LibXil library. This file initialized the data structure required by the LibXil File module, such as the Device tables and the File System table. This routine also initializes STDIN, STDOUT and STDERR, if present.

Limitations LibXil File module currently enforces the following restrictions: x Only one instance of a File System can be mounted. This file system and the mount point has to be indicated in the Microprocessor Software Specification (MSS) file. x Files cannot have names starting with /dev, since it is a reserved word to be used only for accessing devices. x Currently LibXil File has support only for 1 file system (LibXil Memory File System) and 3 devices (UART, UARTlite and GPIO). x Only devices can be assigned as STDIN, STDOUT and STDERR.

1. Note that there is no instance name for filesystem and other Xilinx Microkernel modules. Hence, the name of the filesystem should be used instead of the instance name.

EDK OS and Libraries Reference Guide www.xilinx.com 125 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 7: LibXil File

126 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 8

LibXil FATFile System (FATfs)

This chapter describes the XilFatfs FATfile system access library. This library provides read/write access to files stored on a Xilinx SystemAce compact flash or microdrive device. The chapter contains the following sections. x “Overview” x “XilFatfs Functions” x “LibGen Customization”

Overview The XilFatfs filesystem access library provides read/write access to files stored on a Xilinx SystemACE CompactFlash or IBM microdrive device. This library requires the underlying hardware platform to contain all of the following: x OPB SYSACE Interface Controller - Logicore module x SystemACE controller and CompactFlash connector x 128MB or 256MB CompactFlash card formatted with a FAT16, FAT12 or FAT32 file system or an IBM microdrive formatted with a FAT16, FAT12 or FAT32 file system Caution! FAT16 is required for SystemACE to directly configure the FPGA but the XilFatfs library can work with the SystemACE hardware to support FAT12 and FAT32 as well. See the documentation on OPB SYSACE Interface Controller in the Processor IP Reference Guide for more details on the hardware. If this library is to be used in a MicroBlaze system, and speed is of concern, it is recommended that the MicroBlaze processor be configured to include a hardware barrel shifter. See the MicroBlaze documentation for more information on including the barrel shifter. Users can easily copy files to the flash device from their PC by plugging the flash or microdrive into a suitable USB adapter or similar device. If the compact flash or microdrive has multiple partitions, each formatted as a FAT12, FAT16 or FAT32 filesystem, XilFatfs allows the partitions to be accessed with partition names. The first partition is always called A:, the second partition is always called B:, and so on. As noted earlier, the first partition must be FAT16 for SystemACE to directly configure the FPGA.

EDK OS and Libraries Reference Guide www.xilinx.com 127 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 8: LibXil FATFile System (FATfs)

XilFatfs Functions This section presents a list of functions provided by the XilFatfs. Table 8-1 provides the function names with signature at a glance.

Table 8-1: Summar of XilFatfs Functions Functions void *sysace_fopen (const char *file, const char *mode) int sysace_fread (void *buffer, int size, int count, void *stream) int sysace_fwrite (void *buffer, int size, int count, void *stream) int sysace_fclose (void *stream) int sysace_mkdir (const char *path) int sysace_chdir (const char *path)

Detailed Description of XilFatfsFunctions

void *sysace_fopen (const char *file, const char *mode)

Parameters file is the name of the file on the flash device. mode is “r” or “w” Returns A non zero file handle on success 0 for failure Description The file name should follow the Microsoft 8.3 naming standard with a file name of up to 8 characters, followed by a ‘.’ and a 3 character extension. In this version of the library, the 3 character extension is mandatory so a sample file might be called test.txt This function returns a file handle that has to be used for subsequent calls to read/write or close the file If mode is “r” and the named file does not exist on the device 0 is returned Includes sysace_stdio.h

128 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 XilFatfs Functions R

int sysace_fread (void *buffer, int size, int count, void *stream)

Parameters buffer is a pre allocated buffer that is passed in to this procedure, and is used to return the characters read from the device size is restricted to 1 count is the number of characters to be read stream is the file handle returned by sysace_fopen Returns Non zero number of characters actually read, for success 0 for failure Description The preallocated buffer is filled with the characters that are read from the device. The return value indicates the actual number of characters read, while count specifies the maximum number of characters to read. The buffer size must be at least count. stream should be a valid file handle returned by a call to sysace_fopen. Includes sysace_stdio.h

int sysace_fwrite (void *buffer, int size, int count, void *stream)

Parameters buffer is a pre allocated buffer that is passed in to this procedure, and contains the characters to be written to the device size is restricted to 1 count is the number of characters to be written stream is the file handle returned by sysace_fopen Returns Non zero number of characters actually written, for success 0 or -1 for failure Description The preallocated buffer is filled (by the caller) with the characters that are to be written to the device. The return value indicates the actual number of characters written, while count specifies the maximum number of characters to write. The buffer size must be at least count. stream should be a valid file handle returned by a call to sysace_fopen. Includes sysace_stdio.h

EDK OS and Libraries Reference Guide www.xilinx.com 129 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 8: LibXil FATFile System (FATfs)

int sysace_fclose (void *stream)

Parameters stream: File handle returned by sysace_fopen Returns 1 On success 0 On failure Description Closes an open file Includes sysace_stdio.h

int sysace_mkdir (const char *path)

Parameters path: path name of new directory Returns 0 On success -1On failure Description Create a new directory specified by path. The directory name can be either absolute or relative, and must follow the 8.3 file naming convention. Examples: a:\\dirname, a:\\dirname.dir, a:\\dir1\\dirnew, dirname, dirname.dir If a relative path is specified, and the current working directory is not already set, the current working directory defaults to the root directory. Includes sysace_stdio.h

int sysace_chdir (const char *path)

Parameters path: path name of new directory Returns 0 On success -1On failure Description Create a new directory specified by path. The directory name can be either absolute or relative, and must follow the 8.3 file naming convention. Examples: a:\\dirname, a:\\dirname.dir, a:\\dir1\\dirnew, dirname, dirname.dir If a relative path is specified, and the current working directory is not already set, the current working directory defaults to the root directory. Includes sysace_stdio.h

130 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 LibGen Customization R

LibGen Customization XilFatfs file system can be integrated with a system using the following snippet in the mss file. There are BEGIN LIBRARY parameter LIBRARY_NAME = xilfatfs parameter LIBRARY_VER = 1.10.a # The following 3 parameters are optional and their default value is false parameter CONFIG_WRITE = true parameter CONFIG_DIR_SUPPORT = true parameter CONFIG_FAT12 = true END

The CONFIG_WRITE parameter when set to true, adds write capabilities to the library. The CONFIG_DIR_SUPPORT parameter when set to true, adds the mkdir and chdir functions to the library. The CONFIG_FAT12 parameter when set to true configures the library to work with FAT12 file systems. Otherwise the library works with both FAT16 and FAT32 file systems.

EDK OS and Libraries Reference Guide www.xilinx.com 131 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 8: LibXil FATFile System (FATfs)

132 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 9

LibXil Memory File System (MFS)

This chapter describes the Memory File System (MFS). This file system resides in RAM/ROM/Flash memory and can be accessed through the LibXil File module or directly. The Memory File System is integrated with a system using the Library Generator. The chapter contains the following sections. x “Overview” x “MFS Functions” x “Utility Functions” x “Additional Utilities” x “C-like access” x “LibGen Customization”

Overview The Memory File System (MFS) component, LibXil MFS, provides users the capability to manage program memory in the form of file handles. Users can create directories, and can have files within each directory. The file system can be accessed from the high level C-language through function calls specific to the file system. Alternatively, users can also manage files through the standard C language functions like open provided in XilFile.

MFS Functions This section presents a list of functions provided by the MFS.

Summary of MFS Functions Table 9-1 provides a summary of MFS functions with links to a detailed descriptions for each.

Table 9-1: Summary of MFS Functions Functions void mfs_init_genimage (int numbytes, char *address, int init_type) int mfs_change_dir (char *newdir) int mfs_create_dir (char *newdir) int mfs_delete_dir (char *dirname)

EDK OS and Libraries Reference Guide www.xilinx.com 133 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

Table 9-1: Summary of MFS Functions (Continued) Functions int mfs_get_current_dir_name (char *dirname) int mfs_delete_file (char *filename) int mfs_rename_file (char *from_file, char *to_file) int mfs_exists_file (char *filename) int mfs_get_usage (int *num_blocks_used, int *num_blocks_free) int mfs_dir_open (char *dirname) int mfs_dir_close (int fd) int mfs_dir_read (int fd, char **filename, int *filesize, int *filetype) int mfs_file_open (char *filename, int mode) int mfs_file_read (int fd, char *buf, int buflen) int mfs_file_write (int fd, char *buf, int buflen) int mfs_file_close (int fd) long mfs_file_lseek (int fd, long offset, int whence) int mfs_ls (void) int mfs_ls_r (int recurse) int mfs_cat (char *filename) int mfs_copy_stdin_to_file (char *filename) int mfs_file_copy (char *from_file, char *to_file)

134 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 MFS Functions R

Detailed Summary of MFS Functions

void mfs_init_fs (int numbytes, char *address, int init_type)

Parameters numbytes is the number of bytes of memory available for the file system address is the starting(base) address of the file system memory init_type is one of MFSINIT_NEW, MFSINIT_IMAGE or MFSINIT_ROM_IMAGE Description Initialize the memory file system. This function must be called before any file system operation. Use mfs_init_genimage instead of this function if the filesystem is being initialized with an image generated by mfsgen. The status/mode parameter determines certain filesystem properties: MFSINIT_NEW creates a new, empty file system for read/write MFSINIT_IMAGE initializes a filesystem whose data has been previously loaded into memory at the base address MFSINIT_ROM_IMAGE initializes a Read-Only filesystem whose data has been previously loaded into memory at the base address Includes xilmfs.h

void mfs_init_genimage (int numbytes, char *address, int init_type)

Parameters numbytes is the number of bytes of memory in the image generated by the mfsgen tool. This is equal to the size of the memory available for the file system, plus four address is the starting(base) address of the image init_type is one of MFSINIT_IMAGE or MFSINIT_ROM_IMAGE Description Initialize the memory file system with an image generated by mfsgen. This function must be called before any file system operation. The status/mode parameter determines certain filesystem properties: MFSINIT_IMAGE initializes a filesystem whose data has been previously loaded into memory at the base address MFSINIT_ROM_IMAGE initializes a Read-Only filesystem whose data has been previously loaded into memory at the base address Includes xilmfs.h

EDK OS and Libraries Reference Guide www.xilinx.com 135 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

int mfs_change_dir (char *newdir)

Parameters newdir is the chdir destination. Returns 1 for success 0 for failure Description If newdir exists, make it the current directory of MFS. Current directory is not modified in case of failure. Includes xilmfs.h

int mfs_create_dir (char *newdir)

Parameters newdir: Directory name to be created Returns On success, return index of new directory in the file system On failure, return 0 Description Create a new empty directory called newdir inside the current directory. Includes xilmfs.h

int mfs_delete_dir (char *dirname)

Parameters dirname: Directory to be deleted Returns On success, return index of new directory in the file system On failure, return 0 Description Delete the directory dirname, if it exists and is empty, Includes xilmfs.h

136 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 MFS Functions R

int mfs_get_current_dir_name (char *dirname)

Parameters dirname: Current directory name is returned in this pointer Returns On Success return 0 On failure return 1 Description Return the name of the current directory in a pre allocated buffer, dirname, of at least 16 chars.Note that it does not return the absolute path name of the current directory, but just the name of the current directory Includes xilmfs.h

int mfs_delete_file (char *filename)

Parameters filename: file to be deleted Returns 1 for success 0 for failure Description Delete filename from its directory. Includes xilmfs.h

int mfs_rename_file (char *from_file, char *to_file)

Parameters from_file: Original filename to_file: New file name Returns On success, return 1 On failure, return 0 Description Rename from_file to to_file. Rename works for directories as well as files. Function fails if to_file already exists. Includes xilmfs.h

EDK OS and Libraries Reference Guide www.xilinx.com 137 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

int mfs_exists_file (char *filename)

Parameters filename: file/directory to be checked for existence Returns 0: if filename does not exist 1: if filename is a file 2: if filename is a directory Description Check if the file/directory is present in current directory. Includes xilmfs.h

int mfs_get_usage (int *num_blocks_used, int *num_blocks_free)

Parameters num_blocks_used: Number of blocks used num_blocks_free: Number of free blocks Returns On Success return 0 On failure return 1 Description Get the number of used blocks and the number of free blocks in the file system through pointers. Includes xilmfs.h

int mfs_dir_open (char *dirname)

Parameters dirname: directory to be opened for reading Returns The index of dirname in the array of open files or -1 on failure. Description Open directory dirname for reading. Reading a directory is done using mfs_dir_read() Includes xilmfs.h

138 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 MFS Functions R

int mfs_dir_close (int fd)

Parameters fd: File descriptor return by open Returns On success return 1 On failure return 1 Description Close the dir pointed by fd. The file system regains the fd and uses it for new files. Includes xilmfs.h

int mfs_dir_read (int fd, char **filename, int *filesize, int *filetype)

Parameters fd: File descriptor return by open; passed to this function by caller filename: Pointer to file name at the current position in the directory in MFS; this value is filled in by this function filesize: Pointer to a value filled in by this function: Size in bytes of filename, if it is a regular file; Number of directory entries if filename is a directory filetype: Pointer to a value filled in by this function: MFS_BLOCK_TYPE_FILE if filename is a regular file; MFS_BLOCK_TYPE_DIR if filename is a directory Returns On Success return number of bytes read. On Failure return 1 Description Read the current directory entry and advance the internal pointer to the next directory entry. filename, filetype and filesize are pointers to values stored in the current directory entry Includes xilmfs.h

EDK OS and Libraries Reference Guide www.xilinx.com 139 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

int mfs_file_open (char *filename, int mode)

Parameters filename: file to be opened mode: Read/Write or Create mode. Returns The index of filename in the array of open files or -1 on failure. Description Open file filename with given mode. The function should be used for files and not directories: MFS_MODE_READ, no error checking is done (if file or directory). MFS_MODE_CREATE creates a file and not a directory. MFS_MODE_WRITE fails if the specified file is a DIR. Includes xilmfs.h

int mfs_file_read (int fd, char *buf, int buflen)

Parameters fd: File descriptor return by open buf: Destination buffer for the read buflen: Length of the buffer Returns On Success return number of bytes read. On Failure return 1 Description Read buflen number bytes and place it in buf.fd should be a valid index in “open files” array, pointing to a file, not a directory. buf should be a pre-allocated buffer of size buflen or more. If fewer than buflen chars are available then only that many chars are read. Includes xilmfs.h

140 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 MFS Functions R

int mfs_file_write (int fd, char *buf, int buflen)

Parameters fd: File descriptor return by open buf: Source buffer from where data is read buflen: Length of the buffer Returns On Success return 1 On Failure return 1 Description Write buflen number of bytes from buf to the file. fd should be a valid index in open_files array. buf should be a pre-allocated buffer of size buflen or more. Caution! Writing to locations other than the end of the file is not supported.Using mfs_file_lseek() go to some other location in the file, and then calling mfs_file_write() is not supported.

Includes xilmfs.h

int mfs_file_close (int fd)

Parameters fd: File descriptor return by open Returns On success return 1 On failure return 1 Description Close the file pointed by fd. The file system regains the fd and uses it for new files. Includes xilmfs.h

EDK OS and Libraries Reference Guide www.xilinx.com 141 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

long mfs_file_lseek (int fd, long offset, int whence)

Parameters fd: File descriptor return by open offset: Number of bytes to seek whence: File system dependent mode: If whence is MFS_SEEK_END, the offset can be either 0 or negative, otherwise offset should be non-negative. If whence is MFS_SEEK_CUR, the offset is calculated from the current location If whence is MFS_SEEK_SET, the offset is calculated from the start of the file Returns On success, return offset from the beginning of the file to the current location On failure, return -1; the current location is not modified Description Seek to a given offset within the file at location fd in open_files array. Caution! It is an error to seek before beginning of file or after the end of file. Caution! Writing to locations other than the end of the file is not supported.Using mfs_file_lseek() go to some other location in the file, and then calling mfs_file_write() is not supported. Includes xilmfs.h

Utility Functions The following few functions are utility functions that can be used along with Xilinx MFS. These functions are defined in mfs_filesys_util.c and are declared in xilmfs.h.

int mfs_ls (void)

Parameters None Returns On success return 1 On failure return 0 Description List contents of current directory on STDOUT. Includes xilmfs.h

142 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Utility Functions R

int mfs_ls_r (int recurse)

Parameters recurse: parameter to control recusrsion If recurse = 0, list the contents of the current directory and stop If recurse > 0, list the contents of the current directory and any subdirectories up to a depth of recurse If recurse = -1, complete recursive directory listing with no limit on recursion depth Returns On success return 1 On failure return 0 Description List contents of current directory on STDOUT. Includes xilmfs.h

int mfs_cat (char *filename)

Parameters filename: File to be displayed Returns On success return 1 On failure return 0 Description Print the file to STDOUT Includes xilmfs.h

int mfs_copy_stdin_to_file (char *filename)

Parameters filename: Destination file. Returns On success return 1 On failure return 0 Description Copy from STDIN to named file. An EOF character should be sent from STDIN to allow the function to return 1 Includes xilmfs.h

EDK OS and Libraries Reference Guide www.xilinx.com 143 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

int mfs_file_copy (char *from_file, char *to_file)

Parameters from_file: Source file to_file: Destination file Returns On success return 1 On failure return 0 Description Copy from_file to to_file. It fails if to_file already exists, or if either could not be opened. Includes xilmfs.h

Additional Utilities

A program called mfsgen is provided along with the MFS library. mfsgen can be used to create an MFS memory image on a host system that can subsequently be downloaded to the embedded system memory. mfsgen itself links to libXilMFS and is compiled to run on the host machine rather than the target MicroBlaze or PowerPC system. Conceptually, this is similar to the familiar zip or tar programs. An entire directory hierarchy on the host system can be copied to a local MFS file image using mfsgen. This file image can then be downloaded on to the memory of the embedded system for creating a pre-loaded file system. A few test programs are included to show how this is done. More information can be found in the readme.txt file in the utils sub-directory and the “Using XilMFS” chapter in the Platform Studio User Guide. Usage: mfsgen -txcvsbf [mfs_filename] [num_blocks] Specify exactly one of c,t,x modes t: list the files in the mfs file system image c: create an mfs file system image using the list of files specified on the command line - Directories specified in this list are traversed recursively x: extract the mfs file system from image to host file system v: verbose mode f: specify the host file name (mfs_filename) where the mfs file system image is stored - If the f option is specified the mfs filename should be specified - If the f option is omitted the default file name is filesystem.mfs s: switch endianness b: number of blocks - should be more than 2 - If the b option is specified the num_blocks value should be specifed - If the b option is omitted the default value of num_blocks is 5000 - The b option is meaningful only when used in conjunction with the c option

C-like access The user can choose not to deal with the details of the file system by using the standard C- like interface provided by Xil File. It provides the basic C stdio functions like open,

144 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 LibGen Customization R

close, read, write, and seek. These functions have identical signature as those in the standard ANSI-C. Thus any program with file operations performed using these functions can be easily ported to MFS by interfacing the MFS in conjunction with library Xilfile.

LibGen Customization Memory file system can be integrated with a system using the following snippet in the mss file. The memory file system should be instantiated with the name xilmfs. The attributes used by libgen and their descriptions are given in Table 9-2. BEGIN LIBRARY parameter LIBRARY_NAME = xilmfs parameter LIBRARY_VER = 1.00.a parameter numbytes= 50000 parameter base_address = 0xffe00000 parameter init_type = MFSINIT_NEW parameter need_utils = false END

Table 9-2: Attributes for including Memory File System Attributes Description numbytes Number of bytes allocated for file system.

base_address Starting address for file system memory

init_type MFSINIT_NEW (default) or MFSINIT_IMAGE or MFSINIT_ROM_IMAGE

MFSINIT_NEW creates a new, empty file system MFSINIT_ROM_IMAGE creates a file system based on a pre- loaded memory image loaded in memory of size numbytes at starting address base_address. This memory is considered read- only and modification of the file system is not allowed. MFS_INIT_IMAGE is similar to the previous option except that the file system can be modified, and the memory is considered to be readable and writeable. need_utils true or false (default = false) If true, this causes stdio.h to be included from mfs_config.h. The functions described in the “Utility Functions” section require stdin or stdout to be defined, and setting need_utils to true causes stdio.h to be included. Caution! The underlying software and hardware platforms must support stdin and stdout peripherals for these utility functions to compile and link correctly.

EDK OS and Libraries Reference Guide www.xilinx.com 145 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 9: LibXil Memory File System (MFS)

146 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 10

LibXil Profile

This chapter describes the profiling library for embedded processors, libXil Profile. The chapter contains the following sections: x “Overview” x “Features” x “Profiling Model” x “Customizing xilprofile” x “Building Applications” x “Generating GPROF Files” x “XilProfile Code Description” x “Limitations”

Overview Profiling a program running on hardware (board), provides insight into program execution and identifies where it spends most time. Profiling on hardware is faster and the interaction of program with memory and other peripherals can be more accurately captured. LibXil Profile is a software intrusive profile library that generates Call Graph and Histogram information of program running on board. Executing the program on hardware generates the profiling information which is stored on the hardware. XMD generates output file from the data, which can be read by GNU gprof tools (mb-gprof) to generate the profiling information.Profiling is supported for the MicroBlaze processor.

Features LibXil Profile library has the following features: x Provides Histogram (flat profile) and Call Graph information. i Histogram: Shows how much time the program spent in each function and how many times the function was called. i Call Graph: Shows for each function, which functions called it, which other functions it called and how many times. x Profiling parameters are configurable - Sampling Frequency, Histogram Bin Size and Timer to use. x Memory location and size to store profiling is flexible and configurable based on program requirements.

EDK OS and Libraries Reference Guide www.xilinx.com 147 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 10: LibXil Profile

Profiling Model The libxil profile library, libxilprofile.a is generated and customized for software platform by instantiating the xilprofile library. Running LibGen will create this library. For more details of Profiling flow refer to the “Profiling Embedded Designs” chapter in the Platform Studio User Guide. When the profile option -pg is specified to the compiler (mb-gcc and powerpc-eabi-gcc), this library is automatically linked with the application to profile. The generated executable file contains code to generate profile information. When the program is executed on board, the profile information is stored at the memory location specified by the user. XMD is profile library “aware” and generates the gprof compatible output file based on profile data. Note: The xilprofile library does not have any explicit application API. The library is linked due to profile calls (_mcount) introduced by gcc for profiling. The are some global variables that need to be set in the application for using the library. This is explained in the later sections.

Customizing xilprofile The xilprofile library can be customized for an application. Following is the list of PARAMETERS for the library.

Table 10-1: xilprofile Custom PARAMETERS Name Type Defaults Description histogram_binsize int 4 For Histogram calculation, the program is divided into equal sized bins. This parameter specifies the bin size in bytes. This depends on function size. histogram_sample_freq_hz int 100,000 Frequency of sampling for histogram calculation. This determines the accuracy of histogram calculation. histogram_timer peripheral none The opb_timer instance name to use for instance name profiling in the system. callgraph_no_funcptr boolean false If there is no function pointer in the program, xilprofile uses a method which requires less memory. Setting this parameter to TRUE enables this mode of operation.

Building Applications The memory needed for storing profile information is allocated in the user application. The memory can be either an array allocated in program or any memory in the hardware system. The latter gives the flexibility to specify any available memory in the system without changing the program’s size or custom linker script. This memory is specified to xilprofile library by two pointer variables in the application. x char *memstart - Points to start of memory location. x char *memend - Points to end of memory location.

148 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Generating GPROF Files R

Application Memory Requirements The memory needed for profiling is dependent on the program’s text section size, number of function calls, and presence of function calls. The user can calculate the memory required for profiling by using the TCL file calc_profilemem.tcl Syntax: calc_profilemem.tcl -target -elf -bin Usage: xmd calc_profilemem.tcl -target mblaze -elf executable.elf -bin 4 xilprofile library assumes that the amount of memory allocated is correct and sufficient for the application. This is done to conserve valuable memory. XMD uses the same algorithm to perform memory testing during program download.

Generating GPROF Files XMD helps in the generation of output files that can be read by GNU gprof tools. XMD does the following functions for profiling. 1. Test if the amount of memory is sufficient for profiling. This test is done when the ELF file is downloaded and is compiled with the -pg option. 2. Read the stored profile information from hardware and generate output files. This is done by the following XMD command. Syntax: profile out [-o If output gmon file is not specified, file gmon.out is generated. Sample Profiling Session using XMD: Xilinx Microprocessor Debug (XMD) Engine Xilinx EDK 6.2 Build EDK_Gm.8 Copyright (c) 1995-2002 Xilinx, Inc. All rights reserved. XMD% mbconnect mdm JTAG chain configuration ------Device ID Code IR Length Part Name 1 0124a093 10 XC2VP7 Assuming, Device No: 1 contains the MicroBlaze system Connected to the JTAG MicroBlaze Debug Module (MDM) No of processors = 1

MicroBlaze Configuration : ------Version...... 2.00.a No of PC Breakpoints...... 4 No of Read Addr/Data Watchpoints...1 No of Write Addr/Data Watchpoints..1 Instruction Cache Support...... off Data Cache Support...... off

Connected to MicroBlaze "mdm" target. id = 0 Starting GDB server for "mdm" target (id = 0) at TCP port no 1234 XMD% dow microblaze_0/code/executable.elf

**************************************************************** ** Profiling Memory Test ** Executable: microblaze_0/code/executable.elf ** Memory Allocated: 4200

EDK OS and Libraries Reference Guide www.xilinx.com 149 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 10: LibXil Profile

** Profile Type: PROFILE_FUNCPTR ** Histogram BinSize: 4 **************************************************************** Program Text Size...... 5232 No. of Func. Calls...... 33 No. of Func. Ptr. Calls...... 3 Memory Histogram Tables...... 654 Memory Call Graph Tables...... 864

Total Profile Memory required...... 1518[SUCCESS] XMD% bps 0x470 Setting breakpoint at 0x00000470 XMD% con Processor started. Type "stop" to stop processor RUNNING> stop XMD% profile out Processor stopped at PC: 0x0000177c Profile data written to gmon.out XMD% GNU gprof tool (mb-gprof) tools can be used to read the output file. Refer to the Manual page of gprof for more information on usage.

XilProfile Code Description XilProfile source code is located at $XILINX_EDK/sw/lib/sw_services/xilprofile_v1_00_a directory. Some of the important functions are: x _program_init - This function is called before function main of an application. This function does memory and timer initialization. It allocates memory for histogram (inferred from symbols _ftext and _etext) and call graph based on xilprofile parameters. It initializes the timer routine, registers timer handler accordingly based on timer used and connection to processor and starts the timer. The TCL routine of xilprofile library figures the timer type and connection to processor and generates the #defines. Refer to the “Microprocessor Library Definition (MLD)” chapter in the Embedded System Tools Guide. x mcount - This function is called by _mcount function, which is inserted at every function start by gcc. This function records the caller and callee information (Instruction address), which is used to generate call graph information. Based on whether function pointers are present or not, different information is stored. This is done to decrease memory needed for profiling if there are no function pointers in the application. x profile_intr_handler - This is the interrupt handler for the profiling timer. The timer is set to sample the executing application for PC values at fixed intervals and increment the Bin count. This is used to generate the histogram information. To generate profile output, XMD needs to read xilprofile customization parameters value, profile memory location on the hardware, and actual profile data. XMD does this with the help of global variables in the xilprofile code. The following are the variables used. x memstart, memend - determines the profile memory used. x binsize - determines the Histogram BIN size used. x sample_freq_hz - determines the Sampling Frequency used. x profile_no_funcptr - determines the method used for call graph.

150 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 Limitations R

x _gmonparam - Data stored during profiling and information about the data. Refer profile.h file for more details on this structure.

Limitations The profiled program (text section) should exist as contiguous memory.

EDK OS and Libraries Reference Guide www.xilinx.com 151 UG114 (v3.0) August 20, 2004 1-800-255-7778 R Chapter 10: LibXil Profile

152 www.xilinx.com EDK OS and Libraries Reference Guide 1-800-255-7778 UG114 (v3.0) August 20, 2004 R Chapter 11 lwIP Library

Overview This chapter describes the Embedded Development Kit (EDK) port of the third party network library, Light Weight IP (lwIP), for embedded processors. The chapter details the port of the lwIP library for PowerPC and MicroBlaze processors. It contains the following sections: x “Overview” x “PowerPC System” x “MicroBlaze System” x “Setting Up lwIP in EDK” x “Designing an lwIP Application” x “Example lwIP Application” lwIP is an open source implementation of the TCP/IP protocol suite. The lwIP library supports two interfaces - raw API, BSD style Sockets API. EDK has been ported to work with the raw API interface of the library. The features of the lwIP library are : x IP (Internet Protocol) including packet forwarding on multiple interfaces x ICMP (Internet Control Message Protocol) x UDP (User Datagram Protocol) x TCP (Transmission Control Protocol) x .Raw API interface support for applications The raw API provided by lwIP is the lowest level interface of the stack. It has two modes of operation : Event and Callback. The EDK port uses the Callback mode. lwIP stack maintains internal timers for TCP round trip calculations, retransmissions and other TCP facilities. For this purpose, the lwIP timer functions must be called periodically. This is achieved by using the 64-bit hardware timer in PowerPC. For MicroBlaze an external timer is required. The system design involved for both MicroBlaze and PowerPC are discussed in the following sections.

PowerPC System Figure 11-1 shows an example hardware design of a PowerPC based system for lwIP. The system requires a 10/100 ethernet core for performing the network transactions. The built- in hardware timer is used to call the lwIP timer functions periodically.

EDK OS and Libraries Reference Guide www.xilinx.com 153 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

PLB OPB

SDRAM 10/100 DSPLB MEMC Ethernet ISPLB INT

BRAM 32 KB UART MEMC BRAM 16450 PPC405 Non-Crit PLB2OPB INTC BRIDGE

GPIO

UG114_11_01_051404

Figure 11-1: PowerPC System Design for lwIP-Based Echo Server

MicroBlaze System MicroBlaze does not support an in-built timer. An OPB based timer provides the timer functionality. The system uses the OPB based 10/100 regular ethernet core. A diagram of an example MicroBlaze system design is shown in Figure 11-2.

OPB

SDRAM MEMC MICROBLAZE ILMB DLMB 10/100 ILMB Ethernet DLMB IOPB MDM DOPB

Interrupt GPIO

UART BRAM 32K BRAM 16550 MEMC BRAM MEMC OPB TIMER

UG114_11_02_051404

Figure 11-2: MicroBlaze System Design for lwIP-Based Echo Server

154 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Memory Management R

Memory Management There are two types of memory management in lwIP; the heap memory (mem) and the static memory pools (memp). The pbuf management is a hybrid since it both manages its own memory (th pbuf pool) and uses the heap (mem). The mem is a heap memory manager, such as the C malloc/free manager. A block of memory is requested with a call to mem_malloc( ) and the memory is freed with a call to mem_free( ). This is used by code that allocates memory of different sizes. An example is when contents of a packet needs to be copied into a buffer - since the size of the packet isn’t known beforehand, the memory is allocated from the heap. The memp, on the other hand, uses a set of pools of fixed size memory blocks. This is used by the lwIP stack code to allocate predefined memory blocks. An example is for lwIP stack to allocate memory for TCP protocol control blocks. The pbufs are used to hold packet data. These are to be used by a network device driver who needs to allocate buffers quickly. The memory options are defined in lwipopts.h file. The memory options in lwipopts.h are as follows:

Table 11-1: Memory Option Settings for lwIP Option Name Description MEM_SIZE The size of the heap. If the application will send a lot of data that needs to be copied, this should be set high. MEMP_NUM_PBUF The number of memp struct pbufs. If the application sends a lot of data out of ROM (or other static memory), this should be set high. MEMP_NUM_UDP_PCB The number of UDP protocol control blocks. One per active UDP "connection." MEMP_NUM_TCP_PCB The number of simultaneously active TCP connections. MEMP_NUM_TCP_PCB_LISTEN The number of listening TCP connections. MEMP_NUM_TCP_SEG The number of simultaneously queued TCP segments.

Setting Up lwIP in EDK lwIP is customized using the libgen tool. lwIP supports multiple 10/100 ethernet network interfaces. The 48-bit MAC addresses associated with each of the interfaces are given along with the ethernet instances used in the MHS file. In order to set up lwIP library in XPS, open the software settings dialog. Select lwip 1.00.a library and click on the Library/OS Parameters tab. Enter the 10/100 ethernet instance names from the MHS file that would be used with the lwIP library. For each of the ethernet instance, a 48-bit MAC address is also specified. The following is an MSS snippet for lwIP library : BEGIN LIBRARY PARAMETER LIBRARY_NAME = lwip PARAMETER LIBRARY_VER = 1.00.a PARAMETER EMAC_INSTANCES = ((my_opb_ethernet,0x00,0x00,0x00,0x00,0x22,0x38))

EDK OS and Libraries Reference Guide www.xilinx.com 155 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

END

Running libgen tool in XPS generates liblwip4.a library in /lib directory in the project area. Applications designed with lwIP should link with this library to get the lwIP functionality. To link a library, open the Compiler options for the application and in the Linker Options, set lwip4 as a library to be used for linking.

libgen Customization lwIP library is customized through libgen tool. Here is a snippet from system.mss file for specifying lwIP library. BEGIN LIBRARY PARAMETER LIBRARY_NAME = lwip PARAMETER LIBRARY_VER = 1.00.a PARAMETER EMAC_INSTANCES = ((my_opb_ethernet,0x00,0x0A,0x35,0x00,0x22,0x20)) END

lwIP has the infrastructure to support multiple ethernet interfaces. The parameter emac_instances is an array. It takes in the instance name of an ethernet core (specified in the MHS file) and the 48-bit MAC address corresponding to it. This configures lwIP to use a particular ethernet instance with the 48-bit MAC address.

Table 11-2: Configurable Parameters for lwIP in MSS Parameter Name Description emac_instances This is an array with parameters emac_instname and the ethernet addresses.This is a list of ethernet instances that are to be used with lwIP. emac_instname Name of the ethernet instance from the MHS file eth_addr0 First byte of the 6-byte MAC address eth_addr1 Second byte of the 6-byte MAC address eth_addr2 Third byte of the 6-byte MAC address eth_addr3 Fourth byte of the 6-byte MAC address eth_addr4 Fifth byte of the 6-byte MAC address eth_addr5 Sixth byte of the 6-byte MAC address

Designing an lwIP Application Software applications using lwIP should follow certain structure. As mentioned in the previous sections, the lwIP stack requires its timer function to be called periodically. For PowerPC, the in-build timer is used to calculate the time period. In case of MicroBlaze an external timer is used for providing fixed time periods. For more information on lwIP refer : http://savannah.nongu.org/projects/lwip.

156 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Designing an lwIP Application R

Initializing lwIP lwIP requires the application to call several initialization routines. The following is a code snippet that illustrates the initialization routines required for lwIP. /***************************************************************

* CalllwIP Initialization Routines *****************************************************************/ sys_init(); mem_init(); memp_init();

pbuf_init(); netif_init();

tcp_init(); /***************************************************************

* Setup our 1 network interface (netif)*************************************************************** **/ netif = netif_add(&ip_addr, &net_mask, &gw, &XEmacIF_ConfigTable[0], xemacif_init, ip_input); netif_set_default(netif);

An example application is discussed in later sections to illustrate these requirements

lwIP Raw API The raw API of lwIP is the lowest level interface to the stack. It is also the most efficient interface because it provides direct access to the stack rather than providing extra buffering and message passing features. The following sections describe the most used interface functions. A more detailed description of the raw API is found in the lwIP source tree ($XILINX_EDK/sw/lib/sw_services/lwip_v1_00_a/src/lwip/doc/rawapi.txt). Asynchronous network events (data received, connection established etc.) are communicated to the application through callback functions. These callbacks are registered during the initialization of the TCP connection using the raw API. Table 6-2 lists the events and associated callback routines.

Table 11-3: TCP Events, Callbacks, and Hot to Register Callback Events Event Callback Register with lwIP TCP connection established *accept() tcp_accept() TCP Data Acknowledged *sent() tcp_sent() by Remote Host TCP Data Received *recv() tcp_recv()

The following section, “Raw API Functions for TCP,” lists a subset of TCP related functions. For a complete list of functions for other protocols, see: ($XILINX_EDK/sw/lib/sw_services/lwip_v1_00_a/src/lwip/doc/rawapi.txt)

EDK OS and Libraries Reference Guide www.xilinx.com 157 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

Function Summary

Table 11-4: Summary of lwIP Functions Functions void* tcp_init () void tcp_tmr() struct tcp_pcb * tcp_new() err_t tcp_bind (struct tcp_pcb* pcb, struct ip_addr* ip_addr, u16_t port) struct tcp_pcb* tcp_listen (struct tcp_pcb* pcb) void tcp_accept (struct tcp_pcb* pcb, err_t (*accept)(void* arg, struct tcp_pcb* newpcb, err_t err)) err_t tcp_write (struct tcp_pcb* pcb, void* dataptr, u16_t len, u8_t copy) void tcp_sent (struct tcp_pcb* pcb, err_t (*sent)(void* arg, struct tcp_pcb* tpcb, u16_t len)) void tcp_recv (struct tcp_pcb* pcb, err_t (*recv)(void* arg, struct tcp_pcb* tpcb, struct pbuf* p, err_t err))

Raw API Functions for TCP

void* tcp_init () This function must be called first to initialize the lwIP stack

void tcp_tmr() This function must be called every TCP_TMR_INTERVAL milliseconds (defined in file lwipopts.h). There are two lower level timer functions which are called inside tcp_tmr( ). The example application calls these functions directly - they are: tcp_slowtmr( ) and tcp_fasttmr( ).

struct tcp_pcb * tcp_new() tcp_new creates a new TCP Protocol Control Block (PCB) structure.

158 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Raw API Functions for TCP R

void tcp_arg (struct tcp_pcb* pcb, void* arg) tcp_arg Allows the application to register an argument that will be passed back to the application for all callback functions. This argument, arg, is usually used as a pointer to a structure that holds application state information.

err_t tcp_bind (struct tcp_pcb* pcb, struct ip_addr* ip_addr, u16_t port) Binds the pcb to an IP address, ip_addr and TCP port number port

struct tcp_pcb* tcp_listen (struct tcp_pcb* pcb) The tcp_listen function instructs the lwIP stack to put the pcb in listen state. The pcb will start to listen for connections on the IP address and port number specified in tcp_bind. When a new connection is established, lwIP calls the callback application function specified using the tcp_accept function.

void tcp_accept (struct tcp_pcb* pcb, err_t (*accept)(void* arg, struct tcp_pcb* newpcb, err_t err)) The tcp_accept function allows the application to register a callback function, accept. The lwIP stack calls the accept function when a new connection is established on a pcb that is in the listening state.

err_t tcp_write (struct tcp_pcb* pcb, void* dataptr, u16_t len, u8_t copy) The tcp_write function will write len bytes of data from dataptr to the transmit queue. The copy argument specifies whether or not the stack should copy the data or reference it using the pointer dataptr.

void tcp_sent (struct tcp_pcb* pcb, err_t (*sent)(void* arg, struct tcp_pcb* tpcb, u16_t len)) The tcp_sent function registers the sent callback function. The lwIP stack calls the sent function when data is acknowledged by the remote host. The len argument indicates the number of bytes acknowledged. Once the bytes are acknowledged, the bytes are removed from the transmit buffer creating more space. This is useful when trying to send large amount of data using lwIP. If the tcp_write function fails because the transmit buffer is full, this callback function allows the application to write additional data once buffer space becomes available.

EDK OS and Libraries Reference Guide www.xilinx.com 159 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

void tcp_recv (struct tcp_pcb* pcb, err_t (*recv)(void* arg, struct tcp_pcb* tpcb, struct pbuf* p, err_t err)) The tcp_recv function registers the recv callback function. The lwIP stack calls the recv function when new data arrives on the connection. The p argument is NULL when the connection is closed.

Example lwIP Application The following is a simple TCP based echo server application. The echo server is listening for connections on port 7, and echoes the data sent by the client. The following sections discuss the application run on both PowerPC and MicroBlaze.

PowerPC based Echo Server The hardware system for the example is shown in Figure 11-1. Assign drivers to each of these peripherals. Select lwip library as shown before and configure the library with the ethernet instance name and the 6-byte MAC address. The lwip library, liblwip4.a, gets generated in /lib/ directory once libgen is run.

C Program

The application is split among the following C and header files.

FileName : echo_main.c /*

. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" . * SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR . * XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION

. * AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION . * OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS . * IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, . * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE . * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY

. * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE . * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR . * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF . * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS . * FOR A PARTICULAR PURPOSE. *

. * (c) Copyright 2002, 2003 Xilinx, Inc. . * All rights reserved. * */

/*

. * Copyright (c) 2001, 2002, 2003 Swedish Institute of Computer Science.

160 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

. * All rights reserved. *

. * Redistribution and use in source and binary forms, with or without . * modification, are permitted provided that the following conditions . * are met: *

. * 1. Redistributions of source code must retain the above copyrightnotice,

. * this list of conditions and the following disclaimer.

. * 2. Redistributions in binary form must reproduce the above copyright notice,

. * this list of conditions and the following disclaimer in the documentation

. * and/or other materials provided with the distribution.

. * 3. The name of the author may not be used to endorse or promoteproducts

. * derived from this software without specific prior written

permission. *

. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ‘‘AS IS’’ AND ANY EXPRESS OR

. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES

. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN

. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL,

. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED

. * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR

. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS . * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */

/* Xilinx Includes */ #include "xuartns550_l.h" #include "xtime_l.h" #include "xparameters.h"

EDK OS and Libraries Reference Guide www.xilinx.com 161 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

#include "xcache_l.h" #include "xgpio_l.h"

/* lwIP Includes */ #include "netif/xemacif.h" #include "lwip/tcp.h" #include "lwip/memp.h" #include "netif/etharp.h"

#include "echo.h"

#define UART_BASEADDR XPAR_MYUART_16550_BASEADDR #define UART_CLOCK (XPAR_XUARTNS550_CLOCK_HZ) #define UART_BAUDRATE (115200)

#define LWIP_TIMER_CYCLES (XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ / 1000 \

* TCP_TMR_INTERVAL ) // Upper 6 bytes of MAC - Xilinx Ethernet OUI = 00-0A-35 #define XILINX_MAC_OUI0 0x00 #define XILINX_MAC_OUI1 0x00 #define XILINX_MAC_OUI2 0x00

static void show_dotted_decimal( char * address_array); static void show_dashed_hex( int bytes, char *address_array);

// Static Global Variables static u8_t my_timer = 0;

// External Global Variables

/* defined in lwip/src/core/tcp.c */ extern u32_t tcp_ticks; /* defined in EDK generated xemacif_g.c file */ extern XEmacIf_Config XEmacIf_ConfigTable[];

/*------*/

* show dotted decimal prints a dotted decimal address to the UART*------*/ static void show_dotted_decimal( char *address_array) {

int bb; char temp;

for(bb=0;bb<4;bb++)

{ temp = address_array[bb]; if(bb!=0) xil_printf("."); xil_printf("%d", (int) temp);

} }

/*------*/ /* show dashed hex prints a dashed hex address to the UART */ /*------*/

162 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

static void show_dashed_hex( int bytes, char *address_array) {

//Assumes the caller passes the correct number of bytes int bb;

for(bb=0;bb

{ if(bb !=0) xil_printf("-"); xil_printf("%02X", (int) address_array[bb]);

} }

/*------*/ /* my_tmr - Called Periodically to dispatch TCP and ARP timers */ /*------*/ void my_tmr(void) {

++my_timer;

if(my_timer == 10) {

my_timer = 0; } if(my_timer & 1) {

/* Call tcp_fasttmr() every 2 ms, i.e.,

* every other timer my_tmr() is called. */ tcp_fasttmr(); } if(my_timer == 0 || my_timer == 5) {

/* Call tcp_slowtmr() every 5 ms, i.e.,

* every fifth timer my_tmr() is called. */ tcp_slowtmr(); if (tcp_ticks%2000 == 0)

/* Call etharp_tmr() every 20th call to tcp_slowtmr().

* tcp_ticks is a global var defined in core/tcp.c */ etharp_tmr(); } }

/*------*/ /* print_app_header - prints the legal header */ /*------*/ void print_app_header() {

xil_printf("\n\n\n\n\n\n\n\n\n");

xil_printf("########################################################## ##########

EDK OS and Libraries Reference Guide www.xilinx.com 163 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

\n");

xil_printf("# Xilinx TCP/IP Demo Application (ECHO Server) #\n"); xil_printf("# \n"); xil_printf("# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION

’AS IS’ #\n"); xil_printf("# SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR # \n"); xil_printf("# XILINX DEVICES. # \n"); xil_printf("# # \n"); xil_printf("# (c) Copyright 2003, 2003 Xilinx, Inc. # \n"); xil_printf("# All rights reserved. # \n"); xil_printf("# # \n");

xil_printf("########################################################## ########## \n"); }

/*------*/ /* main function */ /*------*/ int main_main () {

struct tcp_pcb *gddpp_pcb; struct ip_addr ipaddr, netmask, gw; struct netif *default_netif; char menu_select = 0; XTime ml_base, ml_new, ml_offset; int waiting_for_timer = 1; char low_mac[3] = {0x00,0x22,0x38}; char fullmac[6] = {XILINX_MAC_OUI0, XILINX_MAC_OUI1,

XILINX_MAC_OUI2,

low_mac[0], low_mac[2], low_mac[3]}; char ip[4] = {149,199,6,108}; char subnet[4] = {255,255,255,0}; char gateway[4] = {149,199,6,254};

unsigned int init_wait = 15000000;

/*------

* Uart Init* *------*/

/* Disable Interrupts */ XIo_Out8(UART_BASEADDR + XUN_LCR_OFFSET, 0UL);

164 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

XIo_Out8(UART_BASEADDR + XUN_IER_OFFSET, 0UL);

/* Clear Latches */ XIo_In8(UART_BASEADDR + XUN_LSR_OFFSET); XIo_In8(UART_BASEADDR + XUN_IIR_OFFSET); XIo_In8(UART_BASEADDR + XUN_MSR_OFFSET);

/* Disable FIFOs (16450) */ XIo_Out8(UART_BASEADDR + XUN_FCR_OFFSET, 0UL);

/* Normal ABQ level 0 driver inits */ XUartNs550_SetBaud(UART_BASEADDR, UART_CLOCK, UART_BAUDRATE); XUartNs550_mSetLineControlReg(UART_BASEADDR, XUN_LCR_8_DATA_BITS);

/* Sets DTR, RTS, and OUT2 in the MCR */ XIo_Out8(UART_BASEADDR + XUN_MCR_OFFSET, XUN_MCR_OUT_2 | XUN_MCR_RTS | XUN_MCR_DTR);

xil_printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n"); xil_printf("Starting Up... \n"); xil_printf("Console: 16550 initialized. \n");

/*------*/

/* Timer Inits */ /*------*/ ml_offset = LWIP_TIMER_CYCLES;

/*------*/

/* Do LWIP System Inits */ /*------*/ #ifdef STATS

stats_init(); #endif /* STATS */ xil_printf("Initializing Memory Structures."); sys_init(); mem_init(); xil_printf("."); memp_init(); xil_printf(".");

pbuf_init(); xil_printf(" done. \n");

// clear UART Receive Buffer while (XUartNs550_mIsReceiveData(UART_BASEADDR)) { XUartNs550_RecvByte(UART_BASEADDR); }

// set GPIO I/O Mask XGpio_mSetDataDirection(XPAR_MYGPIO_BASEADDR, 0x00000FFF);

EDK OS and Libraries Reference Guide www.xilinx.com 165 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

// Turn on 4 LEDs (Active Low) XGpio_mSetDataReg(XPAR_MYGPIO_BASEADDR, 0x00000000);

/*------*/ /* Initial Header and Menus. Do this before the netif_init() so */ /* we can change the MAC Address and IP addresses if needed */ /*------*/ while(init_wait--); print_app_header(); fullmac[0] = XILINX_MAC_OUI0; fullmac[1] = XILINX_MAC_OUI1; fullmac[2] = XILINX_MAC_OUI2; fullmac[3] = low_mac[0]; fullmac[4] = low_mac[1]; fullmac[5] = low_mac[2];

/*------*/

/* Set host addresses */ /*------*/ xemacif_setmac(0, (u8_t *) fullmac); //Set MAC IP4_ADDR(&gw, gateway[0],gateway[1],gateway[2],gateway[3]); //Set

gateway IP4_ADDR(&ipaddr, ip[0],ip[1],ip[2],ip[3]); //Set ip IP4_ADDR(&netmask,subnet[0],subnet[1],subnet[2],subnet[3]); //Set

subnet msk

/*------*/

/* Show some host boot stuff and parameters */ /*------*/ xil_printf("

\nStarting Network Interface... \n");

xil_printf(" MAC Address: "); show_dashed_hex(6, fullmac); xil_printf(" \n");

xil_printf(" IP Address: "); show_dotted_decimal(ip); xil_printf(" \n");

xil_printf(" Subnet Mask: "); show_dotted_decimal(subnet); xil_printf(" \n");

xil_printf(" Gateway IP: "); show_dotted_decimal(gateway); xil_printf(" \n");

xil_printf(" Echo Port: 7

\n");

166 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

/*------*/

/* Initialize netif */ /*------*/ netif_init();

/*------*/

/* Initialize TCP Stack */ /*------*/ tcp_init();

/*------*/

/* Set up the lwIP network interface... */ /*------*/ default_netif = netif_add(&ipaddr,

&netmask, &gw,

&XEmacIf_ConfigTable[0], xemacif_init, ip_input );

netif_set_default(default_netif);

/*------*/ /* create new tcp pcb and start applications */ /*------*/

// Start the Server xil_printf("Echo Server Running ... "); xil_printf(" \n"); echo_init();

// Get the current Time-Base Register Value // offset it by ml_offset XTime_SetTime(0); XTime_GetTime(&ml_base); ml_base += ml_offset;

while (1) {

while (waiting_for_timer) { xemacif_input(default_netif); XTime_GetTime(&ml_new); if ( ml_new >= ml_base ) {

waiting_for_timer = 0; ml_base = ml_new + ml_offset;

} } // Call my_tmr() every ml_offset cycles my_tmr(); waiting_for_timer = 1;

EDK OS and Libraries Reference Guide www.xilinx.com 167 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

} return (1); }

int main () {

/*------*/ /* Enable instruction and data cache -this must be done first because */ /* the Memec Design Virtex-II Dev Boards (rev1 and rev2) have the

SDRAM */ /* byte enables tied together on the board. Enabling the caches */ /* guarantees that all memory accesses are 32-bit aligned. */ /*------*/ XCache_EnableICache(0x80000001); XCache_EnableDCache(0x80000001); return main_main();

}

FileName : echo.c /*

. * Copyright (c) 2001-2003 Swedish Institute of Computer Science. . * All rights reserved. *

. * Redistribution and use in source and binary forms, with or withoutmodification,

. * are permitted provided that the following conditions are met: *

. * 1. Redistributions of source code must retain the above copyrightnotice,

. * this list of conditions and the following disclaimer.

. * 2. Redistributions in binary form must reproduce the above copyright notice,

. * this list of conditions and the following disclaimer in the documentation

. * and/or other materials provided with the distribution.

. * 3. The name of the author may not be used to endorse or promoteproducts

. * derived from this software without specific prior written

permission. *

168 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ‘‘AS IS’’ AND ANY EXPRESS OR IMPLIED

. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT

. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL,

. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT

. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ORBUSINESS

. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OROTHERWISE) ARISING

. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY

. * OF SUCH DAMAGE. *

. * This file is part of the lwIP TCP/IP stack. *

. * Author: Adam Dunkels

* */

#include "lwip/debug.h" #include "lwip/stats.h" #include "lwip/tcp.h" #include "xparameters.h" #include "echo.h"

struct echo_state { struct pbuf *p; u8_t failed;

#define FAILED_MAX 8 }; /*------*/ static void echo_err(void *arg, err_t err) {

struct echo_state *es = arg;

xil_printf("echo_err \n");

if(arg != NULL) { pbuf_free(es->p);

EDK OS and Libraries Reference Guide www.xilinx.com 169 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

mem_free(arg);

} } /*------*/ static void close_conn(struct tcp_pcb *pcb, struct echo_state *es) {

tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); if(es != NULL) {

pbuf_free(es->p);

mem_free(es); } tcp_close(pcb); xil_printf("Connection Closed

\n"); } /*------*/ static void send_buf(struct tcp_pcb *pcb, struct echo_state *es) {

struct pbuf *q;

do { q = es->p; es->p = pbuf_dechain(q); if(tcp_write(pcb, q->payload, q->len, 1) == ERR_MEM) {

pbuf_chain(q, es->p); es->p = q; return;

} tcp_recved(pcb, q->len); pbuf_free(q);

} while(es->p != NULL); } /*------*/ static err_t echo_poll(void *arg, struct tcp_pcb *pcb) {

struct echo_state *es;

if(arg == NULL) { return tcp_close(pcb); }

es = arg;

170 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

if(es->failed >= FAILED_MAX) { close_conn(pcb, es); tcp_abort(pcb); return ERR_ABRT;

}

if(es->p != NULL) { ++es->failed; send_buf(pcb, es);

}

return ERR_OK; } /*------*/ static err_t echo_sent(void *arg, struct tcp_pcb *pcb, u16_t len) {

struct echo_state *es;

es = arg;

if(es != NULL && es->p != NULL) {

send_buf(pcb, es); } return ERR_OK;

} /*------*/ static err_t echo_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {

struct echo_state *es;

es = arg;

if(p == NULL) { close_conn(pcb, es); return ERR_OK;

}

if(es->p != NULL) { pbuf_chain(es->p, p); } else { es->p = p;

}

send_buf(pcb, es);

return ERR_OK; } /*------*/ static err_t

EDK OS and Libraries Reference Guide www.xilinx.com 171 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

echo_accept(void *arg, struct tcp_pcb *pcb, err_t err) {

struct echo_state *es;

tcp_setprio(pcb, TCP_PRIO_MIN);

/* Allocate memory for the structure that holds the state of the connection. */ es = mem_malloc(sizeof(struct echo_state));

if(es == NULL) { xil_printf("could not malloc memory for echo_state \n"); return ERR_MEM; }

/* Initialize the structure. */ es->p = NULL; es->failed = 0;

/* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, es);

/* Tell TCP that we wish to be informed of incoming data by a call

to the http_recv() function. */ tcp_recv(pcb, echo_recv); tcp_err(pcb, echo_err); tcp_poll(pcb, echo_poll, 1);

xil_printf("Connection Established

\n");

return ERR_OK; } /*------*/ void echo_init(void) {

struct tcp_pcb *pcb;

pcb = tcp_new(); tcp_bind(pcb, IP_ADDR_ANY, ECHO_PORT); pcb = tcp_listen(pcb); tcp_accept(pcb, echo_accept);

} /*------*/

FileName : echo.h #ifndef LWIP_ECHO_H #define LWIP_ECHO_H

172 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

#define ECHO_PORT 7

void echo_init(void);

#endif

Linker script The linker script used with the above example. /********************************************************************* *

. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"

. * SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR

. * XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION

. * AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION

. * OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS

. * IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,

. * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE

. * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY

. * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE

. * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR

. * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF

. * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

. * FOR A PARTICULAR PURPOSE. *

. * (c) Copyright 2003 Xilinx, Inc.

. * All rights reserved. *

*********************************************************************/

_STACK_SIZE = 1024k; _HEAP_SIZE = 1024k;

MEMORY

{ sdram : ORIGIN = 0x00000000, LENGTH = 32M bram : ORIGIN = 0xFFFF8000, LENGTH = 32K - 4 boot : ORIGIN = 0xfffffffc, LENGTH = 4

EDK OS and Libraries Reference Guide www.xilinx.com 173 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

}

STARTUP(boot.o) ENTRY(_boot) GROUP(libxil.a libc.a)

SECTIONS { .vectors : { *(.vectors)

} > sdram

.text : { *(.text) } > sdram

.data :

{ *(.data) *(.got2) *(.rodata) *(.fixup)

} > sdram

/* small data area (read/write): keep together! */ .sdata : { *(.sdata) } > sdram

.sbss :

{ . = ALIGN(4); *(.sbss) . = ALIGN(4);

} > sdram

__sbss_start = ADDR(.sbss); __sbss_end = ADDR(.sbss) + SIZEOF(.sbss);

/* small data area 2 (read only) */ .sdata2 : { *(.sdata2) } > sdram

.bss :

{ . = ALIGN(4); *(.bss) *(COMMON) . = ALIGN(4);

__bss_end = .;

/* add stack and align to 16 byte boundary */ . = . + _STACK_SIZE; . = ALIGN(16); __stack = .; _heap_start = .;

174 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

. = . + _HEAP_SIZE; . = ALIGN(16); _heap_end = .;

} > sdram

__bss_start = ADDR(.bss); .boot0 :

{ *(.boot0) _end = .;

} > sdram

.boot : { *(.boot) } > boot

}

MicroBlaze-Based Echo Server The hardware system for the example is shown in Figure 11-2. Assign drivers to each of these peripherals. Select lwip library as shown before and configure the library with the ethernet instance name and the 6-byte MAC address. The lwip library, liblwip4.a, gets generated in /lib/ directory once libgen is run.

C Program

The application is split among the following C and header files.

FileName : echo_main.c /*

. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" . * SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR . * XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION

. * AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION . * OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS . * IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, . * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE . * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY

. * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE . * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR . * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF . * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS . * FOR A PARTICULAR PURPOSE. *

. * (c) Copyright 2002, 2003 Xilinx, Inc. . * All rights reserved. * */

/*

EDK OS and Libraries Reference Guide www.xilinx.com 175 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

. * Copyright (c) 2001, 2002, 2003 Swedish Institute of Computer Science.

. * All rights reserved. *

. * Redistribution and use in source and binary forms, with or without . * modification, are permitted provided that the following conditions . * are met: *

. * 1. Redistributions of source code must retain the above copyrightnotice,

. * this list of conditions and the following disclaimer.

. * 2. Redistributions in binary form must reproduce the above copyright notice,

. * this list of conditions and the following disclaimer in the documentation

. * and/or other materials provided with the distribution.

. * 3. The name of the author may not be used to endorse or promoteproducts

. * derived from this software without specific prior written

permission. *

. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ‘‘AS IS’’ AND ANY EXPRESS OR

. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES

. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN

. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL,

. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED

. * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR

. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS . * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */

176 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

/* Xilinx Includes */ #include "xuartns550_l.h" #include "xparameters.h" #include "xgpio_l.h" #include "xtmrctr_l.h"

/* lwIP Includes */ #include "netif/xemacif.h" #include "lwip/tcp.h" #include "lwip/memp.h" #include "netif/etharp.h"

#include "echo.h" #define UART_BASEADDR XPAR_MYUART_16550_BASEADDR #define UART_CLOCK (XPAR_XUARTNS550_CLOCK_HZ) #define UART_BAUDRATE (115200)

#define LWIP_TIMER_CYCLES (XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ / 1000 \

* TCP_TMR_INTERVAL ) // Upper 6 bytes of MAC - Xilinx Ethernet OUI = 00-0A-35 #define XILINX_MAC_OUI0 0x00 #define XILINX_MAC_OUI1 0x00 #define XILINX_MAC_OUI2 0x00

static void show_dotted_decimal( char * address_array); static void show_dashed_hex( int bytes, char *address_array);

// Static Global Variables static u8_t my_timer = 0; static int waiting_for_timer = 1;

/* defined in lwip/src/core/tcp.c */ extern u32_t tcp_ticks; /* defined in EDK generated xemacif_g.c file */ extern XEmacIf_Config XEmacIf_ConfigTable[];

/*------*/ // show dotted decimal prints a dotted decimal address to the UART /*------*/ static void show_dotted_decimal( char *address_array)

{ int bb; unsigned char temp;

for(bb=0;bb<4;bb++)

{ temp = address_array[bb]; if(bb!=0) xil_printf("."); xil_printf("%d", temp);

} }

EDK OS and Libraries Reference Guide www.xilinx.com 177 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

/*------*/ /* show dashed hex prints a dashed hex address to the UART */ /*------*/ static void show_dashed_hex( int bytes, char *address_array) {

//Assumes the caller passes the correct number of bytes int bb;

for(bb=0;bb

{ if(bb !=0) xil_printf("-"); xil_printf("%02X", (int) address_array[bb]);

} }

/*------*/ /* my_tmr - Called Periodically to dispatch TCP and ARP timers */ /*------*/ void my_tmr(void) {

++my_timer;

if(my_timer == 10) {

my_timer = 0; } if(my_timer & 1) {

/* Call tcp_fasttmr() every 2 ms, i.e.,

* every other timer my_tmr() is called. */ tcp_fasttmr(); } if(my_timer == 0 || my_timer == 5) {

/* Call tcp_slowtmr() every 5 ms, i.e.,

* every fifth timer my_tmr() is called. */ tcp_slowtmr(); if (tcp_ticks%2000 == 0)

/* Call etharp_tmr() every 20th call to tcp_slowtmr().

* tcp_ticks is a global var defined in core/tcp.c */ etharp_tmr();

} }

/*------*/ /* print_app_header - prints the legal header */ /*------*/ void print_app_header() {

xil_printf("\n\n\n\n\n\n\n\n

178 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

\n");

xil_printf("########################################################## ########## \n");

xil_printf("# Xilinx TCP/IP Demo Application (ECHO Server) # \n");

xil_printf("# # \n"); xil_printf("# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION

’AS IS’ # \n"); xil_printf("# SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR # \n"); xil_printf("# XILINX DEVICES. # \n"); xil_printf("# # \n"); xil_printf("# (c) Copyright 2003, 2003 Xilinx, Inc. # \n"); xil_printf("# All rights reserved. # \n"); xil_printf("# # \n");

xil_printf("########################################################## ########## \n"); }

/*------*/ /* main function */ /*------*/ int main_main () {

struct tcp_pcb *gddpp_pcb; struct ip_addr ipaddr, netmask, gw; struct netif *default_netif; char menu_select = 0;

char low_mac[3] = {0x00,0x22,0x38}; char fullmac[6] = {XILINX_MAC_OUI0, XILINX_MAC_OUI1, XILINX_MAC_OUI2,

low_mac[0], low_mac[2], low_mac[3]}; char ip[4] = {149,199,6,108}; char subnet[4] = {255,255,255,0}; char gateway[4] = {149,199,6,254}; int app_running = 0;

EDK OS and Libraries Reference Guide www.xilinx.com 179 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

unsigned int init_wait = 15000000;

/*------

* Enable microblaze interrupts *------*/

microblaze_enable_interrupts();

/*------

. * Timer and Intc Init *

. * Set the Timer to interrupt for every 100ms *------*/

/* set the number of cycles the timer counts before interrupting */

/* 100 Mhz clock => 100 us for 1 clk tick. For 100ms, 1000 clk ticks need to elapse */

XTmrCtr_mSetLoadReg(XPAR_OPB_TIMER_1_BASEADDR, 0, 10000);

/* reset the timers, and clear interrupts */

XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0, XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK );

/* start the timers */

XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);

/*------

* Uart Init*------*/

/* Disable Interrupts */

XIo_Out8(UART_BASEADDR + XUN_LCR_OFFSET, 0UL);

XIo_Out8(UART_BASEADDR + XUN_IER_OFFSET, 0UL);

/* Clear Latches */

XIo_In8(UART_BASEADDR + XUN_LSR_OFFSET);

XIo_In8(UART_BASEADDR + XUN_IIR_OFFSET);

XIo_In8(UART_BASEADDR + XUN_MSR_OFFSET);

/* Disable FIFOs (16450) */

XIo_Out8(UART_BASEADDR + XUN_FCR_OFFSET, 0UL);

/* Normal ABQ level 0 driver inits */ XUartNs550_SetBaud(UART_BASEADDR, UART_CLOCK, UART_BAUDRATE);

180 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

XUartNs550_mSetLineControlReg(UART_BASEADDR, XUN_LCR_8_DATA_BITS);

/* Sets DTR, RTS, and OUT2 in the MCR */ XIo_Out8(UART_BASEADDR + XUN_MCR_OFFSET, XUN_MCR_OUT_2 | XUN_MCR_RTS | XUN_MCR_DTR);

xil_printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n");

xil_printf("Starting Up... \n");

xil_printf("Console: 16550 initialized. \n");

/*------*/ /* Do LWIP System Inits */ /*------*/

#ifdef STATS stats_init();

#endif /* STATS */ xil_printf("Initializing Memory Structures."); sys_init(); mem_init(); xil_printf("."); memp_init(); xil_printf("."); pbuf_init(); xil_printf(" done.

\n");

// set GPIO I/O Mask XGpio_mSetDataDirection(XPAR_MYGPIO_BASEADDR, 0x00000FFF);

// Turn on 4 LEDs (Active Low) XGpio_mSetDataReg(XPAR_MYGPIO_BASEADDR, 0x00000000);

/*------*/ /* Initial Header and Menus. Do this before the netif_init() so we

can */ /* change the MAC Address and IP addresses if needed */ /*------*/ while(init_wait--); print_app_header();

fullmac[0] = XILINX_MAC_OUI0; fullmac[1] = XILINX_MAC_OUI1; fullmac[2] = XILINX_MAC_OUI2; fullmac[3] = low_mac[0]; fullmac[4] = low_mac[1]; fullmac[5] = low_mac[2]; /*------*/

/* Set host addresses */ /*------*/

EDK OS and Libraries Reference Guide www.xilinx.com 181 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

xemacif_setmac(0, (u8_t *) fullmac); //Set MAC IP4_ADDR(&gw, gateway[0],gateway[1],gateway[2],gateway[3]); //Set

gateway IP4_ADDR(&ipaddr, ip[0],ip[1],ip[2],ip[3]); //Set ip IP4_ADDR(&netmask,subnet[0],subnet[1],subnet[2],subnet[3]); //Set

subnet msk

/*------*/

/* Show some host boot stuff and parameters */ /*------*/ xil_printf("

\nStarting Network Interface... \n");

xil_printf(" MAC Address: "); show_dashed_hex(6, fullmac); xil_printf(" \n");

xil_printf(" IP Address: "); show_dotted_decimal(ip); xil_printf(" \n");

xil_printf(" Subnet Mask: "); show_dotted_decimal(subnet); xil_printf(" \n");

xil_printf(" Gateway IP: "); show_dotted_decimal(gateway); xil_printf(" \n");

xil_printf(" Echo Port: 7 \n");

/*------*/

/* Initialize netif */ /*------*/ netif_init();

/*------*/

/* Initialize TCP Stack */ /*------*/ tcp_init();

/*------*/

/* Set up the lwIP network interface... */ /*------*/ default_netif = netif_add(&ipaddr,

&netmask, &gw, &XEmacIf_ConfigTable[0], xemacif_init,

182 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004 Example lwIP Application R

ip_input

);

netif_set_default(default_netif);

/*------*/ /* create new tcp pcb and start applications */ /*------*/

// Start the Server xil_printf("Echo Server Running ... "); xil_printf("

\n"); echo_init(); app_running = 1;

while (1) { while (waiting_for_timer) {

xemacif_input(default_netif); } my_tmr(); waiting_for_timer = 1;

} return (1); }

int main ()

{ /*------*/ /* Enable instruction and data cache-this must be done first because */ /* the Memec Design Virtex-II Dev Boards (rev1 and rev2) have the SDRAM */ /* byte enables tied together on the board. Enabling the caches

*/ /* guarantees that all memory accesses are 32-bit aligned. */ /*------*/

return main_main(); }

void mytimer_int_handler (void* baseaddr_p) {

int baseaddr = *(int *)baseaddr_p; unsigned int csr; unsigned int gpio_data;

/* Read timer 0 CSR to see if it raised the interrupt */ csr = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);

if (csr & XTC_CSR_INT_OCCURED_MASK) {

EDK OS and Libraries Reference Guide www.xilinx.com 183 UG114 (v3.0) August 20, 2004 1-800-255-7778 Embedded Development Kit R Chapter 11: lwIP Library

//xil_printf("Timer Handler ...\n"); waiting_for_timer = 0;

/* Clear the timer interrupt */ XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0, csr); } }

FileName : echo.c echo.h These are the same files as used in the PowerPC example described above. For MicroBlaze design, the echo server application is set to start at 0x86000000 which is the start address of SDRAM. The entire design runs off the external memory.

184 www.xilinx.com EDK OS and Libraries Reference Guide Embedded Development Kit 1-800-255-7778 UG114 (v3.0) August 20, 2004