LearningMaterial ICT4 v6 0 Week11
LearningMaterial ICT4 v6 0 Week11
Laboratory Exercise 11
Interrupts & IO programming
Goals
After this laboratory exercise, you should understand the basic principles of
interrupts and how interrupts can be used for programming. You should also know
the difference between polling and using interrupts and the relative merits of these
methods.
Literature
■ Patterson and Hennessy: Chapter 2.7, 2.9, 2.10, 2.13, 5.7, Appendix A.6, A.7,
A.10
Polling or Interrupts
A computer can react to external events either by polling or by using interrupts.
One method is simpler, while the other one is more systematic and more efficient.
You will study the similarities and differences of these methods using a simple
“toy” example program.
Each pheriperal device connects to the CPU via a few ports. CPU uses address to
find out the respective port, and after that, CPU could read/write the new value to
these ports to get/control the device.
Preparation
Study literature and these home assignments before coming into the class.
4
Key matrix animation: http://hackyourmind.org/public/images/keypad12keys_anim.gif
Ha Noi University of Science and Technology
School of Information and Communication Technology
#------------------------------------------------------
# col 0x1 col 0x2 col 0x4 col 0x8
#
# row 0x1 0 1 2 3
# 0x11 0x21 0x41 0x81
#
# row 0x2 4 5 6 7
# 0x12 0x22 0x42 0x82
#
# row 0x4 8 9 a b
# 0x14 0x24 0x44 0x84
#
# row 0x8 c d e f
# 0x18 0x28 0x48 0x88
#
#------------------------------------------------------
# command row number of hexadecimal keyboard (bit 0 to 3)
# Eg. assign 0x1, to get key button 0,1,2,3
# assign 0x2, to get key button 4,5,6,7
# NOTE must reassign value for this address before reading,
# eventhough you only want to scan 1 row
.eqv IN_ADDRESS_HEXA_KEYBOARD 0xFFFF0012
# receive row and column of the key pressed, 0 if not key pressed
# Eg. equal 0x11, means that key button 0 pressed.
# Eg. equal 0x28, means that key button D pressed.
.eqv OUT_ADDRESS_HEXA_KEYBOARD 0xFFFF0014
Ha Noi University of Science and Technology
School of Information and Communication Technology
.text
main: li $t1, IN_ADDRESS_HEXA_KEYBOARD
li $t2, OUT_ADDRESS_HEXA_KEYBOARD
li $t3, 0x08 # check row 4 with key C, D,
E, F
Vietnamese support:
Cũng như các bộ xử lý khác, MIPS có 3 service với cùng một nguyên lý, nhưng
khác nhau về mục đích sử dụng
- Exception: xảy ra khi có lỗi trong quá trình chạy, chẳng hạn tham chiếu bộ
nhớ không hợp lệ.
- Trap: xảy ra bởi cách lệnh kiểm tra
- Interrupt: do các thiết bị bên ngoài kích hoạt
Cả 3 cơ chế trên đều được gọi chung là Exception.
Cách thức hoạt động: khi một exception xảy ra
- Khi có một Exception xảy ra, MIPS sẽ luôn nhảy tới địa chỉ cố định
0x80000180 để thực hiện chương trình con phục vụ ngắt. Để viết chương
trình con phục vụ ngắt, sử dụng chỉ thị .ktext để viết code ở địa chỉ
0x80000180 nói trên.
- Bộ đồng xử lý C0, thanh ghi $12 (status) sẽ bật bit 1
- Bộ đồng xử lý C0, thanh ghi $13 (cause) sẽ thay đổi các bit 2~6 cho biết
nguyên nhân gây ra ngắt
- Bộ đồng xử lý C0, thanh ghi $14 (epc) sẽ chứa địa chỉ kế tiếp của chương
trình chính, để quay trở về sau khi xử lý các đoạn mã Exception xong. (giống
như thanh ghi $ra)
- Trường hợp thanh ghi $13 (cause) cho biết nguyên nhân làm tham chiếu
địa chỉ bộ nhớ không hợp lệ, thanh ghi $8 (vaddr) sẽ chứa địa chỉ lỗi đó.
- Nếu không có mã lệnh nào ở địa chỉ 0x80000180 (.ktext), chương trình sẽ
hiện thông báo lỗi và tự kết thúc.
- Sau khi kết thúc chương trình con, sử dụng lệnh eret để quay trở lại chương
btrình chính. Lệnh eret sẽ gán nội dung thanh ghi PC bằng giá trị trong
thanh ghi $14 (epc).
Ha Noi University of Science and Technology
School of Information and Communication Technology
Tuy nhiên, lưu ý rằng, trong MARS, thanh ghi PC vẫn chứa địa chỉ của lệnh
mà ngắt xảy ra, tức là lệnh đã thực hiện xong, chứ không chứa địa chỉ của
lệnh kế tiếp. Bởi vậy phải tự lập trình để tăng địa chỉ chứa trong thanh ghi
epc bằng cách sử dụng 2 lệnh mfc0 (để đọc thanh ghi trong bộ đồng xử lý
C0) và mtc0 (để ghi giá trị vào thanh ghi trong bộ đồng xử lý C0)
mfc0 $at, $14 # $at <= Coproc0.$14 = Coproc0.epc
addi $at, $at, 4 # $at = $at + 4 (next instruction)
mtc0 $at, $14 # Coproc0.$14 = Coproc0.epc <= $at
- Các bit 8-15 của thanh ghi $13 được sử dụng để xác định nguyên nhân gây
ra ngắt. Hãy đọc thanh ghi này, kết hợp với thông tin chi tiết trong hướng
dẫn sử dụng của từng thiết bị giả lập để biết được nguồn gốc gây ra ngắt.
Cách thức viết chương trình phục vụ ngắt: để viết chương trình con phục vụ ngắt
khi có sự kiện ngắt xảy ra, có thể dùng một trong các phương pháp sau:
1. Viết chương trình con phục vụ ngắt trong cùng một file nguồn
2. Viết chương trình con phục vụ ngắt trong file nguồn độc lập, và lưu trữ
trong cùng một thư mục với chương trình chính. Sau đó, sử dụng tính năng
trong mục Settings là “Assemble all files in directory”.
3. Viết chương trình con phục vụ ngắt trong file nguồn độc lập, và lưu trữ
trong cùng một thư mục bất kì. Sau đó, sử dụng tính năng trong mục Settings
là “Exception Handler…”.
.data
Message: .asciiz "Oh my god. Someone's presed a button.\n"
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN Procedure
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.text
main:
#---------------------------------------------------------
# Enable interrupts you expect
#---------------------------------------------------------
# Enable the interrupt of Keyboard matrix 4x4 of Digital Lab
Sim
li $t1, IN_ADDRESS_HEXA_KEYBOARD
li $t3, 0x80 # bit 7 of = 1 to enable interrupt
sb $t3, 0($t1)
#---------------------------------------------------------
# No-end loop, main program, to demo the effective of
interrupt
#---------------------------------------------------------
Loop: nop
nop
Ha Noi University of Science and Technology
School of Information and Communication Technology
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GENERAL INTERRUPT SERVED ROUTINE for all interrupts
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ktext 0x80000180
#--------------------------------------------------------
# Processing
#--------------------------------------------------------
IntSR: addi $v0, $zero, 4 # show message
la $a0, Message
syscall
#--------------------------------------------------------
# Evaluate the return address of main routine
# epc <= epc + 4
#--------------------------------------------------------
next_pc:mfc0 $at, $14 # $at <= Coproc0.$14 = Coproc0.epc
addi $at, $at, 4 # $at = $at + 4 (next instruction)
mtc0 $at, $14 # Coproc0.$14 = Coproc0.epc <= $at
.data
Message: .asciiz "Key scan code "
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN Procedure
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.text
main:
#---------------------------------------------------------
# Enable interrupts you expect
#---------------------------------------------------------
# Enable the interrupt of Keyboard matrix 4x4 of Digital Lab
Sim
li $t1, IN_ADDRESS_HEXA_KEYBOARD
li $t3, 0x80 # bit 7 = 1 to enable
sb $t3, 0($t1)
#---------------------------------------------------------
# Loop an print sequence numbers
#---------------------------------------------------------
xor $s0, $s0, $s0 # count = $s0 = 0
Loop: addi $s0, $s0, 1 # count = count + 1
Ha Noi University of Science and Technology
School of Information and Communication Technology
prn_seq:addi $v0,$zero,1
add $a0,$s0,$zero # print auto sequence number
syscall
prn_eol:addi $v0,$zero,11
li $a0,'\n' # print endofline
syscall
sleep: addi $v0,$zero,32
li $a0,300 # sleep 300 ms
syscall
nop # WARNING: nop is mandatory here.
b Loop # Loop
end_main:
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GENERAL INTERRUPT SERVED ROUTINE for all interrupts
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ktext 0x80000180
#-------------------------------------------------------
# SAVE the current REG FILE to stack
#-------------------------------------------------------
IntSR: addi $sp,$sp,4 # Save $at because we may change it later
sw $at,0($sp)
addi $sp,$sp,4 # Save $sp because we may change it later
sw $v0,0($sp)
addi $sp,$sp,4 # Save $a0 because we may change it later
sw $a0,0($sp)
addi $sp,$sp,4 # Save $t1 because we may change it later
sw $t1,0($sp)
addi $sp,$sp,4 # Save $t3 because we may change it later
sw $t3,0($sp)
#--------------------------------------------------------
# Processing
#--------------------------------------------------------
prn_msg:addi $v0, $zero, 4
la $a0, Message
syscall
get_cod:li $t1, IN_ADDRESS_HEXA_KEYBOARD
li $t3, 0x88 # check row 4 and re-enable bit 7
sb $t3, 0($t1) # must reassign expected row
li $t1, OUT_ADDRESS_HEXA_KEYBOARD
lb $a0, 0($t1)
prn_cod:li $v0,34
syscall
li $v0,11
li $a0,'\n' # print end of line
syscall
#--------------------------------------------------------
# Evaluate the return address of main routine
# epc <= epc + 4
#--------------------------------------------------------
next_pc:mfc0 $at, $14 # $at <= Coproc0.$14 = Coproc0.epc
addi $at, $at, 4 # $at = $at + 4 (next instruction)
mtc0 $at, $14 # Coproc0.$14 = Coproc0.epc <= $at
#--------------------------------------------------------
# RESTORE the REG FILE from STACK
#--------------------------------------------------------
restore:lw $t3, 0($sp) # Restore the registers from stack
addi $sp,$sp,-4
lw $t1, 0($sp) # Restore the registers from stack
addi $sp,$sp,-4
lw $a0, 0($sp) # Restore the registers from stack
addi $sp,$sp,-4
lw $v0, 0($sp) # Restore the registers from stack
Ha Noi University of Science and Technology
School of Information and Communication Technology
addi $sp,$sp,-4
lw $at, 0($sp) # Restore the registers from stack
addi $sp,$sp,-4
.data
msg_keypress: .asciiz "Someone has pressed a key!\n"
msg_counter: .asciiz "Time inteval!\n"
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN Procedure
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.text
main:
#---------------------------------------------------------
# Enable interrupts you expect
#---------------------------------------------------------
# Enable the interrupt of Keyboard matrix 4x4 of Digital Lab
Sim
li $t1, IN_ADDRESS_HEXA_KEYBOARD
li $t3, 0x80 # bit 7 = 1 to enable
sb $t3, 0($t1)
#---------------------------------------------------------
# Loop a print sequence numbers
#---------------------------------------------------------
Ha Noi University of Science and Technology
School of Information and Communication Technology
Loop: nop
nop
nop
sleep: addi $v0,$zero,32 # BUG: must sleep to wait for Time
Counter
li $a0,200 # sleep 200 ms
syscall
nop # WARNING: nop is mandatory here.
b Loop
end_main:
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GENERAL INTERRUPT SERVED ROUTINE for all interrupts
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ktext 0x80000180
IntSR: #--------------------------------------------------------
# Temporary disable interrupt
#--------------------------------------------------------
dis_int:li $t1, COUNTER # BUG: must disable with Time Counter
sb $zero, 0($t1)
# no need to disable keyboard matrix interrupt
#--------------------------------------------------------
# Processing
#--------------------------------------------------------
get_caus:mfc0 $t1, $13 # $t1 = Coproc0.cause
IsCount:li $t2, MASK_CAUSE_COUNTER# if Cause value confirm
Counter..
and $at, $t1,$t2
beq $at,$t2, Counter_Intr
IsKeyMa:li $t2, MASK_CAUSE_KEYMATRIX # if Cause value confirm Key..
and $at, $t1,$t2
beq $at,$t2, Keymatrix_Intr
others: j end_process # other cases
.text
li $k0, KEY_CODE
li $k1, KEY_READY
li $s0, DISPLAY_CODE
li $s1, DISPLAY_READY
loop: nop
WaitForKey: lw $t1, 0($k1) # $t1 = [$k1] = KEY_READY
beq $t1, $zero, WaitForKey # if $t1 = 0 then Polling
MakeIntR: teqi $t1, 1 # if $t1 = 1 then raise an Interrupt
j loop
#---------------------------------------------------------------
# Interrupt subroutine
#---------------------------------------------------------------
.ktext 0x80000180
get_caus: mfc0 $t1, $13 # $t1 = Coproc0.cause
IsCount: li $t2, MASK_CAUSE_KEYBOARD# if Cause value confirm
Keyboard..
and $at, $t1,$t2
beq $at,$t2, Counter_Keyboard
j end_process
Counter_Keyboard:
ReadKey: lw $t0, 0($k0) # $t0 = [$k0] = KEY_CODE
end_process:
next_pc: mfc0 $at, $14 # $at <= Coproc0.$14 = Coproc0.epc
addi $at, $at, 4 # $at = $at + 4 (next instruction)
mtc0 $at, $14 # Coproc0.$14 = Coproc0.epc <= $at
return: eret # Return from exception
Ha Noi University of Science and Technology
School of Information and Communication Technology
Assignment 1
Create a new project, type in, and build the program of Home Assignment 1.
Upgrade the source code so that it could detect all 16 key buttons, from 0 to F.
Assignment 2
Create a new project, type in, and build the program of Home Assignment 2.
Assignment 3
Create a new project, type in, and build the program of Home Assignment 3.
Upgrade the source code so that it could detect all 16 key buttons, from 0 to F.
Assignment 4
Create a new project, type in, and build the program of Home Assignment 4.
Assignment 5
Create a new project, type in, and build the program of Home Assignment 5.
Conclusions
Before you finish the laboratory exercise, think about the questions below:
■ What is polling?
■ What are interrupts?
■ What are interrupt routines?
■ What are the advantages of polling?
■ What are the advantages of using interrupts?
■ What are the differences between interrupts, exceptions, and traps?