Guga Kupradze
Published

Beginner’s Guide to PetaLinux 2025.2 on Arty Z7-20

Step-by-step PetaLinux setup on Arty Z7-20: from VM setup to running your first LED and switch application.

BeginnerProtip57
Beginner’s Guide to PetaLinux 2025.2 on Arty Z7-20

Things used in this project

Story

Read more

Code

helloworld_linux.c

C/C++
Code for PetaLinux
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <stdlib.h>

#define BASE_GPIO_ADDRESS 0x41200000
#define BASE_GPIO_SIZE    0x00034000   // enough to cover up to 0x41233000 + regs

#define BTN_BASE 0x00000
#define LED_BASE 0x11000
#define RGB_BASE 0x22000
#define SWS_BASE 0x33000

int main()
{
    int fd;
    uint8_t *virtual_base;

    volatile uint32_t *btn_addr;
    volatile uint32_t *led_addr;
    volatile uint32_t *rgb_addr;
    volatile uint32_t *sws_addr;

    uint32_t PushButton;
    uint32_t Switches;
    uint32_t RGBleds1;
    uint32_t RGBleds2;
    uint32_t RGBout;

    fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    virtual_base = mmap(NULL, BASE_GPIO_SIZE, PROT_READ | PROT_WRITE,
                        MAP_SHARED, fd, BASE_GPIO_ADDRESS);
    if (virtual_base == MAP_FAILED) {
        perror("mmap");
        close(fd);
        return 1;
    }

    btn_addr = (volatile uint32_t *)(virtual_base + BTN_BASE);
    led_addr = (volatile uint32_t *)(virtual_base + LED_BASE);
    rgb_addr = (volatile uint32_t *)(virtual_base + RGB_BASE);
    sws_addr = (volatile uint32_t *)(virtual_base + SWS_BASE);

    printf("Hello World\n");

    while (1)
    {
        PushButton = *btn_addr;
        Switches   = *sws_addr;

        *led_addr = PushButton;

        RGBleds1 = (Switches & 0x1) ? (PushButton & 0x7) : 0;
        RGBleds2 = (Switches & 0x2) ? ((PushButton & 0x7) << 3) : 0;

        RGBout = RGBleds1 | RGBleds2;
        *rgb_addr = RGBout;

        usleep(50000);
    }

    munmap(virtual_base, BASE_GPIO_SIZE);
    close(fd);
    return 0;
}

helloworld.c

C/C++
Bare metal code
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"

/*
 * Memory-mapped AXI GPIO base addresses
 * These names must match your Vivado design / xparameters.h
 */
volatile unsigned long *BTN = (volatile unsigned long *)XPAR_AXI_GPIO_0_BASEADDR;
volatile unsigned long *LED = (volatile unsigned long *)XPAR_AXI_GPIO_1_BASEADDR;
volatile unsigned long *RGB = (volatile unsigned long *)XPAR_AXI_GPIO_2_BASEADDR;
volatile unsigned long *SWS = (volatile unsigned long *)XPAR_AXI_GPIO_3_BASEADDR;

int main()
{
    int PushButton;
    int Switches;
    int RGBleds1;
    int RGBleds2;
    int RGBout;

    init_platform();

    xil_printf("Hello World\r\n");

    while (1)
    {
        /* Read button and switch input registers */
        PushButton = BTN[0];
        Switches   = SWS[0];

        /* Show pushbutton value on normal LEDs */
        LED[0] = PushButton;

        /*
         * If switch 0 is ON, drive RGB LED 1
         * Use only lowest 3 bits of PushButton:
         * bit0 = R, bit1 = G, bit2 = B
         */
        if (Switches & 0x00000001)
        {
            RGBleds1 = (PushButton & 0x00000007);
        }
        else
        {
            RGBleds1 = 0;
        }

        /*
         * If switch 1 is ON, drive RGB LED 2
         * Same 3 button bits, shifted left by 3
         * so they go into bits 3..5
         */
        if (Switches & 0x00000002)
        {
            RGBleds2 = (PushButton & 0x00000007) << 3;
        }
        else
        {
            RGBleds2 = 0;
        }

        /* Combine both RGB LED values into one output register */
        RGBout = RGBleds1 + RGBleds2;
        RGB[0] = RGBout;
    }

    cleanup_platform();
    return 0;
}

Credits

Guga Kupradze
1 project • 0 followers
Embedded Systems | FPGA & SoC (Zynq UltraScale+) | Real-Time & High-Speed Communication | PL/PS Co-Design

Comments