CMPE 401 - Computer Interfacing

Assignment #1 Solutions

Due: In the CMPE 401 assignment box at 15:45 on Friday, Oct. 3, 2008


  1. Briefly explain the difference between synchronous and asynchronous interfaces. What are the advantages and disadvantages of asynchronous compared to synchronous interfaces?

    [8 marks]
    A synchronous interface uses the same clock signal for both the receiver and transmitter hardware, while an asynchronous interface uses clock signals produced by physically distinct and independent clocks. Asynchronous clock signals must be synchronized with each other periodically, such as at the beginning of each data packet transmission.

    The main advantage of a synchronous interface is that if the clock deviates in frequency or shifts phase, then the transmitter and receiver remain synchronized. The main disadvantage of a synchronous interface is that wiring is required to distribute the common clock signal.
    The main advantage of using an asynchronous interface is that less wiring is required; in fact, no wiring is required to communicate the clock signal between the transmitter and receiver. A disadvantage of an asynchronous interface is that the receiver clock must be resynchronized periodically with the transmitter clock to compensate for the accumulation of relative phase shifts over time.

  2. Briefly explain what is meant the term "memory-mapped input/output"? What would be an alternative to memory-mapped I/O? What are the main advantages of memory-mapped I/O compared to the alternatives?

    [12 marks]
    Memory-mapped input/output is the technique where input/output devices are accessed through registers in the same way as memory locations. Registers in the peripheral devices are mapped to addresses in the CPU's memory space. With memory mapping, no special instructions are required to control the peripheral devices; they can be accessed using ordinary data movement instructions.
    An alternative method for accessing I/O would be to use special I/O registers that are accessed using special I/O instructions (not the normal data movement instructions). The instruction set for such "port-mapped" I/O would be slightly more complicated. But it might be easier to enforce security since the I/O instructions could be made "privileged".
    The advantage of memory-mapped I/O is that regular instructions can be used to access I/O devices through status, control and data registers. With memory-mapped I/O the address map of the computer can be re-organized easily (by changing the address decoding) to accommodate changes in hardware (e.g. addition of new memory and/or new I/O devices). No special I/O instructions are required, so the CPU instruction set is a little simpler with memory-mapped I/O.

  3. The two program counter addressing modes, described on slide 2-41 of the lecture notes, can be used to specify the location of source operands, but not destination operands. This is different from the situation for the otherwise similar address register indirect addressing modes, which can be used for both source and destination operands. Why do you suppose this restriction was placed on the program counter addressing modes?

    [5 marks]
    Allowing the user to do relative addressing was meant to allow the program code to be relocatable in memory when loaded. In this way if the programmer wanted to access data at a certain location, a relative location could be programmed instead of a hard-coded address. Having hard-coded address locations restricts the program to one location, and moving the program in memory would require updating all of these hard coded addresses.

    Restricting PC-relative addressing to source operands is done to increase safety. Allowing the user to perform PC-relative addressing means the user could potentially access the program source code. If this source code was accidentally or purposely modified, difficult-to-diagnose problems with the correct operation of the program might develop, or self-modifying code could be created.

  4. Consult the Coldfire Family Programmer's Reference Manual by clicking on CFPRM.pdf in the on-line version of this handout, and then determine what the MOVEM.L instruction does. In particular, explain what the following two instructions do:
             MOVEM.L  A0-A5/D7,-(SP)
             MOVEM.L  (SP)+,A7/D0-D5
      
    [12 marks]
    MOVEM is the move multiple registers instruction. This moves the contents from selected registers to consecutive memory locations starting at the location provided. The order in which the registers are moved is from D0-D7 then A0-A7.

    MOVEM.L A0-A5/D7,-(SP) moves longword values from registers A0-A5/D7 to consecutive stack locations. The stack pointer is decremented by 4 before the contents of each register are moved. MOVEM.L (SP)+,A7/D0-D5 moves longword values from the stack to A7/D0-D5. The stack pointer is incremented by 4 after each the contents of each register are loaded.

  5. Design a subrountine in ColdFire assembly language, to be called RD_STA_FIELDS, that reads a memory-mapped longword register at symbolic address STAT_REG and then extracts three bit fields as follows. The first field contains the 3 most significant bits in the register (i.e. bits #31-29) concatenated with the 5 least significant bits of the register (bits #4-0). The second field contains the eight bits at positions #28-21. The third field contains the 16 bits at positions #20-5, but with the bits arranged in the reverse order. The first, second and third fields are to be returned in D0.B, D1.B and A2.W, respectively. The contents of no other CPU registers are to be disturbed after the execution of the subroutine.

    [27 marks]
    RD_STA_FIELDS:
    	MOVE.L		D2,-(SP)	/* save temporary register */
    
    	/* Field 1 */
    	MOVE.L		STAT_REG, D2	/* get original longword */
    	CLR.L		D0		/* clear field 1 return register */
    	AND.L		#0xE000001F, D2	/* mask unnecessary bits */
    	MOVE.B		D2, D0		/* move bits 4-0 to return reg */
    	LSR.L		#8, D2		/* shift to get bits 31-29 */
    	LSR.L		#8, D2		/* note: LSR takes immediate values */
    	LSR.L		#8, D2		/* from 1 - 8 only */
    	OR.L		D2, D0		/* move bits 31-29 to return reg */
    
    	/* Field 2 */
    	MOVE.L		STAT_REG, D2	/* get original longword */
    	CLR.L		D1		/* clear field 2 return register */
    	AND.L		#0x1FE00000, D2	/* mask unnecessary bits */
    	LSR.L		#8, D2		/* shift to get bits 28-21 */
    	LSR.L		#8, D2		
    	LSR.L		#5, D2		
    	MOVE.B		D2, D1		/* move bites 28-21 to return reg */
    
    	/* Field 3 */
    	MOVE.L		STAT_REG, D2	/* get original longword */
    	CLR.L		A2		/* clear field 3 return register */
    	AND.L		#0x001FFFE0, D2	/* mask unnecessary bits */
    	LSR.L		#5, D2		/* shift to get bits 20-5 right aligned */
    	BITREV.L	D2		/* reverse bit order to desired order */
    	LSR.L		#8, D2		/* shift to get bits 20-5 right aligned */
    	LSR.L		#8, D2		
    	MOVE.W		D2, A2		/* move bites 20-5 to return reg */
    
    	MOVE.L		(SP)+, D2	/* restore temporary register */
    	RTS				/* return from subroutine */
    
    Notes: MOVE.B and MOVE.W takes low order bytes or words. When saving and restoring temporary registers, do not save/restore D0, D1 or A2 because these will be changed at the end. If you restore them, then you will overwrite your return values just before the RTS.

  6. There are various possible ways of implementing multitasking, where the available execution time on the CPU is shared using some mechanism or rule. Briefly describe round robin time slicing, pre-emptive multitasking, and co-operative multitasking. Be sure to highlight the likely strengths and weaknesses of these three multitasking schemes. Which scheme would be most appropriate for handling hard real time constraints? Carefully justify your answer.

    [19 marks]
    Round robin time slicing schedules tasks to be repeatedly scheduled to run on the CPU, in some fixed order and for equal intervals or "slices" of time. The context switches between tasks are conveniently caused by a regular sequence of interrupts from a hardware timer. The main advantage of round robin time slicing is its fairness. All tasks are guaranteed to run for an equal amount of time. A potential weakness is that if are important tasks that need to be executed, they will still have share the CPU with less critical tasks. This method is also sensitive to the length of time slices, and the variance in time required by tasks. If the time slices for most tasks is not appropriate, a lot of time might be spent idling waiting for time slots to run out. Conversely, it the tasks are switched too often then too much CPU time would be wasted in the context switching actions.

    Pre-emptive multitasking allows tasks to run depending on task priority. Each task is assigned a priority number, and usually the same priority number cannot be assigned to more than one task (that is, the priorities are unique). The highest priority task at any time is always scheduled to run on the CPU. The only time that a lower priority task can execute is if all other higher priority tasks are blocked (say waiting for timers or semaphores). If some event causes a high priority task to become unblocked, then it will immediately be scheduled to run on the CPU instead of a lower priority task. An advantage of pre-emptive multitasking is that, by using high-priority tasks to handle more time-critical activities in the system, the system will be able to provide more predictable real-time response times to events. A potential disadvantage of pre-emtive multitasking is that low priority tasks may be starved of execution time on the CPU if too often there is a ready-to-run higher priority task.

    Co-operative multitasking relys on the tasks to give up control of the CPU voluntarily. When a task gets control over the CPU, the task gives up control after it has completed running or needs to wait. The advantage of this method is it ensures a task completes the desired execution (critical sections) on the CPU before giving up control. The drawback is it relys on the individual tasks to share the CPU placing the responsibility on the programmer to ensure that all tasks co-operate to meet the system objectives.

    In order to handle hard real-time constraints, pre-emptive multitasking is likely to be the most effective. This is because predictable response times are important. By using pre-emptive multitasking, the tasks that must handle the hard real-time contraints can be set to a high priority to ensure they are run promptly.

  7. MicroC/OS requires the private stack data structures for tasks to be 4-byte-aligned. Given the properties of the ColdFire microprocessor, why do you suppose that this storage constraint would be required?

    [5 marks]
    The ColdFire instruction set was derived from the 68000 microprocessor, which provided roughly equal support to byte-size, word-sized and longword-size operands. However, to simplify the design of the CPU, many of the word-sized addressing modes were dropped from the instruction set. This makes the handling of data within the CPU more predictable and more easily pipelined (for faster execution). Thus the ColdFire has been optimized for handling longwords, and this fact has been taken into account in the design of the MicroC/OS data structures.
    By requiring private stack data structures to be 4-byte-aligned, MicroC/OS ensures that information is stored in a predictable manner so it can be read easily and quickly. If they were not 4-byte-aligned, there is the potential for information to be misaligned so that one longword would be in two adjacent memory locations. In order to retrieve the full longword, two reads would be required which is less efficient and cannot be pipelined without some added complexity.

  8. MicroC/OS provides two simple ways of disabling task interleaving to protect critical sections: (a) USER_ENTER_CRITICAL and USER_EXIT_CRITICAL, and (b)OSLock and OSUnlock. What would be advantages and disadvantages of these two ways compared with each other, and then compared with using a binary semaphore.

    [12 marks]
    When using critical sections restrictions, all interrupts are masked while locking restrictions prevents multitasking. The advantage of (a) is the certainty that nothing will prevent program execution, including interrupts. Using (b) can allows tasks to be interrupted but prevents higher priority tasks from executing. The advantage of using (b) is that it only affects multitasking, and will not prevent important interrupts from executing like (a) does. Comparing both of these to semphores, both (a) and (b) are very intrusive to the system as a whole, while the use of semaphores only affect the tasks that are involved.