Search
Link to descrition of task: Description
1/ Run GtkTerm on your PC (Applications→Development→Serial Port Terminal)
GtkMenu: Configuration -> Port: Port: /dev/ttyUSB0; Baud rate: 115200; Parity: none; Stopbit: 1
In GtkTerm window, press enter, if you do not see IP address or restart the board.
GtkTerm has also opened the command line window of MZAPO board OS. The login allows you entering commands for the remote system.
Note: While you are writing password, you will not see any characters, not even *.
Be aware that GtkTerm represents the command line window of the remote Linux running in MZAPO board.
2/ SSH connection allows more possibilities than GtkTerm.
ssh-add-mzapo-key
or
ssh-add /opt/zynq/ssh-connect/mzapo-root-key
3/ Mount the complete target file system into the /tmp subdirectory of your PC. Supply IP address of your MZAPO board discovered by GtkTerm.
/opt/zynq/sshfs-mount-target 192.168.202.xxx
4/ Copying files between PC and the board
The 'Makefile' file from MZAPO template uses opened SSH for comfortable work with the board.
But you can also use Midnight commander on PC for copying files, or alternatively, you can connect via SSH, so you can use SCP to transfer files between the target system and the host PC ssh -i /opt/zynq/ssh-connect/mzapo-root-key root@192.168.202.xxx, eventually, you can connect via ssh as user root ssh root@192.168.202.xxx
ssh -i /opt/zynq/ssh-connect/mzapo-root-key root@192.168.202.xxx
ssh root@192.168.202.xxx
Before using knobs and led, you must map them into address space.
unsigned char *mem_base; mem_base = map_phys_address(SPILED_REG_BASE_PHYS, SPILED_REG_SIZE, 0); if (mem_base == NULL) exit(1);
Reading knobs values
uint32_t rgb_knobs_value; rgb_knobs_value = *(volatile uint32_t*)(mem_base + SPILED_REG_KNOBS_8BIT_o);
The knobs data are returned as 4 bytes unsigned | buttons | R-knob | G knob | B knob |, i.e., the bits 7 to 0 are blue knob, bits 15 to 8 are green knob, bits 23 to 16 are red knob, bit 24 is blue knob button, 25 is green knob button, and 26 is red knob button. You can unpack then, e.g. by
int rk, gk, bk, rb, gb, bb; rk = (rgb_knobs_value>>16) & 0xFF; // red knob position ... similar for green and blue rb = (rgb_knobs_value>>26) & 1; // red buttom ... similar for green and blue
32 LEDs are controlled by writing to their port. The next line will light on all LEDs.
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0xFFFFFFFF;
The board contains 2 RGB LEDs with variable colors. The value is 4 bytes | 0-unused | R- | G | B |. The following lines will set the color of the first led to yellow and the second to violet.
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = 0x00FFFF00; *(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = 0x00FF00FF;
LCD display has 480 columns and 320 rows. The mapping of LCD ports is perfored by:
unsigned char *parlcd_mem_base; parlcd_mem_base = map_phys_address(PARLCD_REG_BASE_PHYS, PARLCD_REG_SIZE, 0); if (parlcd_mem_base == NULL) exit(1);
The initialization of LCD is required before the first usage of LCD. It should be performed only once time by calling:
parlcd_hx8357_init(parlcd_mem_base);
To begin drawing, move LCD pixel pointer to point 0,0 - top left corner
*(volatile uint16_t*)(parlcd_mem_base + PARLCD_REG_CMD_o) = 0x2c;
Each subsequent write the data port of LCD fills a pointed pixel by color information and then, LCD data pointer is moved to next pixel in the current row. At the end of a row, LCD pixel pointer is moved to the beginning of a next row.
The following command writes black.
*(volatile uint16_t*)(parlcd_mem_base + PARLCD_REG_DATA_o) = 0x0;
A color information for LCD is 16 bit unsigned | 5 bits of Red | 6 bits of Green | 5 bits of Blue |. Thus, BLACK is 0x0, WHITE is 0xFFFF, RED is 0xF800, GREEN is 0x07E0, BLUE is 0x001F
Create the program for MZAPO board see the following illustration) that controls two RGB reflectors. The task is intended for groups of 2 students, but it can be solved by a single person as well.
A pair of RGB LEDs, named as LED1 and LED2 on PCB, are shown in the bottom quarter and represent both reflectors. Enter input parameters using the three rotary knobs marked ENCODER1, ENCODER2, and ENCODER3 on the PCB.
The color of the reflector light color is always selected in the HSV / HSB color model, see http://colorizer.org/ . Be aware that the RGB-LED cannot distinguish the full range of colors as displays, but depending on its brightness, it displays from 256 (extreme) to 1024 (medium brightness). Select the change steps accordingly. On the web, you will find a number of C programs to convert from HSV to RGB.
Note: If you work in a team, you need to set up a team before downloading, and it will also apply to individuals. Team creation allows working in pairs.
The solution is divided into scored categories whose values are added together.
Effects are added to reflector lights and their points are added together. The unit must remember effects, i.e. after setting another effect, you can return to the previous one without having to enter its values again. If the effect is running, its values can be changed without having to interrupt it, so the result is immediately visible.
(a) the duration of continuous illumination; (b) the extinction time; © the phase shift of one reflector to the other. -
The last point will be very demanding and it is not necessary to solve it for merely obtaining credit. However, brave students who want to achieve A without a test will not miss Ethernet, because without it they will cross the limit of 90 points from the exercise. If someone omits it, he can also get A, but only after writing a good test!
Task: The unit is not only able to control its reflectors, but also to connect to and control another unit. Therefore, it has to find out its IP address and then send commands via network packets.
Design appropriate protocols and how to communicate with the second unit. You should detect the existence of the second unit and then connect to it at any time, and then disconnect and connect again. If you want A mark without a written test, prove to us that you are a C code-expert and the exam would only keep you from learning to other subjects.
The application template is in the directory
/opt/apo/mzapo_template
The following files are included in the template
A more detailed description of the design registers can be found in documentation of MZ_APO.
The `Makefile` rules for the build program need to be customized for your own application. The application will consist of one or more source files in the language C (files with the extension `*.c`) or in C ++ (files with the extension `*.cpp`).
An example with the main function
main
A list of source files is set in the SOURCES variable, see below Part of the `Makefile` file
SOURCES
SOURCES = change_me.c mzapo_phys.c mzapo_parlcd.c #SOURCES + = font_prop14x16.c font_rom8x16.c
In the first line, you need to edit the name of your main application file. If fonts are used, you need to uncomment the second line. To add other needed files, it is possible to list them in these two lines or repeating them with += for adding other needed files. Header files (`* .h`) are not listed in make files, they are inserted by C preprocessor.
The name of the desired binary executable is assigned in the variable TARGET_EXE
TARGET_EXE
The translation is done by simply calling the build program
make
To delete generated files (object files, application binary code and automatically generated dependencies), use `clean` object. Objects can also be combined
make clean all
Any compilation when you change and run an application on a remote drive is done when invoking the object `run`
make TARGET_IP=192.168.202.xxx run
Automatic login, data transfer and application launch on target device with the given IP address requires an already-established private key in the SSH agent for that session
ssh-add/opt/apo/zynq/ssh-connect/mzapo-root-key
The application is first copied to the subdirectory /tmp created by user's login name and, then, the application is running with the default Both input and output are available on the developer's computer via SSH connections.
git@gitlab.fel.cvut.cz:b35apo/mzapo_template.git
https://gitlab.fel.cvut.cz/b35apo/mzapo_template.git
Currently, the IP (Internet Protokol) is the most common standard for communication between computers and devices. The protocol is a higher packet, datagram and link layer protocol. To implement our own frame transfer, a variety of technologies are available on local networks. The most widespread is ETHERNET, which does not, however, address the transmission of frames between multiple networks in its basic formats.
The IP protocol exists in two versions IPv4, which uses to identify the interface. Each computer on the World Wide 32-bit address. Gradually, it passes to a new version of IPv6 that uses 128-bit addresses with better sophisticated assignment and communication rules.
A simpler version of IPv4 is expected to work on a semester task. Above basic a network layer, there is several other protocols specializing in different needs and types of transmission. The best known is the protocol TCP which serves to ensure a secure connection with the complete acknowledgment of receipt mechanism give. The data stream is suspended in the event of packet loss and re-sending is secured undelivered data. Protocol is used, for example, for the most widespread transport application Protocols and HTTP, HTTPS, and SSH services. However, TCP is not suitable for parallel delivery messages with a general destination address to all participants on the local network (Broadcast).
*In order to maintain the list of all the connected units*, the unconnected datagram protocol UDP will be used within your application that allows sending status information to the local network without defining the destination address. Such messages can then receive by all units on the local network.
An example of a simple program in the role of the server and the other in the client can be found, for example in the Beej's Guide to Network Programming manual.
First you need to set up a network socket
Int sockfd; If ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { Perror ("socket"); Exit (1); }
The AF_INET option specifies the IPv4 address family, SOCK_DGRAM then selects the UDP unconnected service. More about calling socket in Beej's Guide or in https://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html#Creating-a-Socket] GNU C library documentation used on GNU / Linux.
AF_INET
SOCK_DGRAM
Select a local port, on which the application listens and which is used with the outbound IP address. The computer / drive interface is selected by calling bind (GNU).
Because the datagrams could be sent to all local area network units by mistake, this option must be enabled
Int broadcast = 1; If (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, & broadcast, Sizeof broadcast) == -1) { Perror ("setsockopt (SO_BROADCAST)"); Exit (1); }
It is also possible to use calls sendto and recvfrom to send messages.
sendto
recvfrom
Basic example of binding (labeling) IPv4 socket to the service specific port number to be accessible from all network interfaces. The value MY_PORT is 16-bit number in the range 1 to 65535. The network addresses are stored in the network stack data structures in the IP network standard byte order which is big-endian one. The port number has to be converted from the CPU native (h = host) order to the network (n = network) byte order for this reason. The port numbers in the range from 1 to 1000 are reserved for system/privileged services and can be used/requested for the bind only by programs with administrator privilege or delegated privilege for full network stack control.
struct sockaddr_in bindaddr; memset(&bindaddr, 0, sizeof(bindaddr)); bindaddr.sin_family = AF_INET; bindaddr.sin_port = htons(MY_PORT); bindaddr.sin_addr.s_addr = INADDR_ANY; if (bind(sockfd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1) { perror("bind"); exit(1); }
By default, system blocks reassignment of the same port number for the new instance of the service to new socket for some while after previous user has closed/released the port. That is why it is worthwhile to prevent this temporal blocking before bind() call when service should operate on the predefined port number.
int yes=1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { perror("setsockopt (SO_REUSEADDR)"); exit(1); }
Because unintentional sending of broadcast to the network can lead to high load and disturbance of other communications, the broadcast transmission is disable for new socked by default. It can be enabled by set of the socket option
int broadcast = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1) { perror("setsockopt (SO_BROADCAST)"); exit(1); }
The datagrams corresponding UDP services can be send by sendto call and received by recvfrom call.
IPv4 address for broadcast datagram sending to the local network can be setup as
struct sockaddr_in braddr; memset(&braddr, 0, sizeof(braddr)); braddr.sin_family = AF_INET; braddr.sin_port = htons(HELLO_SERVICE_PORT); braddr.sin_addr.s_addr = INADDR_BROADCAST;
Server / listener of UDP packed receiving on all network interfaces starting
nc -u -l -p 44444
Starting command to send message
nc -u 127.0.0.1 44444