Initial commit
This commit is contained in:
commit
1e0a16d131
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
""
|
336
malloc.asm
Normal file
336
malloc.asm
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
mvb .macro dst,imm
|
||||||
|
mov dst,#(:imm(2, $$symlen(imm)): & 0xffff)
|
||||||
|
movt dst,#(:imm(2, $$symlen(imm)): >> 16)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
daa .macro adr,imm,c1,c2
|
||||||
|
.asg :imm(1):,TMP1
|
||||||
|
.asg :imm(2, $$symlen(imm)-1):, LIT1
|
||||||
|
.asg :adr(1):,TMP2
|
||||||
|
.asg :adr(2, $$symlen(imm)-1):, LIT2
|
||||||
|
.if $$symlen(c1) = 0
|
||||||
|
.asg r0,c1
|
||||||
|
.endif
|
||||||
|
.if $$symlen(c2) = 0
|
||||||
|
.asg r1,c2
|
||||||
|
.endif
|
||||||
|
.if $$symcmp(TMP1,"#") = 0 & $$symcmp(TMP2,"#") = 0
|
||||||
|
mvb c1,adr
|
||||||
|
mov c2,imm
|
||||||
|
str c2,[c1]
|
||||||
|
.else
|
||||||
|
.emsg "Bad Macro Parameter"
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
.thumb
|
||||||
|
|
||||||
|
;; EXPORTS
|
||||||
|
.global gtmalloc
|
||||||
|
.global free
|
||||||
|
.global minit
|
||||||
|
.global memcpy
|
||||||
|
.global memset
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
vMB .equ 0x20000204
|
||||||
|
vME .equ 0x20007FFF
|
||||||
|
u15_mask .equ 0x7FFF
|
||||||
|
|
||||||
|
SIZE_MALLOC_META .equ 0x2 ; malloc block header metadata size
|
||||||
|
SIZE_MALLOC_HEAD .equ SIZE_MALLOC_META * 2 ; malloc block header size
|
||||||
|
MALLOC_BASE .field vMB ; malloc base address
|
||||||
|
MALLOC_END .field vME ; malloc end address
|
||||||
|
MALLOC_MAX .field vME - vMB ; malloc max allocation size
|
||||||
|
|
||||||
|
;; Parameters: r0 (size)
|
||||||
|
;; Return: r1 (ptr)
|
||||||
|
;; Clobbers: r0-r6
|
||||||
|
;; INFO: Allocates a sequence of bytes at the returned address that has a
|
||||||
|
;; length that is at least equal to that which was supplied in r0.
|
||||||
|
gtmalloc:
|
||||||
|
ldr r1,MALLOC_BASE
|
||||||
|
mov r3,#u15_mask
|
||||||
|
|
||||||
|
malloc_find: ;; Find a malloc block that fits the required size
|
||||||
|
ldrh r2,[r1,#SIZE_MALLOC_META] ; Load 'current' field from header
|
||||||
|
tst r2,#0x8000
|
||||||
|
bne malloc_find_next
|
||||||
|
cmp r2,r0
|
||||||
|
bcc malloc_find_next
|
||||||
|
b malloc_found
|
||||||
|
malloc_find_next:
|
||||||
|
; Mask out 'allocated' bit
|
||||||
|
and r2,r2,r3
|
||||||
|
|
||||||
|
; Point to next header
|
||||||
|
add r1,r1,r2
|
||||||
|
add r1,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
; Check if next header is valid
|
||||||
|
ldr r2,MALLOC_END
|
||||||
|
cmp r1,r2
|
||||||
|
beq malloc_error
|
||||||
|
b malloc_find
|
||||||
|
malloc_found:
|
||||||
|
; Mask out 'allocated' bit
|
||||||
|
;and r2,r2,r3
|
||||||
|
|
||||||
|
; Point to next header (in r2)
|
||||||
|
add r2,r1,r2
|
||||||
|
add r2,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
; r1 = 'adr'
|
||||||
|
; r2 = 'next'
|
||||||
|
|
||||||
|
ldrh r4,[r1,#SIZE_MALLOC_META] ; Load 'current' field from 'adr' header
|
||||||
|
and r4,r3
|
||||||
|
; r4 = adr->current.size
|
||||||
|
|
||||||
|
; Check if we have to overcommit
|
||||||
|
add r0,#4
|
||||||
|
cmp r4,r0
|
||||||
|
sub r0,#4
|
||||||
|
bcc malloc_found_overcommit
|
||||||
|
|
||||||
|
; r0 = 'total_allocated'
|
||||||
|
|
||||||
|
; Check if 'adr' is the last valid header in the heap
|
||||||
|
ldr r3,MALLOC_END
|
||||||
|
cmp r2,r3
|
||||||
|
beq malloc_found_lasthead
|
||||||
|
b malloc_found_regular
|
||||||
|
|
||||||
|
malloc_found_overcommit:
|
||||||
|
mov r0,r4
|
||||||
|
; r0 = 'total_allocated'
|
||||||
|
b malloc_end
|
||||||
|
|
||||||
|
malloc_found_lasthead:
|
||||||
|
; next = adr + sizeof(malloc_head) + size;
|
||||||
|
add r2,r1,r0
|
||||||
|
add r2,r2,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
ldr r3,MALLOC_END
|
||||||
|
sub r3,r3,r2
|
||||||
|
sub r3,r3,#SIZE_MALLOC_HEAD
|
||||||
|
strh r3,[r2,#SIZE_MALLOC_META]
|
||||||
|
b malloc_end
|
||||||
|
|
||||||
|
malloc_found_regular:
|
||||||
|
add r3,r1,r0
|
||||||
|
add r3,r3,#SIZE_MALLOC_HEAD
|
||||||
|
; r3 = 'new_next'
|
||||||
|
|
||||||
|
mov r4,r2
|
||||||
|
sub r4,r4,r3
|
||||||
|
sub r4,r4,#SIZE_MALLOC_HEAD
|
||||||
|
; r4 = next - (new_next + sizeof(malloc_head));
|
||||||
|
|
||||||
|
mov r6,#u15_mask
|
||||||
|
ldrh r5,[r2,#SIZE_MALLOC_META]
|
||||||
|
tst r5,#0x8000
|
||||||
|
and r5,r5,r6
|
||||||
|
bne malloc_found_regular_nextalloc
|
||||||
|
|
||||||
|
add r4,r4,r5
|
||||||
|
add r4,r4,#SIZE_MALLOC_HEAD
|
||||||
|
strh r4,[r3,#SIZE_MALLOC_META]
|
||||||
|
|
||||||
|
b malloc_found_end
|
||||||
|
|
||||||
|
malloc_found_regular_nextalloc:
|
||||||
|
strh r4,[r3,#SIZE_MALLOC_META]
|
||||||
|
strh r4,[r2]
|
||||||
|
|
||||||
|
malloc_found_end:
|
||||||
|
mov r2,r3
|
||||||
|
|
||||||
|
malloc_end: ;; Finalizes double-linked list headers and returns
|
||||||
|
orr r0,#0x8000
|
||||||
|
str r0,[r1,#SIZE_MALLOC_META]
|
||||||
|
strh r0,[r2]
|
||||||
|
|
||||||
|
add r1,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
malloc_error: ;; Return NULL
|
||||||
|
mov r1,#0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: r0 (ptr)
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r5
|
||||||
|
;; INFO: Frees a resource at a given pointer
|
||||||
|
free:
|
||||||
|
sub r0,#SIZE_MALLOC_HEAD
|
||||||
|
ldrh r1,[r0,#SIZE_MALLOC_META]
|
||||||
|
mov r2,#u15_mask
|
||||||
|
and r1,r1,r2
|
||||||
|
mov r4,r1
|
||||||
|
add r1,r1,r0
|
||||||
|
add r1,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
mov r5,#0 ; Mark that next block shouldn't be changed
|
||||||
|
|
||||||
|
; Check if next head is, in fact, the end of the heap
|
||||||
|
ldr r2,MALLOC_END
|
||||||
|
cmp r1,r2
|
||||||
|
beq free_mergeprev_last
|
||||||
|
|
||||||
|
; Check if we can merge the next block with the block being freed
|
||||||
|
ldrh r3,[r1,#SIZE_MALLOC_META]
|
||||||
|
tst r3,#0x8000
|
||||||
|
bne free_mergeprev_notlast
|
||||||
|
|
||||||
|
; Add next block's size + header size to current block
|
||||||
|
mov r2,#u15_mask
|
||||||
|
and r3,r3,r2
|
||||||
|
add r4,r4,r3
|
||||||
|
add r4,r4,#SIZE_MALLOC_HEAD
|
||||||
|
b free_mergeprev_last
|
||||||
|
|
||||||
|
free_mergeprev_notlast:
|
||||||
|
ldrh r3,[r1] ; Get 'next' blocks 'previous' field
|
||||||
|
mov r5,#u15_mask
|
||||||
|
and r3,r3,r5
|
||||||
|
mov r5,r1 ; Mark that next block should be updated
|
||||||
|
|
||||||
|
free_mergeprev_last: ;; Check if we can merge the block being freed with the previous block
|
||||||
|
; Check if there is a previous block
|
||||||
|
ldr r2,MALLOC_BASE
|
||||||
|
cmp r0,r2
|
||||||
|
beq free_end
|
||||||
|
|
||||||
|
; Check if previous block is allocated or not
|
||||||
|
ldrh r1,[r0]
|
||||||
|
tst r1,#0x8000
|
||||||
|
bne free_end
|
||||||
|
|
||||||
|
; Add previous block's size to the size: we're going to make the previous block the "master" now
|
||||||
|
add r4,r4,r1
|
||||||
|
add r4,r4,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
; Shift free pointer back to previous block head
|
||||||
|
sub r0,r0,r1
|
||||||
|
sub r0,r0,#SIZE_MALLOC_HEAD
|
||||||
|
|
||||||
|
free_end:
|
||||||
|
; Store size and unset 'allocated' bit
|
||||||
|
strh r4,[r0,#SIZE_MALLOC_META]
|
||||||
|
|
||||||
|
; Check if 'next' head has to be updated
|
||||||
|
cmp r5,#0
|
||||||
|
it eq
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
strh r4,[r5]
|
||||||
|
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
;; Parameters: void
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r1
|
||||||
|
;; INFO: Clears first metadata address for use by malloc.
|
||||||
|
minit:
|
||||||
|
ldr r0,MALLOC_BASE
|
||||||
|
ldr r1,MALLOC_MAX
|
||||||
|
sub r1,#SIZE_MALLOC_HEAD
|
||||||
|
lsl r1,#16
|
||||||
|
str r1,[r0]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: r0 (const ptr), r1 (ptr), r2 (len)
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r3
|
||||||
|
;; INFO: Copies (r2) bytes from r0 to r1.
|
||||||
|
memcpy: ;; Initialization
|
||||||
|
add r3,r0,r2
|
||||||
|
|
||||||
|
memcpy_loop: ;; Word-wise data copy
|
||||||
|
sub r2,r3,r0
|
||||||
|
cmp r2,#4
|
||||||
|
bcc memcpy_small
|
||||||
|
ldr r2,[r0]
|
||||||
|
str r2,[r1]
|
||||||
|
add r0,#4
|
||||||
|
add r1,#4
|
||||||
|
b memcpy_loop
|
||||||
|
|
||||||
|
memcpy_small: ;; Sub-word data copy
|
||||||
|
cmp r2,#0
|
||||||
|
it eq
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
cmp r2,#1
|
||||||
|
ittt eq
|
||||||
|
ldrbeq r3,[r0]
|
||||||
|
strbeq r3,[r1]
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
ldrh r3,[r0]
|
||||||
|
strh r3,[r1]
|
||||||
|
|
||||||
|
cmp r2,#3
|
||||||
|
ittt eq
|
||||||
|
ldrbeq r3,[r0,#2]
|
||||||
|
strbeq r3,[r1,#2]
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
ldrh r3,[r0,#2]
|
||||||
|
strh r3,[r1,#2]
|
||||||
|
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: r0 (ptr), r1 (byte), r2 (len)
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r3
|
||||||
|
;; INFO: Overwrites 'r2' bytes at the address specified by r0 with the lowest
|
||||||
|
;; byte in r1.
|
||||||
|
memset:
|
||||||
|
; Copy lowest byte in r1 to all 4 bytes in r1
|
||||||
|
and r1,#0xFF
|
||||||
|
mov r3,#0x101
|
||||||
|
movt r3,#0x101
|
||||||
|
mul r1,r1,r3
|
||||||
|
|
||||||
|
; Compute end of write range
|
||||||
|
add r3,r0,r2
|
||||||
|
memset_loop:
|
||||||
|
sub r2,r3,r0
|
||||||
|
cmp r2,#4
|
||||||
|
bcc memset_small
|
||||||
|
str r1,[r0]
|
||||||
|
add r0,#4
|
||||||
|
b memset_loop
|
||||||
|
|
||||||
|
memset_small:
|
||||||
|
cmp r2,#1
|
||||||
|
it cc
|
||||||
|
bxcc lr
|
||||||
|
|
||||||
|
itt eq
|
||||||
|
strbeq r1,[r0]
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
strh r1,[r0]
|
||||||
|
|
||||||
|
cmp r2,#3
|
||||||
|
itt eq
|
||||||
|
strbeq r1,[r0,#2]
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
strh r1,[r0,#2]
|
||||||
|
|
||||||
|
bx lr
|
54
nvmem.asm
Normal file
54
nvmem.asm
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
; Non-volatile memory routines
|
||||||
|
FLASH_base .field 0x400FD000 ; Flash control base address
|
||||||
|
SYSCONF .field 0x400FE000 ; System memory control base address
|
||||||
|
WRKEY0 .field 0x71D5 ; Write key when BOOTCFG address KEY bit is 0
|
||||||
|
WRKEY1 .field 0xA442 ; Write key when BOOTCFG address KEY bit is 1
|
||||||
|
FLASH_END .field 0x3FFFF ; End of flash memory region
|
||||||
|
|
||||||
|
; Flash control offsets
|
||||||
|
FMA .equ 0x0 ; Target address (0x0 - 0x3FFFF)
|
||||||
|
FMD .equ 0x4 ; Data
|
||||||
|
FMC .equ 0x8 ; Direct (single) write control - Writes 1 word
|
||||||
|
FMC2 .equ 0x20 ; Buffered (wide) write control - Writes up to 32 words
|
||||||
|
FWB_base .equ 0x100 ; Buffered data base offset (max: 0x17C)
|
||||||
|
BOOTCFG .equ 0x1D0 ; Boot configuration address offset
|
||||||
|
|
||||||
|
.text
|
||||||
|
.thumb
|
||||||
|
.global flashtest
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
;; Writes a value near then end of the flash region
|
||||||
|
;; Doesn't seem to survive resets, though
|
||||||
|
;; TODO: Investigate reset-triggered FLASH clearing
|
||||||
|
flashtest:
|
||||||
|
;; Read word
|
||||||
|
ldr r1,FLASH_END
|
||||||
|
sub r1,r1,#8
|
||||||
|
ldr r4,[r1] ; Read last word
|
||||||
|
|
||||||
|
;; Write word
|
||||||
|
; Write target address
|
||||||
|
ldr r0,FLASH_base
|
||||||
|
str r1,[r0,#FMA]
|
||||||
|
|
||||||
|
; Write data to add to FLASH
|
||||||
|
mvn r1,r4
|
||||||
|
str r1,[r0,#FMD]
|
||||||
|
|
||||||
|
; Trigger write
|
||||||
|
ldr r1,WRKEY0 ; TODO: Select appropriate WRKEY based on BOOTCFG
|
||||||
|
lsl r1,#0x10
|
||||||
|
orr r1,#1
|
||||||
|
str r1,[r0,#FMC]
|
||||||
|
|
||||||
|
flashtest_await_write:
|
||||||
|
ldrb r1,[r0,#FMC]
|
||||||
|
tst r1,#1
|
||||||
|
beq flashtest_complete
|
||||||
|
|
||||||
|
flashtest_aight:
|
||||||
|
b flashtest_await_write
|
||||||
|
|
||||||
|
flashtest_complete:
|
||||||
|
bx lr
|
529
pthread.asm
Normal file
529
pthread.asm
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
; Code-style key:
|
||||||
|
; [instruction/definition] ; Single-line description
|
||||||
|
; ;; Section label
|
||||||
|
; ; Code-block label
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; -- "Function" definition
|
||||||
|
; ;; Parameters: rX (type)
|
||||||
|
; ;; Return: rX (type), [flags] (reason)
|
||||||
|
; ;; Clobbers: rX-rY
|
||||||
|
; ;; INFO: General description of what the function does
|
||||||
|
;
|
||||||
|
; -- Note that functions should declare return values as clobbered.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; -- Function naming scheme:
|
||||||
|
;
|
||||||
|
; function: ;; Function's entry point
|
||||||
|
; [insn]
|
||||||
|
; function_localjumplabel: ;; Local jump label
|
||||||
|
; [insn]
|
||||||
|
; function_localjumplabel_sublabel: ;; Jump label that is a part of (or a child-label of) function_localjumplabel. (Think nested block-statements)
|
||||||
|
; [insn]
|
||||||
|
; function_end: ;; End of function (if explicit declaration is necessary)
|
||||||
|
; [insn]
|
||||||
|
|
||||||
|
|
||||||
|
mvb .macro dst,imm
|
||||||
|
mov dst,#(:imm(2, $$symlen(imm)): & 0xffff)
|
||||||
|
movt dst,#(:imm(2, $$symlen(imm)): >> 16)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
daa .macro adr,imm,c1,c2
|
||||||
|
.asg :imm(1):,TMP1
|
||||||
|
.asg :imm(2, $$symlen(imm)-1):, LIT1
|
||||||
|
.asg :adr(1):,TMP2
|
||||||
|
.asg :adr(2, $$symlen(imm)-1):, LIT2
|
||||||
|
.if $$symlen(c1) = 0
|
||||||
|
.asg r0,c1
|
||||||
|
.endif
|
||||||
|
.if $$symlen(c2) = 0
|
||||||
|
.asg r1,c2
|
||||||
|
.endif
|
||||||
|
.if $$symcmp(TMP1,"#") = 0 & $$symcmp(TMP2,"#") = 0
|
||||||
|
mvb c1,adr
|
||||||
|
mov c2,imm
|
||||||
|
str c2,[c1]
|
||||||
|
.else
|
||||||
|
.emsg "Bad Macro Parameter"
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
print .macro msg
|
||||||
|
adr r0,msg
|
||||||
|
bl strlen
|
||||||
|
adr r0,msg
|
||||||
|
bl printstring
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
; UART stuff
|
||||||
|
RCGCUART .equ 0x400FE618
|
||||||
|
RCGCGPIO .equ 0x400fe608
|
||||||
|
UART0_UARTIBRD .equ 0x4000c024
|
||||||
|
UART0_UARTFBRD .equ 0x4000c028
|
||||||
|
UART0_UARTLCRH .equ 0x4000c02c
|
||||||
|
UART0_UARTCTL .equ 0x4000c030
|
||||||
|
UART0_UARTFR .equ 0x4000c018
|
||||||
|
UART0_UARTDR .equ 0x4000c000
|
||||||
|
GPIOA_GPIOAFSEL .equ 0x40004420
|
||||||
|
GPIOA_GPIODEN .equ 0x4000451c
|
||||||
|
|
||||||
|
STRST .equ 0x989680
|
||||||
|
CPERIPH .equ 0xe000e000
|
||||||
|
STCTL .equ 0x010
|
||||||
|
STRLD .equ 0x014
|
||||||
|
STCUR .equ 0x18
|
||||||
|
VBASE .equ 0x20000000 ; RAM virtual memory base address
|
||||||
|
STACK_BASE .equ 0x20000200
|
||||||
|
HEAP_END .equ 0x20007FFF
|
||||||
|
TMPTR .field 0x20000200 ; Thread MUX config pointer address
|
||||||
|
TMS .equ 0x0 ; Thread MUX thread count
|
||||||
|
TMC .equ 0x4 ; Thread MUX current thread
|
||||||
|
TMF .equ 0x8 ; Thread MUX flag offset
|
||||||
|
TMV .equ 0xC ; Thread MUX address vector base address
|
||||||
|
TCOUNT_MAX .equ 0x20 ; Max thread vector count allowed
|
||||||
|
TFRAME_SIZE .equ 0x4 ; Thread MUX frame size
|
||||||
|
;TSTACK_PTR .equ 0x4 ; Thread stack pointer
|
||||||
|
;TEXEC_PTR .equ 0x0 ; Thread execution address
|
||||||
|
|
||||||
|
|
||||||
|
TEST_MESSAGE: .string "Hello, thread",13,10,0
|
||||||
|
|
||||||
|
.text
|
||||||
|
.thumb
|
||||||
|
|
||||||
|
;; EXPORTS
|
||||||
|
.global main
|
||||||
|
.global IntSysTick
|
||||||
|
.global startthread
|
||||||
|
.global threadexit
|
||||||
|
.global threadlock
|
||||||
|
.global threadunlock
|
||||||
|
|
||||||
|
;; IMPORTS
|
||||||
|
;.global flashtest
|
||||||
|
.global gtmalloc
|
||||||
|
.global minit
|
||||||
|
.global free
|
||||||
|
.global memcpy
|
||||||
|
.global memset
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
main:
|
||||||
|
; Initialize peripherals
|
||||||
|
bl inituart
|
||||||
|
|
||||||
|
; Initialize gtmalloc range
|
||||||
|
bl minit
|
||||||
|
|
||||||
|
; Allocate TMUX data
|
||||||
|
mov r0,#(0xC + (TCOUNT_MAX * TFRAME_SIZE))
|
||||||
|
bl gtmalloc
|
||||||
|
mov r0,r1
|
||||||
|
|
||||||
|
; Clear data pointed to by r0
|
||||||
|
push {r0}
|
||||||
|
mov r2,#(0xC + (TCOUNT_MAX * TFRAME_SIZE))
|
||||||
|
mov r1,#0
|
||||||
|
bl memset
|
||||||
|
pop {r0}
|
||||||
|
|
||||||
|
|
||||||
|
; Initialize Thread MUX Size value to 1 (main thread)
|
||||||
|
ldr r1,TMPTR
|
||||||
|
str r0,[r1]
|
||||||
|
mov r1,#1
|
||||||
|
str r1,[r0,#TMS]
|
||||||
|
|
||||||
|
; Initialize Thread MUX Current (int) to 0
|
||||||
|
mov r1,#0
|
||||||
|
str r1,[r0,#TMC]
|
||||||
|
|
||||||
|
; Thread execution address and stack are inferred from the blank frame
|
||||||
|
;str r1,[r0,#TMV]
|
||||||
|
;str r1,[r0,#(TMV + 4)]
|
||||||
|
|
||||||
|
|
||||||
|
; Enable SysTick (and thereby the thread management subsystem)
|
||||||
|
cpsid i ; disable interrupts
|
||||||
|
|
||||||
|
mvb r1,#CPERIPH
|
||||||
|
mvb r0,#STRST ; Set up SysTick to start counting down from STRST (max 24 bits)
|
||||||
|
str r0,[r1,#STRLD]
|
||||||
|
str r0,[r1,#STCUR]
|
||||||
|
|
||||||
|
ldr r0,[r1,#STCTL]
|
||||||
|
orr r0,#0x7 ; Enable system interrupt, set source to system clock (80 MHz), enable timer
|
||||||
|
str r0,[r1,#STCTL]
|
||||||
|
|
||||||
|
cpsie i ; enable interrupts
|
||||||
|
|
||||||
|
; Run thread test
|
||||||
|
adr r0,test_thread
|
||||||
|
bl startthread
|
||||||
|
|
||||||
|
loop: ; Wait forever
|
||||||
|
b loop
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
test_thread:
|
||||||
|
print TEST_MESSAGE
|
||||||
|
b threadexit ; No need to bl since this is the end of the thread anyway
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
;; Parameters: r0 (thread routine address)
|
||||||
|
;; Return: r0 (non-zero if succeeded)
|
||||||
|
;; Clobbers: r0-r6
|
||||||
|
;; INFO: This adds a new entry to the thread multiplexing vector. In the case
|
||||||
|
;; where (for some reason) there is an attempt >=2**32 threads, r0 will
|
||||||
|
;; be returned as 0 to indicate that an overflow was caught. This also
|
||||||
|
;; implies that the thread wasn't created, but that the program will
|
||||||
|
;; continue to execute as normal.
|
||||||
|
startthread:
|
||||||
|
push {r0,lr}
|
||||||
|
bl threadlock ; Ensure changes to TMUX data don't change while we are updating them
|
||||||
|
|
||||||
|
ldr r0,[r1,#TMS] ; Get current thread count
|
||||||
|
mov r2,r0 ; Duplicate it for future use
|
||||||
|
add r0,r0,#1
|
||||||
|
cmp r0,#TCOUNT_MAX
|
||||||
|
beq startthread_end ; If C-flag is set, then r0 == 0 and no more threads can be created: return
|
||||||
|
|
||||||
|
str r0,[r1,#TMS]
|
||||||
|
mov r0,#TFRAME_SIZE
|
||||||
|
mul r2,r2,r0 ; Multiply r2 by TFRAME_SIZE to get address offset for next thread address entry
|
||||||
|
|
||||||
|
pop {r0}
|
||||||
|
push {r1, r2}
|
||||||
|
|
||||||
|
bl initthreadstack ; Allocate a blank (but valid) thread stack
|
||||||
|
|
||||||
|
pop {r1, r2} ; Restore addresses
|
||||||
|
add r1,r1,r2
|
||||||
|
add r1,r1,#TMV
|
||||||
|
|
||||||
|
str r4,[r1] ; Store stack data pointer to threa frame
|
||||||
|
|
||||||
|
startthread_end:
|
||||||
|
bl threadunlock
|
||||||
|
pop {pc}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: void
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r1
|
||||||
|
threadlock:
|
||||||
|
ldr r1,TMPTR
|
||||||
|
ldr r1,[r1]
|
||||||
|
ldr r0,[r1,#TMF]
|
||||||
|
orr r0,#1
|
||||||
|
str r0,[r1,#TMF]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: void
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r2
|
||||||
|
threadunlock:
|
||||||
|
ldr r1,TMPTR
|
||||||
|
ldr r1,[r1]
|
||||||
|
mvn r2,#1
|
||||||
|
ldr r0,[r1,#TMF]
|
||||||
|
and r0,r0,r2
|
||||||
|
str r0,[r1,#TMF]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: void
|
||||||
|
;; Return: doesn't
|
||||||
|
;; Clobbers: N/A
|
||||||
|
threadexit:
|
||||||
|
; Mark this thread for termination by the thread handler
|
||||||
|
ldr r1,TMPTR
|
||||||
|
ldr r1,[r1]
|
||||||
|
|
||||||
|
; Thread0 cannot be killed; just sit in an infinite loop instead
|
||||||
|
ldr r0,[r1,#TMC]
|
||||||
|
cmp r0,#0
|
||||||
|
beq threadexit_wait
|
||||||
|
|
||||||
|
ldr r0,[r1,#TMF]
|
||||||
|
orr r0,#2
|
||||||
|
str r0,[r1,#TMF]
|
||||||
|
|
||||||
|
; Set SysTick counter to 0 (trigger SysTick interrupt)
|
||||||
|
mvb r1,#CPERIPH
|
||||||
|
mov r0,#0
|
||||||
|
str r0,[r1]
|
||||||
|
threadexit_wait:
|
||||||
|
; Wait for imminent SysTick interrupt to take over
|
||||||
|
b threadexit_wait
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
IntSysTick:
|
||||||
|
; CPU pushes some registers here (before ISR state is set and PC is changed):
|
||||||
|
; push {r0-r3, ip, lr, pc, CPSR}
|
||||||
|
; Check if we are interrupting an interrupt
|
||||||
|
mvn r0,#6
|
||||||
|
cmp r0,lr
|
||||||
|
it ne
|
||||||
|
bxne lr
|
||||||
|
|
||||||
|
; Check if there are any threads to multiplex. If not, just return
|
||||||
|
ldr r0,TMPTR
|
||||||
|
ldr r0,[r0]
|
||||||
|
ldr r1,[r0,#TMS] ; Load current thread count
|
||||||
|
cmp r1,#1
|
||||||
|
it eq
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
; Check if thread-lock flag is set. If so, return to active thread
|
||||||
|
ldr r2,[r0,#TMF]
|
||||||
|
tst r2,#1
|
||||||
|
it ne
|
||||||
|
bxne lr
|
||||||
|
|
||||||
|
; Check if thread-kill flag is set; if so, remove thread from address vector
|
||||||
|
tst r2,#2
|
||||||
|
beq IntSysTick_save
|
||||||
|
ldr r2,[r0,#TMC]
|
||||||
|
sub r1,#1
|
||||||
|
cmp r1,r2 ; Check if we are going to loop back to Thread1 after ISR
|
||||||
|
bne IntSysTick_fulldelete
|
||||||
|
|
||||||
|
sub r2,#1
|
||||||
|
str r2,[r0,#TMC]
|
||||||
|
str r1,[r0,#TMS]
|
||||||
|
b IntSysTick_loadnext
|
||||||
|
|
||||||
|
IntSysTick_fulldelete:
|
||||||
|
; Move future threads down to this one's position
|
||||||
|
push {r0-r3, lr}
|
||||||
|
|
||||||
|
; Compute current frame offset and how many frames to copy
|
||||||
|
mov r3,r1
|
||||||
|
mov r1,r2
|
||||||
|
mov r2,r3
|
||||||
|
mov r3,#TFRAME_SIZE
|
||||||
|
sub r2,r2,r1
|
||||||
|
mul r1,r3
|
||||||
|
mul r2,r3
|
||||||
|
|
||||||
|
; Get thread vector address
|
||||||
|
add r0,#TMV
|
||||||
|
|
||||||
|
; Offset base vector address by the current frame address
|
||||||
|
add r1,r1,r0
|
||||||
|
|
||||||
|
; Get address of next frame
|
||||||
|
add r0,r1,#TFRAME_SIZE
|
||||||
|
|
||||||
|
; Copy future frames to current frame address
|
||||||
|
bl memcpy
|
||||||
|
|
||||||
|
pop {r0-r3, lr}
|
||||||
|
|
||||||
|
b IntSysTick_loadnext
|
||||||
|
|
||||||
|
IntSysTick_save:
|
||||||
|
;; Store the current stack
|
||||||
|
; Compute frame offset and save link register value as current frame execution address pointer
|
||||||
|
mov r3,#TFRAME_SIZE
|
||||||
|
mul r2,r2,r3
|
||||||
|
add r2,r2,r0
|
||||||
|
add r2,r2,#TMV
|
||||||
|
|
||||||
|
mov r3,r0
|
||||||
|
|
||||||
|
push {r4-r11} ; Push all the otherwise un-pushed registers (except SP because it's special)
|
||||||
|
mvb r0,#STACK_BASE
|
||||||
|
sub r0,r0,sp ; Compute stack size that needs to be saved
|
||||||
|
add r0,r0,#4 ; Include SP in stack metadata
|
||||||
|
|
||||||
|
push {r0, r2, r3}
|
||||||
|
bl gtmalloc
|
||||||
|
pop {r0, r2, r3}
|
||||||
|
|
||||||
|
; r0 = gtmalloc size
|
||||||
|
; r1 = gtmalloc ptr
|
||||||
|
; r2 = pointer to current thread frame
|
||||||
|
; r3 = thread control base address
|
||||||
|
|
||||||
|
push {r0-r3}
|
||||||
|
|
||||||
|
sub r0,#4
|
||||||
|
mov r2,r0
|
||||||
|
mov r0,sp
|
||||||
|
add r0,r0,#16
|
||||||
|
add r1,r1,#4
|
||||||
|
|
||||||
|
; Copy all stack values except sp
|
||||||
|
bl memcpy
|
||||||
|
|
||||||
|
pop {r0-r3}
|
||||||
|
|
||||||
|
; Save sp to thread stack copy
|
||||||
|
str sp,[r1]
|
||||||
|
|
||||||
|
; Save thread stack copy pointer to frame
|
||||||
|
str r1,[r2]
|
||||||
|
|
||||||
|
IntSysTick_loadnext:
|
||||||
|
;; Load the next stack
|
||||||
|
; Load a fresh thread control pointer
|
||||||
|
ldr r0,TMPTR
|
||||||
|
ldr r0,[r0]
|
||||||
|
ldr r2,[r0,#TMC]
|
||||||
|
ldr r1,[r0,#TMS]
|
||||||
|
sub r1,r1,#1
|
||||||
|
cmp r1,r2 ; Check if we are going to loop back to Thread0 after ISR
|
||||||
|
ite eq
|
||||||
|
eoreq r2,r2
|
||||||
|
addne r2,#1
|
||||||
|
|
||||||
|
str r2,[r0,#TMC]
|
||||||
|
|
||||||
|
; Check frame integrity
|
||||||
|
mov r3,#TFRAME_SIZE
|
||||||
|
mul r2,r3
|
||||||
|
add r2,r2,r0
|
||||||
|
add r2,r2,#TMV
|
||||||
|
ldr r0,[r2] ; Load stack data pointer for thread to be run
|
||||||
|
|
||||||
|
|
||||||
|
ldr r1,[r0] ; Copy thread's stack pointer into r1
|
||||||
|
mov sp,r1 ; Activate thread's stack
|
||||||
|
|
||||||
|
; Copy thread's stack into active stack region
|
||||||
|
push {r0-r2}
|
||||||
|
mvb r2,#STACK_BASE
|
||||||
|
sub r2,r2,r1
|
||||||
|
add r0,#4
|
||||||
|
|
||||||
|
bl memcpy
|
||||||
|
pop {r0-r2}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
push {r2}
|
||||||
|
bl free ; Free thread stack-copy pointer
|
||||||
|
pop {r2}
|
||||||
|
|
||||||
|
mvn lr,#6 ; lr = 0xFFFFFFF9 // address informs processor that it should read return address from stack
|
||||||
|
|
||||||
|
pop {r4-r11} ; Pop values that aren't auto-popped
|
||||||
|
|
||||||
|
;; Resume thread at the given address
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Parameters: r0 (str), r1 (uint32_t)
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0-r5
|
||||||
|
;; INFO: Prints a string of a given length to UART0 serial bus
|
||||||
|
printstring: ; void printstring(char * r0, uint32_t r1){
|
||||||
|
mvb r2,#UART0_UARTFR ; r2 = UART0_UARTFR; // UART0 Flags
|
||||||
|
mvb r3,#UART0_UARTDR ; r3 = UART0_UARTDR; // UART0 Data address
|
||||||
|
add r1,r0 ; r1 += r0; // r1 now holds the address of the first byte after the string
|
||||||
|
printstring_loop: ; while (true) {
|
||||||
|
cmp r0,r1 ; if(r0 == r1) // Check if more bytes can be read
|
||||||
|
beq printstring_end ; break;
|
||||||
|
ldrb r4,[r0],#1 ; r4 = (char) *(r0++); // Put next char in r4
|
||||||
|
printstring_printchar_loop: ; while(true){
|
||||||
|
ldr r5,[r2] ; r5 = *r2; // Read UART0 status flags
|
||||||
|
ands r5,r5,#0x20 ; r5 &= 0x20; // Only get 6th flag bit
|
||||||
|
bne printstring_printchar_loop ; if(r5 != 0x20) continue; // If bit isn't set, UART0 isn't done flushing
|
||||||
|
; break;
|
||||||
|
; }
|
||||||
|
str r4,[r3] ; *r3 = r4; // Write character to UART0 data address
|
||||||
|
b printstring_loop ; continue;
|
||||||
|
printstring_end: ; }
|
||||||
|
bx lr ; return;
|
||||||
|
; }
|
||||||
|
|
||||||
|
;; Parameters: r0 (str)
|
||||||
|
;; Return: r1 (uint32_t)
|
||||||
|
;; Clobbers: r1, r2
|
||||||
|
;; INFO: Computes the length of a given C-style string.
|
||||||
|
strlen: ; uint32_t strlen(char * r0) {
|
||||||
|
mov r1,r0 ; r1 = r0;
|
||||||
|
strlen_loop: ; while(true){
|
||||||
|
ldrb r2,[r0], #1 ; r2 = (char) *(r0++);
|
||||||
|
cmp r2,#0 ; if(r2 != 0)
|
||||||
|
bne strlen_loop ; continue;
|
||||||
|
strlen_endloop: ; }
|
||||||
|
sub r1,r0,r1 ; r1 = r0 - r1;
|
||||||
|
bx lr ; return r1;
|
||||||
|
; }
|
||||||
|
|
||||||
|
;; Parameters: void
|
||||||
|
;; Return: void
|
||||||
|
;; Clobbers: r0, r1
|
||||||
|
;; INFO: Initialize UART0 communication bus at 115200 baud.
|
||||||
|
inituart:
|
||||||
|
daa #RCGCUART,#0x01 ; Koppla in serieport
|
||||||
|
|
||||||
|
mvb r1,#RCGCGPIO ; Koppla in GPIO port A
|
||||||
|
ldr r0,[r1]
|
||||||
|
orr r0,r0,#0x01
|
||||||
|
str r0,[r1]
|
||||||
|
|
||||||
|
nop ; vänta lite
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
daa #GPIOA_GPIOAFSEL,#0x03 ; pinnar PA0 och PA1 som serieport
|
||||||
|
daa #GPIOA_GPIODEN,#0x03 ; Digital I/O på PA0 och PA1
|
||||||
|
daa #UART0_UARTIBRD,#0x08 ; Sätt hastighet till 115200 baud
|
||||||
|
daa #UART0_UARTFBRD,#44 ; Andra värdet för att få 115200 baud
|
||||||
|
daa #UART0_UARTLCRH,#0x60 ; 8 bit, 1 stop bit, ingen paritet, ingen FIFO
|
||||||
|
daa #UART0_UARTCTL,#0x0301 ; Börja använda serieport
|
||||||
|
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
;; Parameters: r0 (thread pc)
|
||||||
|
;; Return: r4 (ptr)
|
||||||
|
;; Clobbers: r0-r6
|
||||||
|
;; INFO: Generate a blank stack frame
|
||||||
|
initthreadstack:
|
||||||
|
push {r0, lr} ; Save argument and return address
|
||||||
|
|
||||||
|
; Allocate thread stack
|
||||||
|
mov r0,#0x44
|
||||||
|
bl gtmalloc
|
||||||
|
mov r4,r1
|
||||||
|
|
||||||
|
; Clear thread stack data
|
||||||
|
mov r2,#0x38
|
||||||
|
mov r0,r1
|
||||||
|
add r0,#4
|
||||||
|
mov r1,#0
|
||||||
|
bl memset
|
||||||
|
|
||||||
|
pop {r0} ; Restore argument
|
||||||
|
|
||||||
|
; Save thread's PC (argument) to blank stack
|
||||||
|
str r0,[r4,#0x3C]
|
||||||
|
|
||||||
|
; Save a valid CPSR to the blank stack
|
||||||
|
mvb r0,#0x81000000
|
||||||
|
str r0,[r4,#0x40]
|
||||||
|
|
||||||
|
; Save a valid stack pointer
|
||||||
|
mvb r0,#(STACK_BASE - 0x40)
|
||||||
|
str r0,[r4]
|
||||||
|
|
||||||
|
pop {pc} ; Fast return
|
45
tm4c1231h6pm.cmd
Normal file
45
tm4c1231h6pm.cmd
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Default Linker Command file for the Texas Instruments TM4C1231H6PM
|
||||||
|
*
|
||||||
|
* This is derived from revision 15071 of the TivaWare Library.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
--retain=g_pfnVectors
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (RX) : origin = 0x00000000, length = 0x00040000
|
||||||
|
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following command line options are set as part of the CCS project. */
|
||||||
|
/* If you are building using the command line, or for some reason want to */
|
||||||
|
/* define them here, you can uncomment and modify these lines as needed. */
|
||||||
|
/* If you are using CCS for building, it is probably better to make any such */
|
||||||
|
/* modifications in your CCS project and leave this file alone. */
|
||||||
|
/* */
|
||||||
|
/* --heap_size=0 */
|
||||||
|
/* --stack_size=256 */
|
||||||
|
/* --library=rtsv7M4_T_le_eabi.lib */
|
||||||
|
|
||||||
|
/* Section allocation in memory */
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.intvecs: > 0x00000000
|
||||||
|
.text : > FLASH
|
||||||
|
.const : > FLASH
|
||||||
|
.cinit : > FLASH
|
||||||
|
.pinit : > FLASH
|
||||||
|
.init_array : > FLASH
|
||||||
|
|
||||||
|
.vtable : > 0x20000000
|
||||||
|
.data : > SRAM
|
||||||
|
.bss : > SRAM
|
||||||
|
.sysmem : > SRAM
|
||||||
|
.stack : > SRAM
|
||||||
|
}
|
||||||
|
|
||||||
|
__STACK_TOP = __stack + 512;
|
301
tm4c1231h6pm_startup_ccs.c
Normal file
301
tm4c1231h6pm_startup_ccs.c
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// Startup code for use with TI's Code Composer Studio.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2011-2014 Texas Instruments Incorporated. All rights reserved.
|
||||||
|
// Software License Agreement
|
||||||
|
//
|
||||||
|
// Software License Agreement
|
||||||
|
//
|
||||||
|
// Texas Instruments (TI) is supplying this software for use solely and
|
||||||
|
// exclusively on TI's microcontroller products. The software is owned by
|
||||||
|
// TI and/or its suppliers, and is protected under applicable copyright
|
||||||
|
// laws. You may not combine this software with "viral" open-source
|
||||||
|
// software in order to form a larger program.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
|
||||||
|
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
|
||||||
|
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
|
||||||
|
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
// DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// Forward declaration of the default fault handlers.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
void ResetISR(void);
|
||||||
|
static void NmiSR(void);
|
||||||
|
static void FaultISR(void);
|
||||||
|
static void IntDefaultHandler(void);
|
||||||
|
extern void IntSysTick(void);
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// External declaration for the reset handler that is to be called when the
|
||||||
|
// processor is started
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
extern void _c_int00(void);
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// Linker variable that marks the top of the stack.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
extern uint32_t __STACK_TOP;
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// External declarations for the interrupt handlers used by the application.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
// To be added by user
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// The vector table. Note that the proper constructs must be placed on this to
|
||||||
|
// ensure that it ends up at physical address 0x0000.0000 or at the start of
|
||||||
|
// the program if located at a start address other than 0.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
|
||||||
|
void (* const g_pfnVectors[])(void) =
|
||||||
|
{
|
||||||
|
(void (*)(void))((uint32_t)&__STACK_TOP),
|
||||||
|
// The initial stack pointer
|
||||||
|
ResetISR, // The reset handler
|
||||||
|
NmiSR, // The NMI handler
|
||||||
|
FaultISR, // The hard fault handler
|
||||||
|
IntDefaultHandler, // The MPU fault handler
|
||||||
|
IntDefaultHandler, // The bus fault handler
|
||||||
|
IntDefaultHandler, // The usage fault handler
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // SVCall handler
|
||||||
|
IntDefaultHandler, // Debug monitor handler
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // The PendSV handler
|
||||||
|
IntSysTick, // The SysTick handler
|
||||||
|
IntDefaultHandler, // GPIO Port A
|
||||||
|
IntDefaultHandler, // GPIO Port B
|
||||||
|
IntDefaultHandler, // GPIO Port C
|
||||||
|
IntDefaultHandler, // GPIO Port D
|
||||||
|
IntDefaultHandler, // GPIO Port E
|
||||||
|
IntDefaultHandler, // UART0 Rx and Tx
|
||||||
|
IntDefaultHandler, // UART1 Rx and Tx
|
||||||
|
IntDefaultHandler, // SSI0 Rx and Tx
|
||||||
|
IntDefaultHandler, // I2C0 Master and Slave
|
||||||
|
IntDefaultHandler, // PWM Fault
|
||||||
|
IntDefaultHandler, // PWM Generator 0
|
||||||
|
IntDefaultHandler, // PWM Generator 1
|
||||||
|
IntDefaultHandler, // PWM Generator 2
|
||||||
|
IntDefaultHandler, // Quadrature Encoder 0
|
||||||
|
IntDefaultHandler, // ADC Sequence 0
|
||||||
|
IntDefaultHandler, // ADC Sequence 1
|
||||||
|
IntDefaultHandler, // ADC Sequence 2
|
||||||
|
IntDefaultHandler, // ADC Sequence 3
|
||||||
|
IntDefaultHandler, // Watchdog timer
|
||||||
|
IntDefaultHandler, // Timer 0 subtimer A
|
||||||
|
IntDefaultHandler, // Timer 0 subtimer B
|
||||||
|
IntDefaultHandler, // Timer 1 subtimer A
|
||||||
|
IntDefaultHandler, // Timer 1 subtimer B
|
||||||
|
IntDefaultHandler, // Timer 2 subtimer A
|
||||||
|
IntDefaultHandler, // Timer 2 subtimer B
|
||||||
|
IntDefaultHandler, // Analog Comparator 0
|
||||||
|
IntDefaultHandler, // Analog Comparator 1
|
||||||
|
IntDefaultHandler, // Analog Comparator 2
|
||||||
|
IntDefaultHandler, // System Control (PLL, OSC, BO)
|
||||||
|
IntDefaultHandler, // FLASH Control
|
||||||
|
IntDefaultHandler, // GPIO Port F
|
||||||
|
IntDefaultHandler, // GPIO Port G
|
||||||
|
IntDefaultHandler, // GPIO Port H
|
||||||
|
IntDefaultHandler, // UART2 Rx and Tx
|
||||||
|
IntDefaultHandler, // SSI1 Rx and Tx
|
||||||
|
IntDefaultHandler, // Timer 3 subtimer A
|
||||||
|
IntDefaultHandler, // Timer 3 subtimer B
|
||||||
|
IntDefaultHandler, // I2C1 Master and Slave
|
||||||
|
IntDefaultHandler, // Quadrature Encoder 1
|
||||||
|
IntDefaultHandler, // CAN0
|
||||||
|
IntDefaultHandler, // CAN1
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // Hibernate
|
||||||
|
IntDefaultHandler, // USB0
|
||||||
|
IntDefaultHandler, // PWM Generator 3
|
||||||
|
IntDefaultHandler, // uDMA Software Transfer
|
||||||
|
IntDefaultHandler, // uDMA Error
|
||||||
|
IntDefaultHandler, // ADC1 Sequence 0
|
||||||
|
IntDefaultHandler, // ADC1 Sequence 1
|
||||||
|
IntDefaultHandler, // ADC1 Sequence 2
|
||||||
|
IntDefaultHandler, // ADC1 Sequence 3
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // GPIO Port J
|
||||||
|
IntDefaultHandler, // GPIO Port K
|
||||||
|
IntDefaultHandler, // GPIO Port L
|
||||||
|
IntDefaultHandler, // SSI2 Rx and Tx
|
||||||
|
IntDefaultHandler, // SSI3 Rx and Tx
|
||||||
|
IntDefaultHandler, // UART3 Rx and Tx
|
||||||
|
IntDefaultHandler, // UART4 Rx and Tx
|
||||||
|
IntDefaultHandler, // UART5 Rx and Tx
|
||||||
|
IntDefaultHandler, // UART6 Rx and Tx
|
||||||
|
IntDefaultHandler, // UART7 Rx and Tx
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // I2C2 Master and Slave
|
||||||
|
IntDefaultHandler, // I2C3 Master and Slave
|
||||||
|
IntDefaultHandler, // Timer 4 subtimer A
|
||||||
|
IntDefaultHandler, // Timer 4 subtimer B
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // Timer 5 subtimer A
|
||||||
|
IntDefaultHandler, // Timer 5 subtimer B
|
||||||
|
IntDefaultHandler, // Wide Timer 0 subtimer A
|
||||||
|
IntDefaultHandler, // Wide Timer 0 subtimer B
|
||||||
|
IntDefaultHandler, // Wide Timer 1 subtimer A
|
||||||
|
IntDefaultHandler, // Wide Timer 1 subtimer B
|
||||||
|
IntDefaultHandler, // Wide Timer 2 subtimer A
|
||||||
|
IntDefaultHandler, // Wide Timer 2 subtimer B
|
||||||
|
IntDefaultHandler, // Wide Timer 3 subtimer A
|
||||||
|
IntDefaultHandler, // Wide Timer 3 subtimer B
|
||||||
|
IntDefaultHandler, // Wide Timer 4 subtimer A
|
||||||
|
IntDefaultHandler, // Wide Timer 4 subtimer B
|
||||||
|
IntDefaultHandler, // Wide Timer 5 subtimer A
|
||||||
|
IntDefaultHandler, // Wide Timer 5 subtimer B
|
||||||
|
IntDefaultHandler, // FPU
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // I2C4 Master and Slave
|
||||||
|
IntDefaultHandler, // I2C5 Master and Slave
|
||||||
|
IntDefaultHandler, // GPIO Port M
|
||||||
|
IntDefaultHandler, // GPIO Port N
|
||||||
|
IntDefaultHandler, // Quadrature Encoder 2
|
||||||
|
0, // Reserved
|
||||||
|
0, // Reserved
|
||||||
|
IntDefaultHandler, // GPIO Port P (Summary or P0)
|
||||||
|
IntDefaultHandler, // GPIO Port P1
|
||||||
|
IntDefaultHandler, // GPIO Port P2
|
||||||
|
IntDefaultHandler, // GPIO Port P3
|
||||||
|
IntDefaultHandler, // GPIO Port P4
|
||||||
|
IntDefaultHandler, // GPIO Port P5
|
||||||
|
IntDefaultHandler, // GPIO Port P6
|
||||||
|
IntDefaultHandler, // GPIO Port P7
|
||||||
|
IntDefaultHandler, // GPIO Port Q (Summary or Q0)
|
||||||
|
IntDefaultHandler, // GPIO Port Q1
|
||||||
|
IntDefaultHandler, // GPIO Port Q2
|
||||||
|
IntDefaultHandler, // GPIO Port Q3
|
||||||
|
IntDefaultHandler, // GPIO Port Q4
|
||||||
|
IntDefaultHandler, // GPIO Port Q5
|
||||||
|
IntDefaultHandler, // GPIO Port Q6
|
||||||
|
IntDefaultHandler, // GPIO Port Q7
|
||||||
|
IntDefaultHandler, // GPIO Port R
|
||||||
|
IntDefaultHandler, // GPIO Port S
|
||||||
|
IntDefaultHandler, // PWM 1 Generator 0
|
||||||
|
IntDefaultHandler, // PWM 1 Generator 1
|
||||||
|
IntDefaultHandler, // PWM 1 Generator 2
|
||||||
|
IntDefaultHandler, // PWM 1 Generator 3
|
||||||
|
IntDefaultHandler // PWM 1 Fault
|
||||||
|
};
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// This is the code that gets called when the processor first starts execution
|
||||||
|
// following a reset event. Only the absolutely necessary set is performed,
|
||||||
|
// after which the application supplied entry() routine is called. Any fancy
|
||||||
|
// actions (such as making decisions based on the reset cause register, and
|
||||||
|
// resetting the bits in that register) are left solely in the hands of the
|
||||||
|
// application.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
void
|
||||||
|
ResetISR(void)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Jump to the CCS C initialization routine. This will enable the
|
||||||
|
// floating-point unit as well, so that does not need to be done here.
|
||||||
|
//
|
||||||
|
__asm(" .global _c_int00\n"
|
||||||
|
" b.w _c_int00");
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// This is the code that gets called when the processor receives a NMI. This
|
||||||
|
// simply enters an infinite loop, preserving the system state for examination
|
||||||
|
// by a debugger.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
static void
|
||||||
|
NmiSR(void)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Enter an infinite loop.
|
||||||
|
//
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// This is the code that gets called when the processor receives a fault
|
||||||
|
// interrupt. This simply enters an infinite loop, preserving the system state
|
||||||
|
// for examination by a debugger.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
static void
|
||||||
|
FaultISR(void)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Enter an infinite loop.
|
||||||
|
//
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//
|
||||||
|
// This is the code that gets called when the processor receives an unexpected
|
||||||
|
// interrupt. This simply enters an infinite loop, preserving the system state
|
||||||
|
// for examination by a debugger.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
static void
|
||||||
|
IntDefaultHandler(void)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Go into an infinite loop.
|
||||||
|
//
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user