Top Banner
Project 6th semester - SS2006 May 26, 2006 HOWTO: NIOS-CPU with additional hardware driven with μClinux Caretaker: Prof. Dr.-Ing. M. Strahnen Peter Feuerer SID: 36635 Steffen Gutmann SID: 36614 Sascha Haensch SID: 34447 Ronny Schroeder SID: 36607 Hochschule Ulm Prittwitzstrasse 10 89075 Ulm
56

Nios2 uClinux Additional Hardware

Apr 12, 2015

Download

Documents

cointoin
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Nios2 uClinux Additional Hardware

Project6th semester - SS2006

May 26, 2006

HOWTO:NIOS-CPU with additional hardware driven

with µClinux

Caretaker: Prof. Dr.-Ing. M. Strahnen

Peter Feuerer SID: 36635Steffen Gutmann SID: 36614Sascha Haensch SID: 34447

Ronny Schroeder SID: 36607

Hochschule UlmPrittwitzstrasse 1089075 Ulm

Page 2: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux Contents

Contents

1 Introduction 21.1 Conceptual Formulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2 Disambiguation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 Used Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.3.1 Used Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.3.2 Used Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Course Of Action 62.1 Necessary Preparations and Rough Flow Chart . . . . . . . . . . . . . . . . . . . . . 6

3 Creating own Hardware 8

3.1 Conception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.2 Creating VHDL Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.3 Add custom hardware to the NIOS II processor . . . . . . . . . . . . . . . . . . . . . 11

4 Installing µClinux toolchain 27

4.1 Building the embedded µClinux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.1.1 µClinux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.1.2 setup the development system . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.1.3 adding a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.1.4 Download sources of microtronix’s nios2 linux . . . . . . . . . . . . . . . . . 28

4.1.5 Building the nios2 linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.1.6 set the path variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.2 configuring and compiling the kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4.3 Ready to start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

5 Programming kernel driver 34

5.1 Implementation of the driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5.1.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5.1.2 Defines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5.1.3 Function calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5.2 Adding device files to rootfs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.3 Adding driver to kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.4 Building the kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

6 User-space programs 37

6.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 1

Page 3: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux Contents

6.2 Using custom IO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

7 Using preinstalled VM 38

7.1 Linux host system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

7.2 Windows host system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

7.3 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

7.4 Moving data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

8 Summary 40

9 Addendum 41

A VHDL Code 42

B Kernel module code 46

C The Expansion Board 52

C.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

C.2 Bill Of Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

C.3 Connection between Expansion Board and Nios II Evaluation Kit . . . . . . . . . . . . 52

C.4 Schematic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

C.5 PCB-Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 2

Page 4: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 1 Introduction

1 Introduction

1.1 Conceptual Formulation

During the 6th semester of our studies in computer engineering at university of applied sci-ences Ulm we had to process a project which practiced us how software and hardware projectare realized. Our order was to expand a FPGA based Microcontroller and get µClinux runningon it. The final goal was to write a howto which describes the following tasks:

• Add a simple parallel I/O-device to the Nios II processor

• Customize µClinux to the modified processor

• Write a driver to control the I/O-device

Other people should be able to add their own VHDL specified hardware devices to a Nios IIprocessor after reading this document. They also should be able to write a device driver whichacts in the kernel space and can be accessed from the user space. Because we want to preventthe readers from running into the same traps as we did we also describes some problematicparts.

1.2 Disambiguation

In this howto we use some technical terms to describe the development process. Maybe notall of them are well known so we explain the most important of them.

FPGA A Field Programmable Gate Array (FPGA) is a semiconductor device containingprogrammable logic components and programmable interconnects. The programmablelogic components can be programmed to duplicate the functionality of basic logic gatessuch as AND, OR, XOR, NOT or more complex combinatorial functions such as de-coders or simple math functions. In most FPGAs, these programmable logic compo-nents also include memory elements, which may be simple flip-flops or more completeblocks of memories.

Nios II The Nios II is a soft-core embedded processor manufactured by Altera. Soft-coremeans that FPGA developers can choose from a myriad of system configurations, pick-ing the best-fit CPU core as well as selecting processor peripherals. There are threeNios II CPU cores: Nios II/f (fast), Nios II/e (economy) and Nios II/s (standard).

Avalon Bus The Avalon Bus is the internal bus system of a Nios II processor. The subcom-ponents of a Nios II processor use it to communicate with each other. User specifiedhardware can be integrated into a Nios II processor by using this bus.

µClinux µClinux (which stands for MicroControllerLinux) is a Linux kernel fork for micro-controllers without a memory management unit (MMU). It is based on version 2.6 ofthe Linux kernel.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 3

Page 5: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 1 Introduction

VHDL VHDL (Very High Speed Integrated Circuit Hardware Description Language) is ahardware description language used to design and specify complex digital systems. Inour case we use VHDL to describe same additional hardware for the Nios II processor.

1.3 Used Environment

In this section we describe which hardware and software we used for this project. Due to thefact that software become obsolete very fast there may be newer versions available. Anywaythe basic principles should be transferable.

1.3.1 Used Hardware

The Nios II Evaluation Kit There were two Nios II Evaluation Kits from Altera at ourdisposal. The most important features are:

• a CycloneTMEP1C12F324 FPGA

• 16 Mbytes of external SDRAM

• 8 Mbytes of external flash

• a RJ-45 connector and 10/100 Ethernet physical layer component

• a USB connector, providing power and host communication

• a Prototype area for user I/O

• user-defined push-button switches

• user-defined LEDs

• some further periphery

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 4

Page 6: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 1 Introduction

Figure 1: The Nios II Evaluation Kit

The expansion Board We designed and build a simple simulation board for our IO-port.Every IO-pin can be connected either with a button or with a LED. Figure 2 shows the princi-ple for one IO-pin.

Figure 2: The expansion board

The button or the LED can be selected with a jumper. Jumper on position 1 means that theIO-pin must act as an input and the button is used. Jumper on position 2 means that the IO-pinmust act as an output and the LED is used. You can find the whole schematic and the layoutin appendix C.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 5

Page 7: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 1 Introduction

Attention: There is no automatically detection if a pin is used as output or input. The userhas to take care about this. Wrong settings could lead to the damage of one or both boards!

1.3.2 Used Software

Quartus II Web Edition Quartus II is a software made by Altera. With this software youcan create HDL based hardware designs, simulate them, assign the pins of a FPGA and createa netlist which is used to configure a FPGA. The Web Edition is free available and comes withthe Nios II Evaluation Kit.

SOPC Builder The SOPC Builder is part of the Quartus II software. It is used to create orcustomize a Nios II processor.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 6

Page 8: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 2 Course Of Action

2 Course Of Action

2.1 Necessary Preparations and Rough Flow Chart

We advise to constitute two teams - one for the hardware part and on for the software part.

The hardware team can start like this:

Get familiar with VHDL

Install Quartus II Web Edition

Get familiar with Quartus (Elektor Howto - [7])

Create own device with VHDL

Add own device to Nios II processor with SOPC Builder

Align the Quartus project

Compile the new Nios II processor

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 7

Page 9: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 2 Course Of Action

The software team can start like this:

Get familiar with linux kernel programming

Install µClinux toolchain

Create kernel module

Then both teams can finish the project:

Build µClinux

Config the FPGA

Program µClinux image to the processor

Have fun and enjoy your life ;)

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 8

Page 10: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

3 Creating own Hardware

3.1 Conception

In the first place it is important to feel confident about how the new hardware device shouldwork. In our case we have two 8-Bit registers. One register contains the data which comesfrom respectively goes to the Nios II processor. The other register is the direction selectregister. It defines if a pin is used as input or output. So we need two addresses (at least oneaddress line) and a 8-Bit data line to the processor. We want to keep this example simpleso we decided that this device should became a slave device. We do not use any interrupts.Reading data from the input have to be done by polling the data register. Figure 3 shows adraft of our device.

Figure 3: Draft of the 8-Bit IO device

3.2 Creating VHDL Specification

First we have to specify which signals we need for our device and which of them are connectedwith the Avalon bus. In the description of the Avalon bus had to find out which signals arenecessary. In our case we need the following signals:

• address: Internal address offset.*

• chipselect: Signal to activate our device.*

• clk: Synchronization clock for the Avalon slave interface. All signals are synchronousto clk.*

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 9

Page 11: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

• reset n: Resets our device. Actually the developer decides what happen in this case.*

• write n: Indicates a write cycle.*

• read n: Indicates a read cycle.*

• writedata: Data lines for write transfers.*

• out port: Data lines which connects our device with the IO-pins.

• readdata: Data lines for read transfers.*

* These signals are required by the Avalon bus.

Please note: The signal readdata is also specified as output because output means not ”con-nected with the hardware pins of the FPGA” but ”data are sent via this line(s) to any othercomponent outside the component which is specified here”!

As a result we got these entity which defines the interface of our device.

entity pio eigen isport (−− inputs:signal address : IN STD LOGIC VECTOR (1 DOWNTO 0);signal chipselect : IN STD LOGIC;signal clk : IN STD LOGIC;signal reset n : IN STD LOGIC;signal write n : IN STD LOGIC;signal read n : IN STD LOGIC;signal writedata : IN STD LOGIC VECTOR (7 DOWNTO 0); 10

−− outputs:signal out port : INOUT STD LOGIC VECTOR (7 DOWNTO 0);signal readdata : OUT STD LOGIC VECTOR (7 DOWNTO 0));

end entity pio eigen;

We are geared to the existing VHDL examples and so we two address lines which gives usfour addresses although we need only two of them.

Now we have to define the architecture which describes the behavior of our device. Withinthe architecture we use local signals. The actual functionality is described within a process.The process is sensitive for the clock signal and for all asynchronous signals.

process (clk, reset_n)

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 10

Page 12: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

First we check if reset n gets a ’0’ signal. In that case we set both registers (data out, dir reg)to ’0’.

if reset_n = ’0’ then-- clear the output register and the direction registerdata_out <= std_logic_vector’("00000000");dir_reg <= std_logic_vector’("00000000");

Then we check if a rising edge occurs. A rising edge detects a read or write transfer.

elsif clk’event and clk = ’1’ then

Now we have to check if our device is responded (chipselect = 1), if it’s a read or write transfer(read n = 0 or write n = 0) and if data out or dir reg is meant (we decided to assign the address’00’ to data out and ’01’ to dir reg). The following (a little complex) statement checks if wewant to write to data out.

if std_logic’(((chipselect AND NOT write_n) ANDto_std_logic((((std_logic_vector’("000000000000000000000000000000") &(address)) = std_logic_vector’("00000000000000000000000000000000")))))) = ’1’ then

The statement checks if chipselect is ’1’ and if write n is ’0’. The Avalon bus has a 32 Bitaddress bus so this statement adds the two Bit internal address offset to 30 zeros and comparesit with 32 zeros. The result of these comparison is converted into a boolean value (withto std logic). This value is compared with ’1’. If all three conditions are true a write transferto data out is detected. The other three types of transfers (read from data out, read fromdir reg and write to dir reg) works similarly. The rest of the code relates to the functionalityof the parallel IO-port. Look at the complete well documented source code in our appendix Ato find out how it works.

Attention: The name of the entity and of the VHDL file have to be the same (In our case’pio eigen.vhd’). The name of the architecture must be ’europa’. We got a lot of problems ifwe do not follow this. The syntax check of Quartus also did not work very well. If you havethe same problems use the open source VHDL simulator GHDL for Linux (command line:ghdl -s nameoffile.vhd).

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 11

Page 13: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

3.3 Add custom hardware to the NIOS II processor

In this chapter we show the needed steps to create a new project and include the specifiedcomponent from the last section.

1. First we need a blank project based on the standard design supported by Altera.Create a copy of the standard project directoryC:\altera\kits\nios2 51\example\vhdl\niosII cyclone 1c12 eval\standard and put it to C:\

2. Now it is important to set user rights for the new directory.Therefore type the following listing in a NIOSII SDK Shell.

cd C: ; chmod -R 777 standard

Figure 4:

3. Now copy the new entity pio eigen.vhd into the project directoryc:\standard\

4. Launch Quartus and open the project filec:\standard\standard eval board.qpf

5. Open the SOPC Builder with a double click on the standard 1c12 symbol

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 12

Page 14: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

6. Click on create new component

Figure 5: Clipping of the SOPC Builder

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 13

Page 15: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

7. The Component Editor opens. Click on the second tab "HDL Files"

Figure 6: Component Editor - HDL Files

Here add the files of the used library altera vhdl support.vhdand the specification of our entity pio eigen.vhd.Click on the button Add HDL File ... to get a File open dialog.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 14

Page 16: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

8. Select the two files and click on Offnen to add the files

Figure 7: File open dialog

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 15

Page 17: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

9. The added files will be checked (visualized by a green blinking background)

Figure 8: Syntax check

10. If everything works fine, the message Component "pio eigen" is okshould appear in the status area

Figure 9: OK message

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 16

Page 18: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

11. Click on the next tab called "Signals" an verify all signals

Figure 10: Component Editor - Signals

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 17

Page 19: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

12. Jump to the last tab "Component Wizard"

Figure 11: Component Editor - Component Wizard

Click the Finish... button and submit the message "do you wish to save"with yes

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 18

Page 20: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

13. Look at the foorbar group an double click on the component pio eigen

Figure 12: Quartus - Add component

Change nothing in the upcomming dialog called Settings, click only Finish

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 19

Page 21: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

14. Now the new component should appear in the integrities list of the NIOS chip

Figure 13: Quartus - Integrities list

Click the button Generate

Figure 14: Dialog - Integrities list

To close this dialog click on Exit

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 20

Page 22: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

15. Back in Quartus a dialog asks you, if you want to update the NIOS symbol.Click on yes and in the next window click all symbols or blocks in file

16. Be carefull! In Quartus 5.x the wires between different symbols are not automaticallyconnected to the correct outputs.

Figure 15: Quartus - missmatched signals

17. Connect all symbols like shown in figure 16

Figure 16: Quartus - correct connected signals

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 21

Page 23: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

18. Click on the symbol button in the toolbox.In the dialog select a bidir pin out of the library primitives

Figure 17: Quartus - add bidirectional output

19. To connect the new symbol place it right next to the output"out port to and from the pio eigen[7..0]" and draw a connecting wirebetween them

Figure 18: Quartus - connect output

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 22

Page 24: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

20. Double click on the just created symbol to open the Pin Properties dialogEnter "pio io[8..1]" into field Pin name(s) and click OK

Figure 19: Quartus - Pin properties

21. Save your work by selecting Save from the File menu

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 23

Page 25: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

22. Click Processing → Start → Start Analysis & Elaboration to addyour new pio io pins to the pin list

Figure 20: Quartus - Start Analysis & Elaboration

23. Click Assignment → Pins

Figure 21: Quartus - Pin assignment

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 24

Page 26: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

24. Scroll down to the lower end of the pin list.Click on the <<new>> field in the first column an choose "pio io[1]"

Figure 22: Quartus - new assignment - pin

Click on the <<new>> field in the second column an choose "PIN L13"

Figure 23: Quartus - new assignment - location

Repeat this to assign all 8 pins.pio io pin1 PIN L132 PIN N143 PIN L144 PIN M155 PIN T176 PIN R177 PIN M138 PIN P14

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 25

Page 27: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

25. Again save your work by selecting Save from the File menu

26. Click Start compilation

Figure 24: Quartus - Compile

Now is the time to get a cup of coffee, this process might take about 45min.We suggest to open the Windows Task Manager to verify all the time, that Quartusdoes it’s work, cause it crashed (not responding = 0% cpu) sometimes.

27. After the compilation ended sucessfully, click on Programmer

Figure 25: Quartus - Start Programmer

28. Click "Hardware Setup...". In the upcoming dialog select"Nios II Evaluation Board [USB-0]" and click the close button.

Figure 26: Programmer - Select device

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 26

Page 28: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 3 Creating own Hardware

29. Check the box in the column "Program/Configure" and press Start

Figure 27: Programmer - Programm the board

30. Dont’t click Cancel in the upcoming dialog (if you do so, the hardware isn’t runningon the board)

Figure 28: Programmer - OpenCore Plus Status

Now the hardware is loaded into SRAM and a linux image can be downloaded to andran on the board:

31. Open a NiosII SDK Shell and enter:nios2-download -g zImage ; nios2-terminal

You can get a prepacked zImage from the CD which comes with this tutorial. Or youcan create one by yourself. (described in section 4)

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 27

Page 29: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

4 Installing µClinux toolchain

4.1 Building the embedded µClinux

4.1.1 µClinux

As in the system architecture document described the Nios II board comes by default with anpreinstalled µClinux distribution of microtronix1. Because the source code of this distributionis not free available we decided to use the nios2 µClinux community solution2. The hardwarewe build on the nios2 is not very complex, so our Linux should just be able to work with thenios2 cpu core, sdram, full featured timer, jtag/serial console and the cfi flash. There is noMMU on the current nios2, so no virtual memory, no shared objs/libs, no fork, and stack sizeis fixed. In the following steps there is described how to build the tools, compile the kerneland build the port applications for this µClinux on a Linux platform. If you get problemsduring this little tutorial about building the embedded linux, please have a look at the moredetailt howto at [9]. For reading it it is necessary that you have been registered. To run intoless trouble we recommend to accomplish these steps on a Linux platform. In our case weused our laptops based on the Fedora Core Linux distribution.

4.1.2 setup the development system

At first we have to build the cross-compiler. We used the gcc3, because the gcc4 cause trou-ble on binuntils-2.15. By using a Fedora Core Linux the development packages have to beinstalled and we recommend to update your system by running

"yum update"

before installing the compat-gcc-32 package (gcc3)

su - # your root passwdyum install compat-gcc-32cd /usr/binmv gcc gcc4ln -s gcc32 gccexit

4.1.3 adding a user

To avoid errors it is very useful to execute the following tasks as a separate user e.g ”jack”.In this tutorial we do all operations as the user ”jack” but using other users except the root isalso possible. To add a user execute the following command.

1www.microtronix.com2http://scorpius.homelinux.org/∼marc/nios2.html

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 28

Page 30: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

su - # your root passwduseradd jackpasswd jack

Login as the user you created e.g. ”jack” an check if home directory e.g. ”/home/jack” exists.

4.1.4 Download sources of microtronix’s nios2 linux

The microtronix port of the nios2 Linux is available athttp://forum.niosforum.com/downloads/1 4/nios2linux-1.4.zip. Af-ter downloading this zip-file to /downlaod directory and extracting we get directories con-taining several contents,

• Cygwin environment

• documents and references about µClinux

• examples about the linux toolbox, busybox, utils etc.

• linux system, containing the uClib, kernel, file system and basic applications

• Configuration files

4.1.5 Building the nios2 linux

To build the linux we used a very handy and useful build script available athttp://hungryhippo.jot.com/WikiHome/build.zip. Downloaded and extractedto /download we can build a linux. This directory contains a few configuration files the buildscript needs. By starting the script you can see how the procedure fetches a lot of files, con-figures an compiles it.

cd ˜/downloadunzip build.zip./build

This could take a couple of minutes depending on the computer you use. The several stepsthe task executes are

• Preparing the kernel sources

...unzip -aoq ../nios2linux-1.4.zip...patch -p0 <˜/download/kernel.diff...

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 29

Page 31: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

patch -p1 <˜/download/mx140apps.diff...

In the main command lines in this section the microtronix’s port of Nios II Linux willbe extracted an the kernel and applications will be patched.

• Preparing the µClinux distribution sources

...wget -N http://www.uclinux.org/pub/uClinux/dist/uClinux-dist-test-20051209.tar.bz2...tar jxf ˜/download/uClinux-dist-test-20051209.tar.bz2...patch -p0 <˜/download/uClinux-dist.diff...

The whole µClinux distribution (”uClinux-dist-test-20051209.tar.bz2”) will be down-loaded by wget in this stage, but we advise to download this file before running thisbuild script athttp://www.uclinux.org/pub/uClinux/dist/ because of the large file sizeabout 200 MB. After downloading, the archive will be extracted and a needed µClinuxpatch will be done.

• Downloading the buildroot snapshot

...SNAPSHOT=20060320wget -N http://buildroot.uclibc.org/downloads/snapshots/buildroot-$SNAPSHOT.tar.bz2wget -N http://www.uclibc.org/downloads/snapshots/uClibc-$SNAPSHOT.tar.bz2wget -N http://busybox.net/downloads/snapshots/busybox-$SNAPSHOT.tar.bz2

ln -s buildroot-$SNAPSHOT.tar.bz2 buildroot-snapshot.tar.bz2ln -s uClibc-$SNAPSHOT.tar.bz2 uClibc-snapshot.tar.bz2ln -s busybox-$SNAPSHOT.tar.bz2 busybox-snapshot.tar.bz2...tar jxf ˜/download/buildroot-snapshot.tar.bz2...ln -s ˜/download dl...

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 30

Page 32: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

Among the µClinux sources, several other packages are needed to build a full runnableembedded linux. At first we download the buildrom which is a set of Makefiles andpatches that allows to generate both a cross-compilation toolchain and a root file systemfor our target easily . The cross-compilation toolchain uses uClibc which we downloadin the next step. To let the operator work with the embedded linux, we need a EmbeddedLinux BusyBox which combines tiny versions of many common UNIX utilities into asingle small executable. We get this tools by downloading the busybox. Finally wecreate some links for these packages for compiling.

• Patch the configuration and prepare the root file system

...#path the configpatch -p0 <˜/download/buildroot.diffmake oldconfigmake...# prepare root fsmkdir ˜/rootfscp -a ˜/buildroot/build_nios2/root/* ˜/rootfs...

To get working our build root we just need to patch and compile it. Then at last wegenerate the rootfs directory the kernel needs to build the initramfs image.

After a few minutes depending on your machine you use the script will finish successfully.You could have a look at your home directory e.g ”/home/jack” and see several directo-ries. The uClinux distribution will be prepared in /uClinux-dist. Applications ported bymicrotronix will be in /apps. The kernel we will generate is the 2.6.11-uc0 which you canfind in /linux-1.6.x with zImage, EPCS MTD and avalon watchdog drivers. If you plan toadd or remove dev nodes you have to edit the /download/rootfs list file. We will do this in thedriver development section later on. For more Information about the build script, please havea look at the complete script in the addendum.

4.1.6 set the path variable

For using the cross compiler gcc we need to use the following path.

PATH=$PATH:˜/buildroot/build_nios2/staging_dir/bin

A better solution is to set this path permanently in the /.bash profile.

PATH=$PATH:$HOME/bin:$HOME/buildroot/build_nios2/staging_dir/bin

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 31

Page 33: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

To verify that you set this path correctly run this command,

nios2-linux-uclibc-gcc -v

if you get an error message you did something wrong.

Run this to verify that you have the proper busybox in FLT format,

nios2-linux-uclibc-flthdr ˜/rootfs/bin/busybox

it is correct if the result displays the FLT header like this,

/home/jack/rootfs/bin/busyboxMagic: bFLTRev: 4Build Date: We Apr 26 11:55:05 2006Entry: 0x40Data Start: 0x632c8Data End: 0x7bb80BSS End: 0x96750Stack Size: 0x3e80Reloc Start: 0x7bb80Reloc Count: 0x344dFlags: 0x1 ( Load-to-Ram )

4.2 configuring and compiling the kernel

cd ˜/linux-2.6.x# generate nios2_system.h from ptfmake ARCH=nios2nommu CROSS_COMPILE=nios2-linux-uclibc-hwselect SYSPTF=your_system.ptf

To compile the linux kernel we have to set a parameter which describes the hardware of yourboard. It is important that this file matches your current hardware. In our case we use the Al-tera Cyclone II NIOS standard board with cyclone 1c12 chip. If you create optional hardwarelike in our case you have to take the ptf file you created with the Altera Development tool. Oryou can use the standard ptf file fromaltera/kits/nios2 51/example/vhdl/niosII cyclone 1c12 eval/standard/standard 1c12.ptf.

By running the command line you will be asked what hardware devices you want to use. Thiscould look like the following,

--- Please select which CPU you wish to build the kernel against:

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 32

Page 34: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

(1) cpu - Class: altera_nios2 Type: s Version: 5.11Selection: 1--- Please select a device to upload the kernel to:(1) ext_flash

Class: altera_avalon_cfi_flashSize: 16777216 bytes

Selection: 1--- Please select a device to execute kernel from:(1) ext_ssram

Class: altera_avalon_cy7c1380_ssramSize: 2097152 bytes

(2) ddr_sdramClass: ddr_sdram_componentSize: 33554432 bytes

(3) epcs_controllerClass: altera_avalon_epcs_flash_controllerSize: 2048 bytes

Selection: 2

After that we have to configure the kernel by that command line,

# config the kernelmake ARCH=nios2nommu CROSS_COMPILE=nios2-linux-uclibc- menuconfig

In the menu ”Device Drivers –> Character devices –> Serial drivers –>” we select a serialor a jtag console. If your user id and group id on Linux are not 500, change these to your idinstead, ”Device Drivers –> Block devices –> (for 2.6.11-uc0)”

Then finally we can save and exit our configuration and last but not least, compile our kernel,

# compile the kernelmake ARCH=nios2nommu CROSS_COMPILE=nios2-linux-uclibc- zImage

4.3 Ready to start

Now the compressed kernel image ”arch/nios2nommu/boot/zImage” is ready to get down-loaded to your hardware. At first, download the sof file of your hardware to your board withquartusII programmer, then open a nios2 sdk shell, Go to the directory your linux home ismapped to e.g ”c: is /cygdrive/c/” and download the kernel image.

cd /cygdrive/c/linux-2.6.x/arch/nios2nommu/bootnios2-download -g zImagenios2-terminal

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 33

Page 35: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 4 Installing µClinux toolchain

By loading this image, some boot messages will appear and finally a boot prompt will beshown.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 34

Page 36: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 5 Programming kernel driver

5 Programming kernel driver

5.1 Implementation of the driver

5.1.1 General

This section of the tutorial shows, how to program a driver for linux kernel 2.6. We recom-mend to print out the kernel module source (see appendix B), which is attached to this how toand to read the source simultaneously with this section.

First of all you should know, that a kernel module is in principle just a c program with at leasttwo functions, static int init mod init(void) and static void exitmod exit(void). (The names of the functions are specified bymodule init(mod init); and module exit(mod exit); where function pointersare given to the kernel)

5.1.2 Defines

• We define the major numbers for linking between file-system and driver:#define DATA MAJOR 240 - data device file gets major number 240#define DIR MAJOR 241 - direction device file gets major 241

• We need the addresses of the data and direction register in the avalon bus. This address isassigned when adding the pio eigen.vhd to the hardware specification in SOPC-builder(see section 5).#define DATA REGISTER 0x00801090 - data register is at address 0x00801090#define DIR REGISTER 0x00801091 - direction register is at address 0x00801091

• We need buffers to hold the data read from registers for copying into user-space.#define STRING LEN 5 - buffers are 5 bytes long

5.1.3 Function calls

The init function is called when the module is loaded into the kernel, e.g. with insmodmodulename and the exit function is executed when unloading the module from the kernel,e.g. with rmmod modulename.This way it is possible to run a program in kernel-space, but it is still not possible to accessthe hardware from the user-space. To make that possible, it is necessary to extend the moduleto a driver which links the hardware registers into the linux filesystem.

To get such a driver we need to register all device files we want to use to the IO-management ofthe kernel. This is done by register chrdev(DATA MAJOR, "iodata", &fops dat);for the data register and by register chrdev(DIR MAJOR, "iodir", &fops dir);for the direction register in module’s init function. The first parameter of these function calls

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 35

Page 37: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 5 Programming kernel driver

(DATA MAJOR and DIR MAJOR) are just integer values for linking the device files of thefilesystem to the driver. The second parameter is the name, which identifies the device file inkernel IO-management. The last parameter is a struct, including pointers to functions whichare called when accessing the device files.

static struct file_operations fops_dir ={.read= dir_read,.write= dir_write,.open= dir_open,.release= dir_release};

• Function int dir open(..) is called when a process tries to open the device file.It checks, whether another process uses this file already, if so, it will return a busy signalto the process, which tries to open. If a process got successfully access to the devicefile, the data of the direction register is read with inb(DIR REGISTER) and storedas string in a buffer.

• Function size t dir read(..) is called when a process reads from device file. Itcopies every byte of the buffer (containing the data of the direction register) into user-space using the command put user(..). Normally the reason why we cannot justcopy from a kernel space buffer into a user space buffer using memcpy would be, thatthe buffers are in different virtual address blocks. But due to the fact that we don’thave a memory management unit (mmu), those buffers are in the same address block.Nevertheless we decided to program it like if we had a mmu, to allow debugging on ahost-machine with mmu.

• Function size t dir write(..) is called when writing to the device file. It copiesdata from an user space buffer into a kernel space buffer using copy from user(..).The reason for not using memcpy is the same like for function dir read. Data isstored into direction register using outb(buffer,DIR REGISTER) after copying.

• Function int dir release(..) is called when a process closes the file. It unlocksthe device file and the module.

Same functions exist for the data register too.

When unloading the driver the device files have to be unregistered from IO-management.To accomplish that, those two functions must be called in the module’s exit function:unregister chrdev(DATA MAJOR,"iodata"); for unregistering the data device fileand unregister chrdev(DIR MAJOR,"iodir"); for unregistering the direction de-vice file.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 36

Page 38: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 5 Programming kernel driver

5.2 Adding device files to rootfs

Now we have to take care, that our device files are generated when booting the linux imageon the target. Therefor you can add these two lines to ∼/download/rootfs list:nod /dev/iodata 666 0 0 c 240 0nod /dev/iodir 666 0 0 c 241 0

The lines say, that 2 device files are generated, /dev/iodata and /dev/iodir both with the Unixpermissions 666, and the major numbers for associating the files with the driver, in this case240 and 241.When building a new kernel, it will automatically create all device files like configured in∼/download/rootfs list.

5.3 Adding driver to kernel

To add the driver to the kernel sources, copy the source code to linux-source/drivers/misc/.Now we need to tell menuconfig something about the new kernel driver. Therefor the lineobj-$(CONFIG IO) += io.ohas to be added to the Makefile in linux-source/drivers/misc/. And following lines to theKconfig file in linux-source/drivers/misc/ right above the ”endmenu” statement:

config IOtristate "IO module for custom IO"helpEnable module to access custom IO.

5.4 Building the kernel

Change into the directory of the linux source and type:make ARCH=nios2nommu CROSS COMPILE=nios2-linux-uclibc- menuconfig

Now the kernel configuration interface shows up. To enable the custom kernel driver changetoDevice Drivers --> Misc devices

and press ’y’ when highlighting IO module for custom IO. Then press exit and savethe configuration.

To cross-compile the kernel type:make ARCH=nios2nommu CROSS COMPILE=nios2-linux-uclibc- zImageAfter kernel was successfully generated, the zImage including kernel and rootfs can be copiedfrom: linux-source/arch/nios2nommu/boot/zImage.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 37

Page 39: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 6 User-space programs

6 User-space programs

6.1 General

Due to the fact, that there is not enough space on the target board for a whole compiler suite,it is necessary to cross-compile user-space programs on a host machine. To cross-compile anyC source code, just run:nios2-linux-uclibc-gcc source.c -o output bin -elf2flt="-s 16000"-Wall

After that you have to move the binary program into the rootfilesystem, with e.g.mv output bin ∼/rootfs/usr/bin/

and compile a new kernel (have a look a chapter above), what creates a new zImage withthe kernel and the modified rootfs.After downloading the new zImage the command output bin should be available on thetarget.

6.2 Using custom IO

If you want to code a program using the custom hardware defined in pio eigen.vhd you caninclude the header file testing/pio eigen.h into your C program. It implements functions forreading and writing to the two device files /dev/iodata and /dev/iodir:

• unsigned char read dev(files file) returns the value as unsigned char ofthe device file you want to read from. The data type ”files” is an enumeration consistingof dir file and dat file.e.g: int a=read dev(dat file);

• void write dev(files file, unsigned char val) writes the value ofthe byte ”val” into the device file.e.g: write dev(dir file,240);

Two example programs can be found in testing/ folder; test io output and test io input.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 38

Page 40: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 7 Using preinstalled VM

7 Using preinstalled VM

We created a virtual machine based on fedora core 4 for compiling µClinux to save time whichwould be needed to step through the installation process of the µClinux tool-chain. The virtualmachine runs with qemu, an open source PC emulator compiled for different host systems,like linux or windows. You need at least 8GB of hard disk space on your host system to usethis virtual machine.

7.1 Linux host system

1. extract the file qemu-0.8.1-i386.tar.gz from ”virtual machine dvd 1” to ”/”:su - [root pw]cd /tar xvfz /media/cdrom/qemu-0.8.1-i386.tar.gz

2. copy the image-files ”fedora4 uclinux.img” (dvd 1), ”fedora4 jack.img” (dvd 2) andthe start-script ”fedora4 uclinux.sh” (dvd 1) into the same folder of your hard disk.

3. run the start-script (ensure that you are in the folder where the start-script and the imagesare):sh fedora4 uclinux.sh

7.2 Windows host system

1. we made a dvd with ext2 filesystem due to file size limitations on normal iso9660filesystem, what concludes, that it isn’t possible to read this dvd’s from windows sys-tem by default. It might work with the ext2 driver from http://www.fs-driver.org or withexplore2fs.

2. unzip the file qemu-0.8.1-windows-3.zip from ”virtual machine dvd 1” to anyfolder of your hard disk.

3. copy the image files ”fedora4 uclinux.img” (dvd 1), ”fedora4 jack.img” (dvd 2) and thebatch-script ”fedora4 uclinux.bat” (dvd 1) into the folder where you extracted qemu to.

4. run the start-script ”fedora4 uclinux.bat” by double clicking.

7.3 Usage

After executing the start-script, the virtual machine boots and after some time asks you forlogin. To work with the µClinux tool-chain you should login as ”jack” with the password”jack”. The root account should only be used for system configuration purposes password forroot is ”123456”.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 39

Page 41: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 7 Using preinstalled VM

7.4 Moving data

You can move data between the guest OS and the host OS by connecting from guest OS tohost OS. You cannot connect from host OS to guest OS. Thus we suggest you to create awindows share if you are using windows as host OS or to use scp/sftp if you are using linuxas host OS.

Windows OS :

1. Create share on host OS, e.g. the folder ”c:\bla”

2. Mount the share on guest OS:mount -o username=windows username //10.0.2.2/bla /mnt/tmp/

3. Now you can copy data from your guest OS to the shared directory

Linux OS :

1. Start the ssh daemon on your host OS:/etc/init.d/sshd start

2. Copy files this way:scp file you want to copy [email protected]:

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 40

Page 42: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux 8 Summary

8 Summary

In the early planning phase we assumed to get the most problems with the open source tools.Actually it was the other way round and we got disappointed in the commercial tools fromAltera. Some problem may be due to a bad installation of our software. Unfortunately wedid not have the time to set up a new software environment to verify this. Finally we finishedour project successfully because we met most requirements. The things you can do with thishowto are:

• Create own VHDL hardware

• Add own hardware to a Nios II processor

• Write a kernel module for own hardware

• Build µClinux for Nios II processor

Things that would be nice to have in the future:

• Program Nios II configuration into flash memory to save data on power off.

• Add network support to Nios II to add own software to µClinux without building a newkernel.

In the end we would give some tips to people who want to take this howto as basis for furtherprojects. Our strategy to constitute two teams exposed to be the right one. Things are mucheasier if you just have to care about hardware or software. We also found out that it is veryhelpful you know the used software tools. You will save a lot of time of trying to figure outsilly problems.

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 41

Page 43: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux References

9 Addendum

References

[1] Official altera page:http://www.altera.com

[2] Support for nearly everything ;)http://www.wikipedia.org

[3] Support for things wikipedia doesn’t know:http://www.google.com

[4] Official µClinux page:http://uclinux.org/

[5] Community forum about Nios II:http://www.niosforum.com/

[6] Linux Kernel Module Programming Guide:http://www.tldp.org/LDP/lkmpg/2.6/html/x569.html

[7] Quartus II Howto (german):http://www.elektor.de/Portals/0/Magazine/Downloads/2006/060025-12DE.pdf

[8] Linux Driver Development (german):http://ezs.kr.hsnr.de/TreiberBuch/html/

[9] Nios 2 UClinux port guide (Account required):http://forum.niosforum.com/forum/index.php?showtopic=3174

[10] Nios 2 UClinux port:http://scorpius.homelinux.org/∼marc/nios2.html

[11] GHDL a open source VHDL simulator:http://ghdl.free.fr/

[12] QEMU a processor emulator:http://fabrice.bellard.free.fr/qemu/

[13] Avalon Interface Specification:http://www.altera.com/literature/manual/mnl avalon spec.pdf

[14] Nios II Hardware Development Tutorial:http://www.altera.com/literature/tt/tt nios2 hardware tutorial.pdf

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 42

Page 44: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux A VHDL Code

A VHDL Code−− ——————————-−− pio eigen.vhd−− 03.05.2006−−−− 8 Bit parallel IO-Interface−− for NIOS II−−−− Peter Feuerer, Steffen Gutmann−− Ronny Schroeder, Sascha Haensch−− ——————————- 10

−− library from Altera−− defines function to std logiclibrary altera vhdl support;use altera vhdl support.altera vhdl support lib.all;

library ieee;use ieee.std logic 1164.all;use ieee.std logic arith.all;use ieee.std logic unsigned.all; 20

−− define interfaceentity pio eigen is

port (−− inputs:

signal address : IN STD LOGIC VECTOR (1 DOWNTO 0);signal chipselect : IN STD LOGIC;signal clk : IN STD LOGIC;signal reset n : IN STD LOGIC;signal write n : IN STD LOGIC; 30signal read n : IN STD LOGIC;signal writedata : IN STD LOGIC VECTOR (7 DOWNTO 0);

−− outputs:signal out port : INOUT STD LOGIC VECTOR (7 DOWNTO 0);signal readdata : OUT STD LOGIC VECTOR (7 DOWNTO 0)

);end entity pio eigen;

40−− define functionalityarchitecture europa of pio eigen is

signal dir reg : STD LOGIC VECTOR (7 DOWNTO 0);signal data out : STD LOGIC VECTOR (7 DOWNTO 0);signal data in : STD LOGIC VECTOR (7 DOWNTO 0);

begin

process (clk, reset n) 50

begin

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 43

Page 45: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux A VHDL Code

if reset n = ’0’ then−− clear the output register and the direction registerdata out <= std logic vector’("00000000");dir reg <= std logic vector’("00000000");−− rising edge detects read or write transfer

elsif clk’event and clk = ’1’ then−− WRITE to data register 60−− if chipselect = ’1’ and−− write n = ’0’ and−− address = ’00’if std logic’(((chipselect AND NOT write n) AND

to std logic((((std logic vector’("000000000000000000000000000000") &(address)) = std logic vector’("00000000000000000000000000000000"))))))= ’1’ then−− if dir reg(x) = ’1’ (= output) then−− data out(x) <= writedata(x)−− else 70−− data out(x) <= ’Z’ (High Impedance)if dir reg(0) = ’1’ then

data out(0) <= writedata(0);else

data out(0) <= ’Z’;end if;if dir reg(1) = ’1’ then

data out(1) <= writedata(1);else

data out(1) <= ’Z’; 80end if;if dir reg(2) = ’1’ then

data out(2) <= writedata(2);else

data out(2) <= ’Z’;end if;if dir reg(3) = ’1’ then

data out(3) <= writedata(3);else

data out(3) <= ’Z’; 90end if;if dir reg(4) = ’1’ then

data out(4) <= writedata(4);else

data out(4) <= ’Z’;end if;if dir reg(5) = ’1’ then

data out(5) <= writedata(5);else

data out(5) <= ’Z’; 100end if;if dir reg(6) = ’1’ then

data out(6) <= writedata(6);else

data out(6) <= ’Z’;end if;if dir reg(7) = ’1’ then

data out(7) <= writedata(7);

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 44

Page 46: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux A VHDL Code

elsedata out(7) <= ’Z’; 110

end if;

−− READ from data register−− if chipselect = ’1’ and−− read n = ’0’ and−− address = ’00’elsif std logic’(((chipselect AND NOT read n) AND

to std logic((((std logic vector’("000000000000000000000000000000") &(address)) = std logic vector’("00000000000000000000000000000000"))))))= ’1’ then 120

readdata(7 DOWNTO 0) <= data in;

−− WRITE to direction register−− if chipselect = ’1’ and−− write n = ’0’ and−− address = ’01’elsif std logic’(((chipselect AND NOT write n) AND

to std logic((((std logic vector’("000000000000000000000000000000") &(address)) = std logic vector’("00000000000000000000000000000001")))))) 130= ’1’ then

dir reg <= writedata(7 DOWNTO 0);

−− if dir reg(x) = ’0’ (= Input) then−− data out(x) <= ’Z’ (High Impedance)−− every input driver is set to High Impedanceif dir reg(0) = ’0’ then

data out(0) <= ’Z’;end if; 140if dir reg(1) = ’0’ then

data out(1) <= ’Z’;end if;if dir reg(2) = ’0’ then

data out(2) <= ’Z’;end if;if dir reg(3) = ’0’ then

data out(3) <= ’Z’;end if;if dir reg(4) = ’0’ then 150

data out(4) <= ’Z’;end if;if dir reg(5) = ’0’ then

data out(5) <= ’Z’;end if;if dir reg(6) = ’0’ then

data out(6) <= ’Z’;end if;if dir reg(7) = ’0’ then

data out(7) <= ’Z’; 160end if;

−− READ from direction register

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 45

Page 47: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux A VHDL Code

−− if chipselect = ’1’ and−− read n = ’0’ and−− address = ’01’elsif std logic’(((chipselect AND NOT read n) AND

to std logic((((std logic vector’("000000000000000000000000000000") &(address)) = std logic vector’("00000000000000000000000000000001"))))))= ’1’ then 170

readdata(7 DOWNTO 0) <= dir reg;

end if;

end if;

end process;

−− fill out port with data out and 180−− data in with out port independently−− from the process−− every time and in parallelout port <= data out;

data in <= out port;

end europa;

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 46

Page 48: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux B Kernel module code

B Kernel module code/* Copyright (C) 2006 Sascha Haensch, Peter Feuerer, Ronny Schroeder, Steffen Gutmann *//* This program is free software; you can redistribute it and/or modify *//* it under the terms of the GNU General Public License as published by *//* the Free Software Foundation; either version 2 of the License, or *//* (at your option) any later version. *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU General Public License for more details. *//* You should have received a copy of the GNU General Public License */ 10/* along with this program; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

/* uncomment following line to use the kernelmodule without *//* io (inb / outb) functions, needed for debug purposses on host *//* machine. *//* #define DEBUG */

#include <linux/kernel.h> 20#include <linux/module.h>#include <linux/fs.h>#include <asm/uaccess.h>

/* major numbers for identifying the device files *//* mknod /dev/iodata c 240 0 */#define DATA MAJOR 240/* mknod /dev/iodir c 241 0 */#define DIR MAJOR 241

30/* register addresses */#define DATA REGISTER 0x00801090#define DIR REGISTER 0x00801091

/* max buffer length */#define STRING LEN 5

MODULE AUTHOR("Sascha Haensch, Peter Feuerer,Ronny Schroeder, Steffen Gutmann"); 40

MODULE LICENSE("GPL");MODULE DESCRIPTION("Module which creates devicehandler

for /dev/iodata and /dev/iodir for 8 I/O pins");MODULE SUPPORTED DEVICE("none");

/* define buffers for the strings sended to user */char dat string[STRING LEN]="0\n";char dir string[STRING LEN]="0\n";

char* dat ptr=dat string; 50char* dir ptr=dir string;

/* device files open? */

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 47

Page 49: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux B Kernel module code

int dir is open = 0;int dat is open = 0;

/* convert string to integer */static int atoi(const char *name){

int val = 0; 60for (;;name++){

switch (*name){

case ’0’. . .’9’:val = 10*val+(*name−’0’);break;

default:return val;

} 70}

}

/* convert byte to string */void itoa(char *name, unsigned char value){

int i,j=0;for(i=100;i>0;i/=10){

name[j++]=’0’+value/i; 80value=value−(value/i)*i;if(name[0]==’0’ && i!=1)

j=0;}name[j++]=’\n’;name[j]=0;

}

/* called when data device file is opened */static int dat open(struct inode *inode, struct file *file) 90{

unsigned char value;

if (dat is open++)return −EBUSY;

/* catch new information from data register */#ifndef DEBUGvalue=inb(DATA REGISTER);itoa(dat string,value); 100#endif

dat ptr=dat string;

try module get(THIS MODULE);return 0;

}

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 48

Page 50: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux B Kernel module code

/* called when process closes data device file */static int dat release(struct inode *inode, struct file *file) 110{

−−dat is open;module put(THIS MODULE);return 0;

}

/* called when a process reads from data file */static ssize t dat read(struct file *filp, char *buffer, size t length, loff t * offset){

/* Number of bytes actually written to the buffer */ 120int bytes read = 0;

/* If we’re at the end of the message, return 0 signifying end of file */if (*dat ptr == 0)

return 0;

while (length−− && *dat ptr) {

/* The buffer is in the user data segment, not the kernel *//* segment so “*” assignment won’t work. We have to use */ 130/* put user which copies data from the kernel data segment to *//* the user data segment. */put user(*(dat ptr++), buffer++);

bytes read++;}

/* return count of bytes, sent to user */return bytes read;

} 140

/* called when a process writes to data file*/static ssize t dat write(struct file *filp, const char *buff, size t len, loff t * off){

int not copied=0;if(len > (STRING LEN−1))

len=STRING LEN−1;/* copy data from user into buffer dat string */not copied=copy from user(dat string,buff,len);dat string[len]=’\0’; 150

/* output the value of the number in buffer dat string *//* to address of the direction register */#ifndef DEBUGoutb((unsigned char)atoi(dat string),DATA REGISTER);#endif

return len−not copied;} 160

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 49

Page 51: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux B Kernel module code

/* called when direction device file is opened */static int dir open(struct inode *inode, struct file *file){

unsigned char value;170

if (dir is open++)return −EBUSY;

/* catch new information from direction register */#ifndef DEBUGvalue=inb(DIR REGISTER);itoa(dir string,value);#endif

dir ptr=dir string; 180

try module get(THIS MODULE);return 0;

}

/* called when process closes direction device file */static int dir release(struct inode *inode, struct file *file){

−−dir is open; 190module put(THIS MODULE);return 0;

}

/* called when a process reads from direction file */static ssize t dir read(struct file *filp, char *buffer, size t length, loff t * offset){

/* Number of bytes actually written to the buffer */int bytes read = 0;

200/* If we’re at the end of the message, return 0 signifying end of file */if (*dir ptr == 0)

return 0;

while (length−− && *dir ptr) {

/* The buffer is in the user data segment, not the kernel *//* segment so “*” assignment won’t work. We have to use *//* put user which copies data from the kernel data segment to *//* the user data segment. */ 210put user(*(dir ptr++), buffer++);

bytes read++;}

/* return count of bytes, sent to user */return bytes read;

}

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 50

Page 52: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux B Kernel module code

/* called when a process writes to direction file*/ 220static ssize t dir write(struct file *filp, const char *buff, size t len, loff t * off){

int not copied=0;if(len > (STRING LEN−1))

len=STRING LEN−1;/* copy data from user into buffer dir string */not copied=copy from user(dir string,buff,len);dir string[len]=’\0’;

/* output the value of the number in buffer dir string */ 230/* to address of the direction register */#ifndef DEBUGoutb((unsigned char)atoi(dir string),DIR REGISTER);#endif

return len−not copied;}

/* definitions, which functions are called for /dev/iodata */ 240static struct file operations fops dat ={

.read= dat read,

.write= dat write,

.open= dat open,

.release= dat release};

/* definitions, which functions are called for /dev/iodir */static struct file operations fops dir = 250{

.read= dir read,

.write= dir write,

.open= dir open,

.release= dir release};

/* initialize the module */static int init mod init(void) 260{

if(register chrdev(DATA MAJOR, "iodata", &fops dat)){

printk("register_chrdev of iodata failed!\n");return −EIO;

}if(register chrdev(DIR MAJOR, "iodir", &fops dir)){

printk("register_chrdev of iodir failed!\n");return −EIO; 270

}/* workaround for initializing all pins as input */#ifndef DEBUG

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 51

Page 53: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux B Kernel module code

outb(255,DATA REGISTER);outb(0,DATA REGISTER);#endifreturn 0;

}

/* exit the module */ 280static void exit mod exit(void){

unregister chrdev(DATA MAJOR,"iodata");unregister chrdev(DIR MAJOR,"iodir");

}

/* what are the module init/exit functions */module init( mod init );module exit( mod exit );

290

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 52

Page 54: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux C The Expansion Board

C The Expansion Board

C.1 Description

Our expansion board provides eight independent channels which are configureable as eitheran input or an output. Each channel consists of a jumper, a led, a pushbutton and two resistors.

C.2 Bill Of Materials

• 8x resistor 180 ohm

• 8x resistor 10k ohm

• 8x low current led red 3mm

• 8x pushbutton (APEM - PHAP3301)

• 8x 2-pole jumper

• 8x 3-pole strip

• 1x 10-pole strip

• 4x spacer 10mm

• 4x bolt M3x6

• pcb with provided layout

C.3 Connection between Expansion Board and Nios II Evaluation Kit

We used the multipoint connector J5 on the prototype area of the Nios II Evaluation Kit.

J5 on Evaluation Board Connector on Expansion BoardVcc3 3 (Pin 2) Vcc

Ground (Pin 3, 7, 10, 12, 13, 17) Ground4 16 28 314 416 518 61 75 8

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 53

Page 55: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux C The Expansion Board

C.4 Schematic

Figure 29: schematic of the expansion board

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 54

Page 56: Nios2 uClinux Additional Hardware

NIOS-CPU with additional hardware driven with µClinux C The Expansion Board

C.5 PCB-Layout

Figure 30: pcb of the expansion board

Peter Feuerer, Steffen Gutmann, Sascha Haensch, Ronny Schroeder Page 55