zed
zed
zed
Fernando Rincón
[email protected]
● Zedboard
– I/O
– Boot Configuration
● Xilinx layered drivers architecture
● GNU/Linux for the Zynq
● FreeRTOS
● Asymmetric vs Symmetric Processing
USB-JTAG
(programming, host PC)
USB-UART
(host PC comms)
USB-OTG
(peripherals)
● 4 options
– Wired
● Appropriate during development cycle
● USB-JTAG:
– default method
– Only requires micro-usb cable
● Traditional JTAG
– Trough the JTAG connector
– Requires a Xilinx Platform USB cable or Digitlent USB-TAG prog. Cable
– Autonomous
● Secure booting
● Quad-SPI flash memory
● SD card
JTAG Mode
Cascaded JTAG (default)
Independent JTAG
Boot Device
JTAG (default)
PLL Mode
PLL used (default)
Quad-SPI Flash
PLL Bypassed
SD Card
Source: avnet
● Why GNU/Linux?
– Advantages:
● Broad use as an open source desktop, server, and embedded OS
● Feature-rich
– Symmetric multiprocessing
– Preemptive multitasking
– Shared libraries
– Device drivers
– Memory management
– IP networking
– Support for multiple file systems
– Free & Open Source
tem (rootfs)
chain & Debugger
Kernel
Linux Kernel Device Drivers Image
U-boot
Boot
Loader
First Stage Boot Loader
Hardware QEMU
Linux Build tools: PetaLinux,
Yocto, OpenEmbedded, buildroot
Other tool chains: Linaro, GCC
mainline Board Support Package (BSP): Collection of SoC/board specific Linux
components that include Linux kernel & device drivers, boot loader and tools
● User applications
– Task specific
● Libraries
– C run time, networking,
graphics, for example
● Kernel
● Hardware
– CPU, memory
– Timer, interrupt controller,
I/O
● Open-source, second stage boot loader that boots the Linux system
– Platform/Board specific configuration required
– e.g. custom clock settings
● Powerful features:
– Load Linux kernel, applications, data blobs, root file system, device trees,
PL bitstream
– Boot from Flash, SPI Flash, SD/MMC, USB, Ethernet, I2C, etc.
– Decompression (including bitstream) and unpacking of combined images of
various types
– Has a simple shell/script environment
● Packaged into boot image file BOOT.BIN
fatload
fatload mmc
mmc 00 0x8000
0x8000 zImage;
zImage;
fatload
fatload mmc
mmc 00 0x1000000
0x1000000 devicetree.dtb;
devicetree.dtb;
fatload mmc
fatload mmc 00 0x2000000 ramdisk32M.image.gz;
0x2000000 ramdisk32M.image.gz;
go
go 0x8000
0x8000
● The boot image can contain FSBL, bitstream and application code or a
second stage bootloader
● Stored in persistent memory and loaded at boot time
● Booting a kernel
– Boot arguments and pass-over
– Kernel will setup the platform/architecture based on the device tree
– Setup, Initialize and Allocate memory, setup early devices (e.g. UART)
– Drivers are probed and initialized (based on device tree and scanning)
– Root file system is mounted
– Start user space ‘init’ program (PID = 1)
● Numerous kernel subsystems varying levels of hardware abstraction
– E.g. Disk Controller Drivers, Block Devices, File Systems, Virtual File
Systems
● Kernel Space
– Virtual and Physical memory
– CPU ‘Kernel/Supervisor Mode’ Application
● User Space
Virtual memory only (kernel Kernel syscall API
–
handles the mapping and page Linux Kernel
faults)
– CPU ‘User Mode’ (ARM Hardware
Unprivileged)
– All hardware access via kernel
syscall interface
● Pros
– Very simple – no kernel module or code
– Good for quick prototyping / IP verification
– peek/poke utilities
– Portable (in a very basic sense)
● Cons
– No interrupt handling possible
– No protection against simultaneous access
– Need to know physical address of IP
● Hard-code?
● OK for prototyping – not recommended for production
/sys/class/gpio/gpio7
/sys/class/gpio/gpio7 ## echo
echo 11 >> value
value Useful for controlling
/sys/class/gpio/gpio7
/sys/class/gpio/gpio7 ## cat value
cat value Devices from shell scripts
fprintf(file_led7,
fprintf(file_led7, “%d”,
“%d”, 1);
1); The programmatic way
fscanf(file_led7, “%d”, &n_ch);
fscanf(file_led7, “%d”, &n_ch);
fd=open("/dev/uioX",O_RDWR);
fd=open("/dev/uioX",O_RDWR);
● Several options
– Issuing a read() on the device returns number of interrupts since last read
call
read(fd,
read(fd, &num_irqs,
&num_irqs, sizeof(num_irqs));
sizeof(num_irqs));
/*
/* open
open the
the device
device */
*/
int fd=open(“/dev/uioX”,O_RDWR);
int fd=open(“/dev/uioX”,O_RDWR);
/*
/* memory
memory map
map it
it */
*/
volatile
volatile unsigned int
unsigned int *ptr
*ptr == \\
mmap(NULL,
mmap(NULL, 4096,
4096, PROT_READ|PROT_WRITE,
PROT_READ|PROT_WRITE, MAP_SHARED,
MAP_SHARED, fd,
fd, 0);
0);
/*
/* setup
setup the
the device
device registers
registers */
*/
*(ptr+REG_OFFSET)
*(ptr+REG_OFFSET) == ...
...
/*
/* main
main IRQ/processing
IRQ/processing loop
loop */*/
while(1)
while(1) {{
unsigned
unsigned tmp
tmp == 0x1;
0x1;
/*
/* Enable the interrupt */
Enable the interrupt */
write(fd, &tmp,sizeof(tmp));
write(fd, &tmp,sizeof(tmp));
/*
/* Wait
Wait for
for an
an IRQ
IRQ
read(fd, &tmp,
read(fd, &tmp, sizeof(tmp);
sizeof(tmp);
/*
/* Handle
Handle the
the IRQ
IRQ */
*/
tmp = *(ptr+REG_OFFSET);
tmp = *(ptr+REG_OFFSET);
...
...
*(ptr+REG_OFFSET)
*(ptr+REG_OFFSET) == ...
...
}}
● Pros
– Benefits of /dev/mem and mmap()
– Plus IRQ handling
– No kernel code at all
● If using OF_GENIRQ extensions
– No need to recompile and reboot kernel
● Kernel drivers can easily break the kernel and force a reboot
– UIO driver errors not usually fatal
● Open driver development to non-kernel developers
● Cons
– Interrupt model is simple but adequate
– Subject to variable or high latency
– No support for DMA to/from user space
Zedboard / OS © Grupo ARCO-UCLM, 2015 41
Application Development
● Pre-emptive scheduling
– Highest priority ready task
– Time slice same priority task
● Idle task
– For low priority or background
tasks
– System in low-power
● Supports
– Tasks
– Queues
– Semaphores & Mutex
– Dynamic memory allocation
XAPP1079
XAPP1078 Wiki
XAPP1093