Software Interrupts - Controlling the Car

Instructions

In this exercise, you will do the same activity as Exercise 7.1: you must control a car to move it from a parking lot to the entrance of the Test Track. However, you can no longer access the MMIO addresses directly on user code, i.e., the high-level code with the control logic. You must implement a set of syscalls to control the car and use them in your control logic, that has to be executed in user mode.

Separating the control code

The following code is suggested as a starting point for your solution. You can change it however you want.

.text
.align 4

int_handler:
  ###### Syscall and Interrupts handler ######

  # <= Implement your syscall handler here

  csrr t0, mepc  # load return address (address of
                 # the instruction that invoked the syscall)
  addi t0, t0, 4 # adds 4 to the return address (to return after ecall)
  csrw mepc, t0  # stores the return address back on mepc
  mret           # Recover remaining context (pc <- mepc)


.globl _start
_start:

  la t0, int_handler  # Load the address of the routine that will handle interrupts
  csrw mtvec, t0      # (and syscalls) on the register MTVEC to set
                      # the interrupt array.

# Write here the code to change to user mode and call the function
# user_main (defined in another file). Remember to initialize
# the user stack so that your program can use it.

.globl control_logic
control_logic:
  # implement your control logic here, using only the defined syscalls

You must create a second file, called main.s, that contains only the code below. This code can't be changed and will be used by the assistant to check your solution.

.text
.globl user_main
user_main:
  jal control_logic
infinite_loop:
  j infinite_loop

Syscalls

You can implement the system calls listed below. In case your code doesn't use some of them, it is not necessary to implement it. For this exercise, you mustn't implement any additional system calls.

syscallParametersReturn ValueDescription
syscall_set_engine_and_steering
Code: 10
a0: Movement direction
a1: Steering wheel angle
0 if successful and -1 if failed (invalid parameters)Start the engine to move the car.
a0's value can be -1 (go backward), 0 (off) or 1 (go forward).
a1's value can range from -127 to +127, where negative values turn the steering wheel to the left and positive values to the right.
syscall_set_hand_brake
Code: 11
a0: value stating if the hand brakes must be used-a0 must be 1 to use hand brakes.
syscall_read_sensors
Code: 12
a0: address of an array with 256 elements that will store the values read by the luminosity sensor.-Read values from the luminosity sensor.
syscall_get_position
Code: 15
a0: address of the variable that will store the value of x position.
a1: address of the variable that will store the value of y position.
a2: address of the variable that will store the value of z position.
-Read the car's approximate position using the GPS device.

Notes and Tips

  • Check the ALE Peripheral MMIO Manual for information about the Self Driving Car peripheral.
  • If you are not using the assistant, you must configure the simulator in a similar way as done for Exercise 7.1. However, with a small difference: the option “Enable Operating System” must stay disabled.
  • You mustn't call the exit syscall (as there isn't an operating system, it doesn't exist).
  • The syscall operation code must be passed via register a7, as done in previous exercises.
  • You can test your code using the simulator's assistant from this link.