Problem Set 5 Harvard Extension School CSCI E-92: Principles of Operating Systems Spring 2024 Due: April 14, 2024 at Midnight ET (Eastern Time) Total of 100 Points 1. (100 Points) Freescale K70 Programming. Write a C program (with embedded assembler as necessary) for the Freescale K70/MK70FN1M0 Tower Development Kit that implements the following constructs: a. Timer routines that use FlexTimer interrupts (from FTM0) to maintain the current time and date. A supervisor call should be implemented to allow the time and date to be set and a second supervisor call should be implemented to return the current time and date. The time should be maintained as the number of milliseconds since an epoch of midnight (zero hours) on January 1, 1980 -- this is the MS-DOS Epoch. Note that this epoch is different from the Unix Epoch that we used in Problem Set 1. Your routines should maintain this count of milliseconds in a double word (64 bit) value. You should define and document the format through which parameters are passed to the supervisor call and returned from the supervisor call. When your OS starts, the initial time and date will be set to zero (the MS-DOS Epoch). A user must issue the supervisor call to set the time and date to the correct value. This implementation of the supervisor call to set the time and date is problematic in that it allows any user to set the time and date. Even though this is a security hole in your OS, we will allow this to happen. If you implement password-protected logins to your OS as part of your final project, you can make some logins be privileged and store the privileged vs. non-privileged state in the PCB. Then, you can make the supervisor call that sets the time and date check that the process is privileged before allowing that operation. b. Interrupt-driven I/O from/to the user RS232 UART (UART5). In order to implement this, maintain two queues: one queue for input characters (from the port to the K70) and one queue for output characters (from the K70 to the port). When a UART receiver interrupt ("receiver full interrupt") occurs, read the character from the UART data register and enqueue the character to the input queue. When the character input SVC assigned to this serial I/O device is called, dequeue a character from the input queue and return it to the user. When the character output SVC assigned to this serial I/O device is called, enqueue the character to the output queue and make sure that the UART transmitter interrupt is enabled. When the UART transmitter interrupt occurs, dequeue a character from the output queue and send it to the UART data register. If there are no more characters in the output queue, disable transmitter interrupts. In cases where the SVC action inside the SVC software interrupt service routine (ISR) cannot be accomplished (for example, an input SVC with no characters in the buffer or an output SVC with the buffer full), busy wait for the condition to clear. Never busy wait in a *hardware* interrupt routine. If a hardware interrupt routine cannot complete its action (for example, if a UART receiver interrupt occurs and the input queue is full or if a UART transmitter interrupt occurs and the output queue is empty), either discard the character that caused the interrupt and possibly echo a bell character (control-G) back to the serial port or don't output a character, respectively. If you choose to possibly echo a bell character on input queue full, whether or not that behavior is performed should be enabled or disabled by a physical device flag. Think about how to cause a character to be output on the corresponding output device. All input and output from/to UART5 should now use interrupt-driven I/O rather than non-interrupt driven (polled) I/O. c. Timer routines for a different timer (the PDB0 timer) that can be used by a user through a supervisor call interface. The user should be able to set the timer time period and furnish a function to be called from the interrupt routine when the timer interrupt occurs. The range of time periods available to the user should include from 50 ms to 1 second. You must allow the interval to be set to exactly 1 second. There is *no* requirement for the 50 ms interval to be able to be set exactly. You may find the PRESCALER and MULT fields in the PDBx_SC register on labeled page 1181 (PDF page 1188) of the K70 Sub-Family Reference Manual, Rev. 4, Oct-2015 to be helpful. This timer should be a one-shot -- that is, it should occur only once after being requested, not continuously. The user function to be called should be quite simple since it is called from the interrupt routine and may be running on the interrupt stack and with elevated interrupt priority level. This implementation of the supervisor call to initiate a user one-shot timer that will call a user function is problematic in that it allows a user to furnish the address of a function that is called from the interrupt routine. Even though this is a security hole in your OS -- because the function may perform an operation that would not be valid in thread mode or because the function may access memory locations that would not be accessible in thread mode, we will allow this to happen. d. Implement a shell command to set the date and time. This shell command should be named "date" and must accept a single integral argument which is the number of milliseconds since the MS-DOS epoch of midnight (zero hours) on January 1, 1980. (10 Points) Extra credit: Modify the "date" command to accept a single argument which is a simplified ISO 8601 date/time string in the form 2017-04-29T14:30. Note that the input string does not include seconds or fractions of seconds. You must reject any invalid input date/time with an appropriate error message. e. Add a shell command to display the current date and time. This command will use the same command name "date," but will display the current date and time when invoked without any arguments. f. Use the current time and date maintained by the FlexTimer in part a above to update the FAT32 required "last modification date and time" in directory entries. This last modification date and time should be written/updated when a new regular file or directory is created and also when an fclose SVC/system call is executed when a regular file has been modified. Note that when a regular file has been modified, that file's directory entry needs to be updated to contain the file's new size in bytes; when this operation is performed, always update the last modified date and time, as well. Your "ls" command must also be able to display the modification date and time for each file, if it doesn't already do this. This output could be an option when the a "-l" switch or another switch is utilized, or it's fine to display the modification date and time when no switch is specified. The date and time should be displayed with its full precision and in a human-readable format. For extra credit, correctly maintain the creation date and time and the last access date in directory entries for regular files, in addition to maintaining the last modification date and time. For extra credit, correctly maintain the last modification date and time in directory entries for *directories*. Correctly implementing this feature requires that the last modification date and time for a directory is updated whenever the content of that directory is changed (i.e., either a regular file or directory is added to or deleted from the directory). Do *not* update the last modification date and time when a regular file or directory in the directory is updated. g. Implement a shell command named "flashled" that uses the user timer supervisor calls in problem "c" above to flash the orange LED on and off approximately every half a second (the LED will light approximately once a second). End when SW1 is depressed. See the class web site for sample programs to perform all the tasks above at a basic level. Last revised 26-Mar-24