Bar
SpaceWire UK
Specialist providers of VHDL Intellectual Property & Design Services
BarBarBarBar
Tutorial
Missing Image!
Part 11 - Update website to allow access to Programmable Logic address space

Introduction

This tutorial details the steps required to add form elements to the existing website such that the Programmable Logic address space can be accessed from a webpage.

Aims

The aims of this tutorial are as follows :-

    Part 1 - Project Setup

    1. Setup environment
    2. Change present working directory

    Part 2 - Enchance website application

    1. Add form elements to website
    2. Add extra Javascript functions

    Part 3 - Build & package PetaLinux

    1. Build PetaLinux
    2. Package PetaLinux

    Part 4 - Hardware Deployment

    1. Setup Zedboard hardware
    2. Launch MiniCom terminal emulator
    3. Run PetaLinux on Zedboard via JTAG
    4. Check everything is working as expected

    Part 5 - Revision Control

    1. Commit to repository

    Part 6 - Quickstart

    1. Obtain tutorial files from Bitbucket, create & build project, deploy on Zedboard
    #### Part 1 - Project Setup ####

    1. Setup environment

    Setup Xilinx design environment for the 2021.2 toolset.
    steve@Desktop:~$ xilinx
    Xilinx tools available tools at /opt/Xilinx :-
    1) 2021.2 - Vivado - SDK - Vitis - PetaLinux
    0) Exit
    Please select tools required or exit : 1

    Tools are as follows :-
    vivado @ /opt/Xilinx/Vivado/2021.2/bin/vivado
    vitis @ /opt/Xilinx/Vitis/2021.2/bin/vitis
    petalinux-build @ /opt/Xilinx/PetaLinux/2021.2/tool/tools/common/petalinux/bin/petalinux-build

    2. Change present working directory

    Change the present working directory to be the project directory.
    steve@Desktop:~$ cd ~/projects/zedboard_linux/os/petalinux
    #### Part 2 - Enchance website application ####

    3. Add form elements to website

    Edit the existing dynamic webpage file to add read & write register functionality using HTML forms linked to Javascript functions. Lines 59-77 show the additions.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/cgi-bin/index.cgi

    index.cgi

    1. #!/bin/sh

    2. # Output Header
    3. printf "Content-type: text/html\r\n\r\n"

    4. # Get information
    5. sys_host=$(hostname)
    6. sys_time=$(date)
    7. sys_load=$(awk '{print $1}' /proc/loadavg)
    8. sys_up=$(awk '{print $1}' /proc/uptime)
    9. cpu_model=$(grep model /proc/cpuinfo | cut -d : -f2 | tail -1 | sed 's/\s//')
    10. cpu_cores=$(grep -c ^processor /proc/cpuinfo)
    11. mem_total=$(free -m | awk 'NR==2{print $2}')
    12. mem_used=$(free -m | awk 'NR==2{print $3}')
    13. mem_free=$(free -m | awk 'NR==2{print $4}')
    14. net_mac=$(cat /sys/class/net/eth0/address)
    15. net_ip_loc=$(ip a | grep inet | grep -vw lo | grep -v inet6 | cut -d \/ -f1 | sed 's/[^0-9\.]*//g')
    16. net_ip_ext=$(wget -q -O- http://ipecho.net/plain)

    17. # Output HTML
    18. printf '<!DOCTYPE html>'
    19. printf '<html lang="en">'
    20. printf '<head>'
    21. printf '<meta http-equiv="content-type" content="text/html; charset=UTF-8">'
    22. printf '<script src="../uptime.js"></script>';
    23. printf '<title>Zedboard webserver</title>'
    24. printf '</head>'
    25. printf '<body>'
    26. printf 'Hello from your Zedboard webserver...'
    27. printf '<br>'
    28. printf '<img src="../zedboard.png" alt="Missing Image!">'

    29. printf '<br>System<br>'
    30. printf 'Honstname: %s<br>' "${sys_host}"
    31. printf 'Time: %s<br>' "${sys_time}"
    32. printf 'Uptime: <span id="uptime_text">%.2f</span> seconds ' ${sys_up}
    33. printf '​<button onclick="GetUpTime()">Refresh</button>'
    34. printf '​ Auto : <select onchange="SetTimeout(this)">'
    35. printf '​<option value="0">Off</option>'
    36. printf '​<option value="1">1s</option>'
    37. printf '​<option value="5">5s</option>'
    38. printf '​</select><br>'

    39. printf '<br>CPU<br>'
    40. printf 'Model: %s<br>' "${cpu_model}"
    41. printf 'Cores: %d<br>' ${cpu_cores}
    42. printf 'Load: %.2f<br>' ${sys_load}

    43. printf '<br>Memory<br>'
    44. printf 'Total: %d Mb<br>' ${mem_total}
    45. printf 'Used: %d Mb<br>' ${mem_used}
    46. printf 'Free: %d Mb<br>' ${mem_free}

    47. printf '<br>Network<br>'
    48. printf 'MAC Address: %s<br>' "${net_mac}"
    49. printf 'Local IP: %s<br>' "${net_ip_loc}"
    50. printf 'External IP: %s<br>' "${net_ip_ext}"

    51. printf '<br>';
    52. printf '<form onsubmit="return false;">'
    53. printf ' <label for="waddr">Write : address</label>'
    54. printf ' <input type="text" id="waddr" name="waddr" value="0x41200000" size="10">'
    55. printf ' <label for="wdata">data </label>'
    56. printf ' <input type="text" id="wdata" name="wdata" value="0x00000000" size="10">'
    57. printf ' <input type="submit" value="Write" onclick="WebWrite(this.form)">'
    58. printf ' Status : <span id="wstatus">None</span>';
    59. printf '</form>';

    60. printf '<br>';
    61. printf '<form onsubmit="return false;">'
    62. printf ' <label for="raddr">Read : address</label>'
    63. printf ' <input type="text" id="raddr" name="raddr" value="0x41200000" size="10">'
    64. printf ' <label for="rdata">data</label>'
    65. printf ' <input type="text" id="rdata" name="rdata" value="0x00000000"  size="10" readonly>'
    66. printf ' <input type="submit" value="Read" onclick="WebRead(this.form)">'
    67. printf ' Status : <span id="rstatus">None</span>';
    68. printf '</form>';

    69. printf '</body>'
    70. printf '</html>'

    4. Add extra Javascript functions

    Edit the existing Javascript file to add read and write register requests that call the peek & poke CGI scripts and update the webpage accordingly. Lines 37-80 show the additions.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/uptime.js

    uptime.js

    1. // Requests
    2. var uptime_req;
    3. var timer_req;
    4. var write_req;
    5. var read_req;

    6. // Receive data & update webpage accordingly
    7. function GotUptime() {
    8.   if (uptime_req.readyState == 4 && uptime_req.status == 200) {
    9.     txtObj = document.getElementById("uptime_text");
    10.     if (txtObj !== null) {
    11.       txtObj.innerHTML = uptime_req.responseText;
    12.     }
    13.   }
    14. }

    15. // Setup request and ask for data return
    16. function GetUpTime() {
    17.   if (window.XMLHttpRequest) {
    18.     uptime_req = new XMLHttpRequest();
    19.     uptime_req.abort();
    20.     uptime_req.onreadystatechange = GotUptime;
    21.     uptime_req.open("POST", "/cgi-bin/uptime.cgi", true);
    22.     uptime_req.send(null);
    23.   }
    24. }

    25. // Setup/Cancel timer request
    26. function SetTimeout(obj) {
    27.   clearInterval(timer_req);
    28.   var interval = obj.value;
    29.   if (interval > 0) {
    30.     timer_req = setInterval("GetUpTime()", 1000 * interval);
    31.   }
    32. }

    33. // Receive data & update webpage accordingly
    34. function GotWrite() {
    35.   if (write_req.readyState == 4 && write_req.status == 200) {
    36.     if (write_req.responseText.substr(0,6) == "Error:") {
    37.       document.getElementById("wstatus").innerHTML = "Failed";
    38.     } else {
    39.       document.getElementById("wstatus").innerHTML = "Success";
    40.     }
    41.   }
    42. }

    43. // Setup request and ask for data return
    44. function WebWrite(form) {
    45.   if (window.XMLHttpRequest) {
    46.     write_req = new XMLHttpRequest();
    47.     write_req.abort();
    48.     write_req.onreadystatechange = GotWrite;
    49.     write_req.open("POST", "/cgi-bin/poke?" + form.waddr.value + "&" + form.wdata.value, true);
    50.     write_req.send(null);
    51.   }
    52. }

    53. // Receive data & update webpage accordingly
    54. function GotRead() {
    55.   if (read_req.readyState == 4 && read_req.status == 200) {
    56.     if (read_req.responseText.substr(0,6) == "Error:") {
    57.       document.getElementById("rstatus").innerHTML = "Failed";
    58.     } else {
    59.       document.getElementById("rstatus").innerHTML = "Success";
    60.       document.getElementById("rdata").value = read_req.responseText.toUpperCase();
    61.     }
    62.   }
    63. }

    64. // Setup request and ask for data return
    65. function WebRead(form) {
    66.   if (window.XMLHttpRequest) {
    67.     read_req = new XMLHttpRequest();
    68.     read_req.abort();
    69.     read_req.onreadystatechange = GotRead;
    70.     read_req.open("POST", "/cgi-bin/peek?" + form.raddr.value, true);
    71.     read_req.send(null);
    72.   }
    73. }

    #### Part 3 - Build & package PetaLinux ####

    5. Build PetaLinux

    Rebuild the project to include the updated files.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-build

    6. Package PetaLinux

    Package up the project ready for deployment.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-package --prebuilt --force
    #### Part 4 - Hardware Deployment ####

    7. Setup Zedboard hardware

    Connect up the hardware as follows :-
    1. Xubuntu PC USB ⇄ Zedboard USB JTAG/Debug
    2. Xubuntu PC USB ⇄ Zedboard USB UART
    3. Zedboard Ethernet ⇄ Router
    4. Xubuntu PC Ethenet ⇄ Router
    5. Router ⇄ Internet
    Missing Image! Set the boot mode jumpers on the Zedboard for JTAG. Missing Image! Power on the Zedboard.

    8. Launch MiniCom terminal emulator

    If not already running, open up a new terminal and launch the MiniCom terminal emulator.
    steve@Desktop:~$ minized

    Welcome to minicom 2.7.1

    OPTIONS: I18n
    Compiled on Dec 23 2019, 02:06:26.
    Port /dev/ttyACM0, 06:34:25

    Press CTRL-A Z for help on special keys

    9. Run PetaLinux on Zedboard via JTAG

    Power cycle the Zedboard and deploy the project via JTAG.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-boot --jtag --prebuilt 3

    10. Check everything is working as expected

    Access the webserver running on the Zedboard using a browser pointing at the Zedboard's IP address (192.168.2.87). All being well something akin to the following webpage should be displayed. Missing Image! Registers within the Programmable Logic can now be accessed directly using the Read & Write forms at the bottom of the webpage. To write a register set the write address, write data and press the Write button. Likewise to read a register set the read address and press the Read button. As before the LED register is located at 0x41200000 and the slide switch register at 0x41200008. The status of the executed request is shown next the the Status text. Note the Javascript functions do not contain any timeout functionality so if the CGI scripts do not respond with anything then no error status will be reported.
    #### Part 5 - Revision Control ####

    11. Commit to repository

    Commit the updated files, create an annotated tag and push the commit & tag up to the remote repository.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git commit -am "Added peek/poke CGI access to website application."
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git tag -a v6.0 -m "PetaLinux, Peek/Poke, LED Runner, Webserver, Peek/Poke CGI & PL Access with XSA from zedboard_leds_switches v1.0"
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git push
    #### Part 6 - Quickstart ####

    12. Obtain tutorial files from Bitbucket, create & build project, deploy on Zedboard

    The source files relating to this tutorial for the OS can be obtained from Bitbucket. The OS repository contains both PetaLinux and a local copy of the exported hardware (firmware).

    The instructions below assume that Part 1 - Installation of tools, setup of environment and creation of project area has been completed in full and that the environment has been setup as per 1. Setup environment. The root project area ~/projects should be present and contain the common project. The zedboard_linux projects should NOT be present. Adjust the commands below to suit if the above differs.

    Obtain OS source, build & deploy on Zedboard.
    steve@Desktop:~$ cd ~/projects
    steve@Desktop:~/projects$ git clone -b v4.0 https://bitbucket.org/spacewire_firmware/zedboard_linux
    steve@Desktop:~/projects$ cd zedboard_linux/os/petalinux
    Do something with the OS (if required) then perform the following steps :-
    1. Build PetaLinux
    2. Package PetaLinux
    3. Setup Zedboard hardware
    4. Launch MiniCom terminal emulator
    5. Run PetaLinux on Zedboard via JTAG
    6. Check everything is working as expected