├── 01_hello_world ├── Makefile ├── int_vector.c ├── main.c └── rtos.ld ├── 02_cm3 ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ └── os_stdio.h ├── int_vector.c ├── main.c ├── os_stdio.c └── rtos.ld ├── 03_rtos_basic ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 04_two_task_delay ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 05_critical ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 06_multi_prio ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── config.h │ ├── lib.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 07_delay_queue ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── config.h │ ├── lib.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 08_prio_slice ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── config.h │ ├── lib.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 09_suspend_resume ├── Makefile ├── cm3.c ├── cm3.o ├── cm3_s.o ├── cm3_s.s ├── include │ ├── cm3.h │ ├── config.h │ ├── lib.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── int_vector.o ├── lib.c ├── lib.o ├── main.c ├── main.o ├── os_stdio.c ├── os_stdio.o ├── rtos.bin ├── rtos.dis ├── rtos.elf ├── rtos.ld ├── task.c └── task.o ├── 10_task_delete ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── config.h │ ├── lib.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 11_task_select ├── Makefile ├── cm3.c ├── cm3_s.s ├── include │ ├── cm3.h │ ├── config.h │ ├── lib.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 12_event ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── lib.h │ ├── os.h │ ├── os_stdio.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld └── task.c ├── 13_semaphore ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── lib.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ └── task.h ├── int_vector.c ├── lib.c ├── main.c ├── os_stdio.c ├── rtos.ld ├── sem.c └── task.c ├── 14_mailbox ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── lib.h │ ├── mailbox.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ └── task.h ├── int_vector.c ├── lib.c ├── mailbox.c ├── main.c ├── os_stdio.c ├── rtos.ld ├── sem.c └── task.c ├── 15_mem_block ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── lib.h │ ├── mailbox.h │ ├── memblock.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ └── task.h ├── int_vector.c ├── lib.c ├── mailbox.c ├── main.c ├── memblock.c ├── os_stdio.c ├── rtos.ld ├── sem.c └── task.c ├── 16_timer ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── lib.h │ ├── mailbox.h │ ├── memblock.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ ├── task.h │ └── timer.h ├── int_vector.c ├── lib.c ├── mailbox.c ├── main.c ├── memblock.c ├── os_stdio.c ├── rtos.ld ├── sem.c ├── task.c └── timer.c ├── 17_mutex ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── lib.h │ ├── mailbox.h │ ├── memblock.h │ ├── mutex.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ ├── task.h │ └── timer.h ├── int_vector.c ├── lib.c ├── mailbox.c ├── main.c ├── memblock.c ├── mutex.c ├── os_stdio.c ├── rtos.ld ├── sem.c ├── task.c └── timer.c ├── 18_flag ├── Makefile ├── cm3.c ├── cm3_s.s ├── event.c ├── flag_group.c ├── include │ ├── cm3.h │ ├── config.h │ ├── event.h │ ├── flag_group.h │ ├── lib.h │ ├── mailbox.h │ ├── memblock.h │ ├── mutex.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ ├── task.h │ └── timer.h ├── int_vector.c ├── lib.c ├── mailbox.c ├── main.c ├── memblock.c ├── mutex.c ├── os_stdio.c ├── rtos.ld ├── sem.c ├── task.c └── timer.c ├── README.md ├── cmsis_rtos ├── CMSIS_RV │ ├── Include │ │ ├── ARMCM3.h │ │ ├── arm_common_tables.h │ │ ├── arm_const_structs.h │ │ ├── arm_math.h │ │ ├── cmsis_armcc.h │ │ ├── cmsis_armcc_V6.h │ │ ├── cmsis_gcc.h │ │ ├── core_cm0.h │ │ ├── core_cm0plus.h │ │ ├── core_cm3.h │ │ ├── core_cm4.h │ │ ├── core_cm7.h │ │ ├── core_cmFunc.h │ │ ├── core_cmInstr.h │ │ ├── core_cmSimd.h │ │ ├── core_sc000.h │ │ ├── core_sc300.h │ │ └── system_ARMCM3.h │ ├── RTE_Components.h │ ├── RV_Config.h │ ├── RV_Framework.c │ ├── RV_Framework.h │ ├── RV_Report.h │ ├── RV_Typedefs.h │ ├── cmsis_rv.c │ └── cmsis_rv.h ├── Makefile ├── cm3.c ├── cm3_s.s ├── cmsis_os.c ├── event.c ├── flag_group.c ├── include │ ├── cm3.h │ ├── cmsis_os.h │ ├── config.h │ ├── event.h │ ├── flag_group.h │ ├── lib.h │ ├── mailbox.h │ ├── memblock.h │ ├── mutex.h │ ├── os.h │ ├── os_stdio.h │ ├── sem.h │ ├── task.h │ └── timer.h ├── int_vector.c ├── lib.c ├── mailbox.c ├── main.c ├── memblock.c ├── mutex.c ├── os_stdio.c ├── rtos.ld ├── sem.c ├── task.c └── timer.c ├── kill_qemu.py └── tools └── qemu-system-arm /01_hello_world/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /01_hello_world/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | volatile uint32_t * const UART0DR = (uint32_t *)0x4000C000; 3 | 4 | void send_str(char *s) 5 | { 6 | while(*s != '\0') { 7 | *UART0DR = *s++; 8 | } 9 | } 10 | 11 | void main() 12 | { 13 | send_str("hello world\n"); 14 | while(1); 15 | } 16 | -------------------------------------------------------------------------------- /01_hello_world/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /02_cm3/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /02_cm3/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | 3 | void init_systick() 4 | { 5 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 6 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 7 | *sys_prio_p = 0xf0; 8 | systick_p->load = (HSI_CLK & 0xffffffUL) - 1; 9 | systick_p->val = 0; 10 | systick_p->ctrl = 0x7; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /02_cm3/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .global main 5 | .global reset_handler 6 | .global _p_stack_top 7 | .global get_psp 8 | .global get_msp 9 | .global get_control_reg 10 | 11 | reset_handler: 12 | 13 | /*Set the stack as process stack*/ 14 | mov r0, #33 15 | mrs r0, CONTROL 16 | mov r1, #2 17 | orr r0, r1 18 | msr CONTROL, r0 19 | 20 | ldr r0, =_p_stack_top 21 | mov sp, r0 22 | 23 | ldr r0, =main 24 | blx r0 25 | b . 26 | 27 | get_psp: 28 | mrs r0, PSP 29 | blx lr 30 | 31 | get_msp: 32 | mrs r0, MSP 33 | blx lr 34 | 35 | get_control_reg: 36 | mrs r0, CONTROL 37 | blx lr 38 | -------------------------------------------------------------------------------- /02_cm3/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define HSI_CLK 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | typedef struct systick_tag { 12 | volatile uint32_t ctrl; 13 | volatile uint32_t load; 14 | volatile uint32_t val; 15 | volatile uint32_t calrb; 16 | }systick_t; 17 | 18 | extern uint32_t get_psp(void); 19 | extern uint32_t get_msp(void); 20 | extern uint32_t get_control_reg(void); 21 | 22 | extern void init_systick(void); 23 | #endif /*CM3_H*/ 24 | -------------------------------------------------------------------------------- /02_cm3/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | extern void printk(const char *fmt, ...); 7 | extern int memset(void *mem, uint8_t val, uint32_t sz); 8 | extern int memcpy(void *dst, const void *src, uint32_t sz); 9 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 10 | extern int strcmp(char *str1, char *str2); 11 | extern int strncmp(char *str1, char *str2, uint32_t sz); 12 | extern int strtoul(char *str, uint32_t *val); 13 | extern int strtol(char *str, int *val); 14 | extern uint32_t strlen(char *str); 15 | extern int strcpy(char *dst, char *src); 16 | extern void no_printk(const char *fmt, ...); 17 | 18 | #define DEBUG_SUPPORT 19 | #ifdef DEBUG_SUPPORT 20 | #define DEBUG printk 21 | #else 22 | #define DEBUG no_printk 23 | #endif /*DEBUG*/ 24 | 25 | #endif /*OS_STDIO_H*/ 26 | -------------------------------------------------------------------------------- /02_cm3/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | 5 | extern uint32_t _bss; 6 | extern uint32_t _ebss; 7 | 8 | static inline void clear_bss(void) 9 | { 10 | uint8_t *start = (uint8_t *)_bss; 11 | while ((uint32_t)start < _ebss) { 12 | *start = 0; 13 | start++; 14 | } 15 | } 16 | 17 | void systick_handler(void) 18 | { 19 | DEBUG("systick_handler\n"); 20 | } 21 | 22 | int main() 23 | { 24 | 25 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 26 | clear_bss(); 27 | 28 | DEBUG("Hello RTOS\n"); 29 | DEBUG("psp:0x%x\n", get_psp()); 30 | DEBUG("msp:0x%x\n", get_msp()); 31 | 32 | init_systick(); 33 | while(1) { 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /02_cm3/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /03_rtos_basic/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /03_rtos_basic/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | 4 | void init_systick() 5 | { 6 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 7 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 8 | *sys_prio_p = 0xf0; 9 | systick_p->load = (HSI_CLK & 0xffffffUL) - 1; 10 | systick_p->val = 0; 11 | systick_p->ctrl = 0x7; 12 | } 13 | 14 | void systick_handler(void) 15 | { 16 | DEBUG("systick_handler\n"); 17 | } 18 | 19 | void trigger_pend_sv(void) 20 | { 21 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 22 | //MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 23 | *((uint32_t volatile *)0xE000ED04) = 0x10000000; 24 | } 25 | -------------------------------------------------------------------------------- /03_rtos_basic/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | 14 | /*Import*/ 15 | .global g_current_task 16 | .global g_next_task 17 | .global main 18 | 19 | reset_handler: 20 | 21 | /*Set the stack as process stack*/ 22 | mov r0, #33 23 | mrs r0, CONTROL 24 | mov r1, #2 25 | orr r0, r1 26 | msr CONTROL, r0 27 | 28 | ldr r0, =_p_stack_top 29 | mov sp, r0 30 | 31 | ldr r0, =main 32 | blx r0 33 | b . 34 | 35 | get_psp: 36 | mrs r0, PSP 37 | blx lr 38 | 39 | set_psp: 40 | msr PSP, r0 41 | blx lr 42 | 43 | get_msp: 44 | mrs r0, MSP 45 | blx lr 46 | 47 | get_control_reg: 48 | mrs r0, CONTROL 49 | blx lr 50 | 51 | pendsv_handler: 52 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 53 | mrs r0, psp 54 | cbz r0, pendsv_handler_nosave 55 | 56 | /* g_current_task->psp-- = r11; 57 | * ... 58 | * g_current_task->psp-- = r4; 59 | * g_current_task->stack = psp; 60 | */ 61 | stmdb r0!, {r4-r11} 62 | ldr r1, =g_current_task 63 | ldr r1, [r1] 64 | str r0, [r1] 65 | 66 | pendsv_handler_nosave: 67 | 68 | /* *g_current_task = *g_next_task */ 69 | ldr r0, =g_current_task 70 | ldr r1, =g_next_task 71 | ldr r2, [r1] 72 | str r2, [r0] 73 | 74 | /*r0 = g_current_task->stack*/ 75 | ldr r0, [r2] 76 | ldmia r0!, {r4-r11} 77 | 78 | msr psp, r0 79 | orr lr, lr, #0x04 /*Swtich to PSP*/ 80 | bx lr 81 | -------------------------------------------------------------------------------- /03_rtos_basic/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define HSI_CLK 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | 31 | extern void init_systick(void); 32 | extern void trigger_pend_sv(void); 33 | extern void pendsv_handler(void); 34 | #endif /*CM3_H*/ 35 | -------------------------------------------------------------------------------- /03_rtos_basic/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | extern void printk(const char *fmt, ...); 7 | extern int memset(void *mem, uint8_t val, uint32_t sz); 8 | extern int memcpy(void *dst, const void *src, uint32_t sz); 9 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 10 | extern int strcmp(char *str1, char *str2); 11 | extern int strncmp(char *str1, char *str2, uint32_t sz); 12 | extern int strtoul(char *str, uint32_t *val); 13 | extern int strtol(char *str, int *val); 14 | extern uint32_t strlen(char *str); 15 | extern int strcpy(char *dst, char *src); 16 | extern void no_printk(const char *fmt, ...); 17 | 18 | #define DEBUG 19 | #ifdef DEBUG 20 | #define DEBUG printk 21 | #else 22 | #define DEBUG no_printk 23 | #endif /*DEBUG*/ 24 | 25 | #endif /*OS_STDIO_H*/ 26 | -------------------------------------------------------------------------------- /03_rtos_basic/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | 6 | typedef uint32_t task_stack_t; 7 | /*Task Control block*/ 8 | typedef struct task_tag { 9 | 10 | task_stack_t *stack; 11 | }task_t; 12 | 13 | extern task_t *g_current_task; 14 | extern task_t *g_next_task; 15 | extern task_t *g_task_table[2]; 16 | 17 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t * stack); 18 | extern void task_sched(void); 19 | extern void task_switch(void); 20 | extern void task_run_first(void); 21 | 22 | #endif /*TASK_H*/ 23 | -------------------------------------------------------------------------------- /03_rtos_basic/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | void delay(uint32_t count) 19 | { 20 | while(--count > 0); 21 | } 22 | 23 | void task1_entry(void *param) 24 | { 25 | for(;;) { 26 | printk("task1_entry\n"); 27 | delay(65536000); 28 | task_sched(); 29 | } 30 | } 31 | 32 | void task2_entry(void *param) 33 | { 34 | for(;;) { 35 | printk("task2_entry\n"); 36 | delay(65536000); 37 | task_sched(); 38 | } 39 | } 40 | 41 | task_t task1; 42 | task_t task2; 43 | task_stack_t task1_stk[1024]; 44 | task_stack_t task2_stk[1024]; 45 | 46 | int main() 47 | { 48 | 49 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 50 | clear_bss(); 51 | 52 | DEBUG("Hello RTOS\n"); 53 | DEBUG("psp:0x%x\n", get_psp()); 54 | DEBUG("msp:0x%x\n", get_msp()); 55 | 56 | task_init(&task1, task1_entry, (void *)0x11111111, &task1_stk[1024]); 57 | task_init(&task2, task2_entry, (void *)0x22222222, &task2_stk[1024]); 58 | 59 | g_task_table[0] = &task1; 60 | g_task_table[1] = &task2; 61 | g_next_task = g_task_table[0]; 62 | 63 | task_run_first(); 64 | 65 | for(;;); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /03_rtos_basic/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /03_rtos_basic/task.c: -------------------------------------------------------------------------------- 1 | #include "task.h" 2 | #include "cm3.h" 3 | #include "os_stdio.h" 4 | 5 | task_t *g_current_task; 6 | task_t *g_next_task; 7 | task_t *g_task_table[2]; 8 | 9 | void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t * stack) 10 | { 11 | DEBUG("%s\n", __func__); 12 | *(--stack) = (uint32_t) (1 << 24); //XPSR, Thumb Mode 13 | *(--stack) = (uint32_t) entry; //PC 14 | *(--stack) = (uint32_t) 0x14; //LR 15 | *(--stack) = (uint32_t) 0x12; //R12 16 | *(--stack) = (uint32_t) 0x3; //R3 17 | *(--stack) = (uint32_t) 0x2; //R2 18 | *(--stack) = (uint32_t) 0x1; //R1 19 | *(--stack) = (uint32_t) param; //R0 20 | *(--stack) = (uint32_t) 0x11; //R11 21 | *(--stack) = (uint32_t) 0x10; //R10 22 | *(--stack) = (uint32_t) 0x9; //R9 23 | *(--stack) = (uint32_t) 0x8; //R8 24 | *(--stack) = (uint32_t) 0x7; //R7 25 | *(--stack) = (uint32_t) 0x6; //R6 26 | *(--stack) = (uint32_t) 0x5; //R5 27 | *(--stack) = (uint32_t) 0x4; //R4 28 | 29 | task->stack = stack; 30 | } 31 | 32 | void task_sched() 33 | { 34 | if (g_current_task == g_task_table[0]) { 35 | g_next_task = g_task_table[1]; 36 | } else { 37 | g_next_task = g_task_table[0]; 38 | } 39 | 40 | task_switch(); 41 | } 42 | 43 | void task_switch() 44 | { 45 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; 46 | } 47 | 48 | void task_run_first() 49 | { 50 | DEBUG("%s\n", __func__); 51 | set_psp(0); 52 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; 53 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; 54 | } 55 | -------------------------------------------------------------------------------- /04_two_task_delay/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /04_two_task_delay/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | 4 | void init_systick(uint32_t ms) 5 | { 6 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 7 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 8 | *sys_prio_p = 0xf0; 9 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 10 | systick_p->val = 0; 11 | systick_p->ctrl = 0x7; 12 | } 13 | 14 | void systick_handler(void) 15 | { 16 | /*DEBUG("systick_handler\n");*/ 17 | task_system_tick_handler(); 18 | } 19 | 20 | void trigger_pend_sv(void) 21 | { 22 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 23 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 24 | } 25 | -------------------------------------------------------------------------------- /04_two_task_delay/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | 14 | /*Import*/ 15 | .global g_current_task 16 | .global g_next_task 17 | .global main 18 | 19 | reset_handler: 20 | 21 | /*Set the stack as process stack*/ 22 | mov r0, #33 23 | mrs r0, CONTROL 24 | mov r1, #2 25 | orr r0, r1 26 | msr CONTROL, r0 27 | 28 | ldr r0, =_p_stack_top 29 | mov sp, r0 30 | 31 | ldr r0, =main 32 | blx r0 33 | b . 34 | 35 | get_psp: 36 | mrs r0, PSP 37 | blx lr 38 | 39 | set_psp: 40 | msr PSP, r0 41 | blx lr 42 | 43 | get_msp: 44 | mrs r0, MSP 45 | blx lr 46 | 47 | get_control_reg: 48 | mrs r0, CONTROL 49 | blx lr 50 | 51 | pendsv_handler: 52 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 53 | mrs r0, psp 54 | cbz r0, pendsv_handler_nosave 55 | 56 | /* g_current_task->psp-- = r11; 57 | * ... 58 | * g_current_task->psp-- = r4; 59 | * g_current_task->stack = psp; 60 | */ 61 | stmdb r0!, {r4-r11} 62 | ldr r1, =g_current_task 63 | ldr r1, [r1] 64 | str r0, [r1] 65 | 66 | pendsv_handler_nosave: 67 | 68 | /* *g_current_task = *g_next_task */ 69 | ldr r0, =g_current_task 70 | ldr r1, =g_next_task 71 | ldr r2, [r1] 72 | str r2, [r0] 73 | 74 | /*r0 = g_current_task->stack*/ 75 | ldr r0, [r2] 76 | ldmia r0!, {r4-r11} 77 | 78 | msr psp, r0 79 | orr lr, lr, #0x04 /*Swtich to PSP*/ 80 | bx lr 81 | -------------------------------------------------------------------------------- /04_two_task_delay/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | 31 | extern void init_systick(uint32_t ms); 32 | extern void trigger_pend_sv(void); 33 | extern void pendsv_handler(void); 34 | #endif /*CM3_H*/ 35 | -------------------------------------------------------------------------------- /04_two_task_delay/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | extern void printk(const char *fmt, ...); 7 | extern int memset(void *mem, uint8_t val, uint32_t sz); 8 | extern int memcpy(void *dst, const void *src, uint32_t sz); 9 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 10 | extern int strcmp(char *str1, char *str2); 11 | extern int strncmp(char *str1, char *str2, uint32_t sz); 12 | extern int strtoul(char *str, uint32_t *val); 13 | extern int strtol(char *str, int *val); 14 | extern uint32_t strlen(char *str); 15 | extern int strcpy(char *dst, char *src); 16 | extern void no_printk(const char *fmt, ...); 17 | 18 | #define DEBUG 19 | #ifdef DEBUG 20 | #define DEBUG printk 21 | #else 22 | #define DEBUG no_printk 23 | #endif /*DEBUG*/ 24 | 25 | #endif /*OS_STDIO_H*/ 26 | -------------------------------------------------------------------------------- /04_two_task_delay/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | 6 | typedef uint32_t task_stack_t; 7 | /*Task Control block*/ 8 | typedef struct task_tag { 9 | 10 | task_stack_t *stack; 11 | uint32_t delay_ticks; 12 | }task_t; 13 | 14 | extern task_t *g_current_task; 15 | extern task_t *g_next_task; 16 | extern task_t *g_task_table[2]; 17 | 18 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t * stack); 19 | extern void task_sched(void); 20 | extern void task_switch(void); 21 | extern void task_run_first(void); 22 | extern void task_delay(uint32_t ticks); 23 | extern void task_system_tick_handler(void); 24 | extern void init_task_module(void); 25 | 26 | #endif /*TASK_H*/ 27 | -------------------------------------------------------------------------------- /04_two_task_delay/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | void task1_entry(void *param) 19 | { 20 | init_systick(1000); 21 | for(;;) { 22 | printk("%s\n", __func__); 23 | task_delay(1); 24 | } 25 | } 26 | 27 | void task2_entry(void *param) 28 | { 29 | for(;;) { 30 | printk("%s\n", __func__); 31 | task_delay(5); 32 | } 33 | } 34 | 35 | task_t task1; 36 | task_t task2; 37 | task_stack_t task1_stk[1024]; 38 | task_stack_t task2_stk[1024]; 39 | 40 | int main() 41 | { 42 | 43 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 44 | clear_bss(); 45 | 46 | DEBUG("Hello RTOS C02.2\n"); 47 | DEBUG("psp:0x%x\n", get_psp()); 48 | DEBUG("msp:0x%x\n", get_msp()); 49 | 50 | task_init(&task1, task1_entry, (void *)0x11111111, &task1_stk[1024]); 51 | task_init(&task2, task2_entry, (void *)0x22222222, &task2_stk[1024]); 52 | 53 | g_task_table[0] = &task1; 54 | g_task_table[1] = &task2; 55 | g_next_task = g_task_table[0]; 56 | init_task_module(); 57 | 58 | task_run_first(); 59 | 60 | for(;;); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /04_two_task_delay/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /05_critical/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /05_critical/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | 4 | void init_systick(uint32_t ms) 5 | { 6 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 7 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 8 | *sys_prio_p = 0xf0; 9 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 10 | systick_p->val = 0; 11 | systick_p->ctrl = 0x7; 12 | } 13 | 14 | void systick_handler(void) 15 | { 16 | /*DEBUG("systick_handler\n");*/ 17 | task_system_tick_handler(); 18 | } 19 | 20 | void trigger_pend_sv(void) 21 | { 22 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 23 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 24 | } 25 | -------------------------------------------------------------------------------- /05_critical/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | .global set_primask 14 | .global get_primask 15 | .global disable_irq 16 | .global enable_irq 17 | 18 | /*Import*/ 19 | .global g_current_task 20 | .global g_next_task 21 | .global main 22 | 23 | reset_handler: 24 | 25 | /*Set the stack as process stack*/ 26 | mov r0, #33 27 | mrs r0, CONTROL 28 | mov r1, #2 29 | orr r0, r1 30 | msr CONTROL, r0 31 | 32 | ldr r0, =_p_stack_top 33 | mov sp, r0 34 | 35 | ldr r0, =main 36 | blx r0 37 | b . 38 | 39 | get_psp: 40 | mrs r0, PSP 41 | blx lr 42 | 43 | set_psp: 44 | msr PSP, r0 45 | blx lr 46 | 47 | get_msp: 48 | mrs r0, MSP 49 | blx lr 50 | 51 | get_control_reg: 52 | mrs r0, CONTROL 53 | blx lr 54 | 55 | pendsv_handler: 56 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 57 | mrs r0, psp 58 | cbz r0, pendsv_handler_nosave 59 | 60 | /* g_current_task->psp-- = r11; 61 | * ... 62 | * g_current_task->psp-- = r4; 63 | * g_current_task->stack = psp; 64 | */ 65 | stmdb r0!, {r4-r11} 66 | ldr r1, =g_current_task 67 | ldr r1, [r1] 68 | str r0, [r1] 69 | 70 | pendsv_handler_nosave: 71 | 72 | /* *g_current_task = *g_next_task */ 73 | ldr r0, =g_current_task 74 | ldr r1, =g_next_task 75 | ldr r2, [r1] 76 | str r2, [r0] 77 | 78 | /*r0 = g_current_task->stack*/ 79 | ldr r0, [r2] 80 | ldmia r0!, {r4-r11} 81 | 82 | msr psp, r0 83 | orr lr, lr, #0x04 /*Swtich to PSP*/ 84 | bx lr 85 | 86 | get_primask: 87 | mrs r0, PRIMASK 88 | blx lr 89 | 90 | set_primask: 91 | msr PRIMASK, r0 92 | blx lr 93 | 94 | disable_irq: 95 | cpsid i 96 | blx lr 97 | 98 | enable_irq: 99 | cpsie i 100 | blx lr 101 | -------------------------------------------------------------------------------- /05_critical/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /05_critical/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | extern void printk(const char *fmt, ...); 7 | extern int memset(void *mem, uint8_t val, uint32_t sz); 8 | extern int memcpy(void *dst, const void *src, uint32_t sz); 9 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 10 | extern int strcmp(char *str1, char *str2); 11 | extern int strncmp(char *str1, char *str2, uint32_t sz); 12 | extern int strtoul(char *str, uint32_t *val); 13 | extern int strtol(char *str, int *val); 14 | extern uint32_t strlen(char *str); 15 | extern int strcpy(char *dst, char *src); 16 | extern void no_printk(const char *fmt, ...); 17 | 18 | #define DEBUG 19 | #ifdef DEBUG 20 | #define DEBUG printk 21 | #else 22 | #define DEBUG no_printk 23 | #endif /*DEBUG*/ 24 | 25 | #endif /*OS_STDIO_H*/ 26 | -------------------------------------------------------------------------------- /05_critical/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | 6 | typedef uint32_t task_stack_t; 7 | /*Task Control block*/ 8 | typedef struct task_tag { 9 | 10 | task_stack_t *stack; 11 | uint32_t delay_ticks; 12 | }task_t; 13 | 14 | extern task_t *g_current_task; 15 | extern task_t *g_next_task; 16 | extern task_t *g_task_table[2]; 17 | 18 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t * stack); 19 | extern void task_sched(void); 20 | extern void task_switch(void); 21 | extern void task_run_first(void); 22 | extern void task_delay(uint32_t ticks); 23 | extern void task_system_tick_handler(void); 24 | extern void init_task_module(void); 25 | extern uint32_t task_enter_critical(void); 26 | extern void task_exit_critical(uint32_t status); 27 | 28 | #endif /*TASK_H*/ 29 | -------------------------------------------------------------------------------- /05_critical/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | uint32_t test_sync_val = 0; 19 | 20 | void task1_entry(void *param) 21 | { 22 | uint32_t status = 0; 23 | init_systick(1000); 24 | for(;;) { 25 | printk("%s\n", __func__); 26 | status = task_enter_critical(); 27 | task_delay(1); 28 | test_sync_val++; 29 | task_exit_critical(status); 30 | printk("task1:test_sync_val:%d\n", test_sync_val); 31 | } 32 | } 33 | 34 | void task2_entry(void *param) 35 | { 36 | uint32_t counter = test_sync_val; 37 | uint32_t status = 0; 38 | 39 | for(;;) { 40 | printk("%s\n", __func__); 41 | 42 | status = task_enter_critical(); 43 | counter = test_sync_val; 44 | task_delay(5); 45 | test_sync_val = counter +1; 46 | task_exit_critical(status); 47 | 48 | printk("task2:test_sync_val:%d\n", test_sync_val); 49 | } 50 | } 51 | 52 | task_t task1; 53 | task_t task2; 54 | task_stack_t task1_stk[1024]; 55 | task_stack_t task2_stk[1024]; 56 | 57 | int main() 58 | { 59 | 60 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 61 | clear_bss(); 62 | 63 | DEBUG("Hello RTOS C02.2\n"); 64 | DEBUG("psp:0x%x\n", get_psp()); 65 | DEBUG("msp:0x%x\n", get_msp()); 66 | 67 | task_init(&task1, task1_entry, (void *)0x11111111, &task1_stk[1024]); 68 | task_init(&task2, task2_entry, (void *)0x22222222, &task2_stk[1024]); 69 | 70 | g_task_table[0] = &task1; 71 | g_task_table[1] = &task2; 72 | g_next_task = g_task_table[0]; 73 | init_task_module(); 74 | 75 | task_run_first(); 76 | 77 | for(;;); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /05_critical/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /06_multi_prio/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /06_multi_prio/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /06_multi_prio/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | .global set_primask 14 | .global get_primask 15 | .global disable_irq 16 | .global enable_irq 17 | 18 | /*Import*/ 19 | .global g_current_task 20 | .global g_next_task 21 | .global main 22 | 23 | reset_handler: 24 | 25 | /*Set the stack as process stack*/ 26 | mov r0, #33 27 | mrs r0, CONTROL 28 | mov r1, #2 29 | orr r0, r1 30 | msr CONTROL, r0 31 | 32 | ldr r0, =_p_stack_top 33 | mov sp, r0 34 | 35 | ldr r0, =main 36 | blx r0 37 | b . 38 | 39 | get_psp: 40 | mrs r0, PSP 41 | blx lr 42 | 43 | set_psp: 44 | msr PSP, r0 45 | blx lr 46 | 47 | get_msp: 48 | mrs r0, MSP 49 | blx lr 50 | 51 | get_control_reg: 52 | mrs r0, CONTROL 53 | blx lr 54 | 55 | pendsv_handler: 56 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 57 | mrs r0, psp 58 | cbz r0, pendsv_handler_nosave 59 | 60 | /* g_current_task->psp-- = r11; 61 | * ... 62 | * g_current_task->psp-- = r4; 63 | * g_current_task->stack = psp; 64 | */ 65 | stmdb r0!, {r4-r11} 66 | ldr r1, =g_current_task 67 | ldr r1, [r1] 68 | str r0, [r1] 69 | 70 | pendsv_handler_nosave: 71 | 72 | /* *g_current_task = *g_next_task */ 73 | ldr r0, =g_current_task 74 | ldr r1, =g_next_task 75 | ldr r2, [r1] 76 | str r2, [r0] 77 | 78 | /*r0 = g_current_task->stack*/ 79 | ldr r0, [r2] 80 | ldmia r0!, {r4-r11} 81 | 82 | msr psp, r0 83 | orr lr, lr, #0x04 /*Swtich to PSP*/ 84 | bx lr 85 | 86 | get_primask: 87 | mrs r0, PRIMASK 88 | blx lr 89 | 90 | set_primask: 91 | msr PRIMASK, r0 92 | blx lr 93 | 94 | disable_irq: 95 | cpsid i 96 | blx lr 97 | 98 | enable_irq: 99 | cpsie i 100 | blx lr 101 | -------------------------------------------------------------------------------- /06_multi_prio/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /06_multi_prio/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | 6 | #endif /*CONFIG*/ 7 | -------------------------------------------------------------------------------- /06_multi_prio/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /06_multi_prio/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /06_multi_prio/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | #include "config.h" 6 | 7 | typedef uint32_t task_stack_t; 8 | /*Task Control block*/ 9 | typedef struct task_tag { 10 | 11 | task_stack_t *stack; 12 | uint32_t delay_ticks; 13 | uint32_t prio; 14 | }task_t; 15 | 16 | extern task_t *g_current_task; 17 | extern task_t *g_next_task; 18 | extern task_t *g_task_table[OS_PRIO_COUNT]; 19 | 20 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t prio, uint32_t * stack); 21 | extern void task_sched(void); 22 | extern void task_switch(void); 23 | extern void task_run_first(void); 24 | extern void task_delay(uint32_t ticks); 25 | extern void task_delay_s(uint32_t seconds); 26 | extern void task_system_tick_handler(void); 27 | extern void init_task_module(void); 28 | extern uint32_t task_enter_critical(void); 29 | extern void task_exit_critical(uint32_t status); 30 | extern void task_sched_disable(void); 31 | extern void task_sched_enable(void); 32 | extern task_t *task_highest_ready(void); 33 | 34 | #endif /*TASK_H*/ 35 | -------------------------------------------------------------------------------- /06_multi_prio/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | 19 | void task1_entry(void *param) 20 | { 21 | init_systick(10); 22 | for(;;) { 23 | printk("%s\n", __func__); 24 | task_delay_s(1); 25 | } 26 | } 27 | 28 | void task2_entry(void *param) 29 | { 30 | 31 | for(;;) { 32 | printk("%s\n", __func__); 33 | task_delay_s(2); 34 | } 35 | } 36 | 37 | task_t task1; 38 | task_t task2; 39 | task_stack_t task1_stk[1024]; 40 | task_stack_t task2_stk[1024]; 41 | 42 | int main() 43 | { 44 | 45 | clear_bss(); 46 | 47 | DEBUG("Hello RTOS C03_Multi Prio\n"); 48 | DEBUG("psp:0x%x\n", get_psp()); 49 | DEBUG("msp:0x%x\n", get_msp()); 50 | 51 | task_init(&task1, task1_entry, (void *)0x11111111, 0, &task1_stk[1024]); 52 | task_init(&task2, task2_entry, (void *)0x22222222, 1, &task2_stk[1024]); 53 | 54 | init_task_module(); 55 | 56 | for(;;); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /06_multi_prio/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /07_delay_queue/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /07_delay_queue/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /07_delay_queue/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /07_delay_queue/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | 6 | #endif /*CONFIG*/ 7 | -------------------------------------------------------------------------------- /07_delay_queue/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /07_delay_queue/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /07_delay_queue/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | #include "config.h" 6 | #include "lib.h" 7 | 8 | #define OS_TASK_STATE_RDY 0 9 | #define OS_TASK_STATE_DELAYED (1 << 1) 10 | 11 | typedef uint32_t task_stack_t; 12 | /*Task Control block*/ 13 | typedef struct task_tag { 14 | 15 | task_stack_t *stack; 16 | uint32_t delay_ticks; 17 | uint32_t prio; 18 | 19 | list_node_t delay_node; 20 | uint32_t state; 21 | }task_t; 22 | 23 | extern task_t *g_current_task; 24 | extern task_t *g_next_task; 25 | extern task_t *g_task_table[OS_PRIO_COUNT]; 26 | 27 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t prio, uint32_t * stack); 28 | extern void task_sched(void); 29 | extern void task_switch(void); 30 | extern void task_run_first(void); 31 | extern void task_delay(uint32_t ticks); 32 | extern void task_delay_s(uint32_t seconds); 33 | extern void task_system_tick_handler(void); 34 | extern void init_task_module(void); 35 | extern uint32_t task_enter_critical(void); 36 | extern void task_exit_critical(uint32_t status); 37 | extern void task_sched_disable(void); 38 | extern void task_sched_enable(void); 39 | extern task_t *task_highest_ready(void); 40 | extern void task_ready(task_t *task); 41 | extern void task_unready(task_t *task); 42 | extern void task_delay_wait(task_t *task, uint32_t ticks); 43 | extern void task_delay_wakeup(task_t *task); 44 | 45 | #endif /*TASK_H*/ 46 | -------------------------------------------------------------------------------- /07_delay_queue/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | 19 | void task1_entry(void *param) 20 | { 21 | init_systick(10); 22 | for(;;) { 23 | printk("%s\n", __func__); 24 | task_delay_s(1); 25 | } 26 | } 27 | 28 | void task2_entry(void *param) 29 | { 30 | 31 | for(;;) { 32 | printk("%s\n", __func__); 33 | task_delay_s(2); 34 | } 35 | } 36 | 37 | task_t task1; 38 | task_t task2; 39 | task_stack_t task1_stk[1024]; 40 | task_stack_t task2_stk[1024]; 41 | 42 | int main() 43 | { 44 | 45 | clear_bss(); 46 | 47 | DEBUG("Hello RTOS C03_Delay_List\n"); 48 | 49 | DEBUG("psp:0x%x\n", get_psp()); 50 | DEBUG("msp:0x%x\n", get_msp()); 51 | 52 | task_init(&task1, task1_entry, (void *)0x11111111, 0, &task1_stk[1024]); 53 | task_init(&task2, task2_entry, (void *)0x22222222, 1, &task2_stk[1024]); 54 | 55 | init_task_module(); 56 | 57 | for(;;); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /07_delay_queue/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /08_prio_slice/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /08_prio_slice/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /08_prio_slice/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /08_prio_slice/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /08_prio_slice/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /08_prio_slice/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /08_prio_slice/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | #include "config.h" 6 | #include "lib.h" 7 | 8 | #define OS_TASK_STATE_RDY 0 9 | #define OS_TASK_STATE_DELAYED (1 << 1) 10 | 11 | typedef uint32_t task_stack_t; 12 | /*Task Control block*/ 13 | typedef struct task_tag { 14 | 15 | task_stack_t *stack; 16 | uint32_t delay_ticks; 17 | uint32_t prio; 18 | 19 | list_node_t delay_node; 20 | uint32_t state; 21 | 22 | list_node_t prio_list_node; 23 | uint32_t slice; 24 | }task_t; 25 | 26 | extern task_t *g_current_task; 27 | extern task_t *g_next_task; 28 | extern list_t g_task_table[OS_PRIO_COUNT]; 29 | 30 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t prio, uint32_t * stack); 31 | extern void task_sched(void); 32 | extern void task_switch(void); 33 | extern void task_run_first(void); 34 | extern void task_delay(uint32_t ticks); 35 | extern void task_delay_s(uint32_t seconds); 36 | extern void task_system_tick_handler(void); 37 | extern void init_task_module(void); 38 | extern uint32_t task_enter_critical(void); 39 | extern void task_exit_critical(uint32_t status); 40 | extern void task_sched_disable(void); 41 | extern void task_sched_enable(void); 42 | extern task_t *task_highest_ready(void); 43 | extern void task_ready(task_t *task); 44 | extern void task_unready(task_t *task); 45 | extern void task_delay_wait(task_t *task, uint32_t ticks); 46 | extern void task_delay_wakeup(task_t *task); 47 | 48 | #endif /*TASK_H*/ 49 | -------------------------------------------------------------------------------- /08_prio_slice/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | 19 | void task1_entry(void *param) 20 | { 21 | init_systick(10); 22 | for(;;) { 23 | printk("%s\n", __func__); 24 | task_delay_s(2); 25 | } 26 | } 27 | 28 | void delay(uint32_t delay) 29 | { 30 | while(delay--); 31 | } 32 | 33 | void task2_entry(void *param) 34 | { 35 | 36 | for(;;) { 37 | printk("%s\n", __func__); 38 | delay(65536000); 39 | } 40 | } 41 | 42 | void task3_entry(void *param) 43 | { 44 | for(;;) { 45 | printk("%s\n", __func__); 46 | delay(65536000); 47 | } 48 | } 49 | 50 | task_t task1; 51 | task_t task2; 52 | task_t task3; 53 | task_stack_t task1_stk[1024]; 54 | task_stack_t task2_stk[1024]; 55 | task_stack_t task3_stk[1024]; 56 | 57 | int main() 58 | { 59 | 60 | clear_bss(); 61 | 62 | DEBUG("Hello RTOS C03_Delay_List\n"); 63 | 64 | DEBUG("psp:0x%x\n", get_psp()); 65 | DEBUG("msp:0x%x\n", get_msp()); 66 | 67 | init_task_module(); 68 | 69 | task_init(&task1, task1_entry, (void *)0x11111111, 0, &task1_stk[1024]); 70 | task_init(&task2, task2_entry, (void *)0x22222222, 1, &task2_stk[1024]); 71 | task_init(&task3, task3_entry, (void *)0x33333333, 1, &task3_stk[1024]); 72 | 73 | g_next_task = task_highest_ready(); 74 | task_run_first(); 75 | 76 | for(;;); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /08_prio_slice/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /09_suspend_resume/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /09_suspend_resume/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /09_suspend_resume/cm3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/cm3.o -------------------------------------------------------------------------------- /09_suspend_resume/cm3_s.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/cm3_s.o -------------------------------------------------------------------------------- /09_suspend_resume/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /09_suspend_resume/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /09_suspend_resume/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /09_suspend_resume/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /09_suspend_resume/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | #include "config.h" 6 | #include "lib.h" 7 | 8 | #define OS_TASK_STATE_RDY 0 9 | #define OS_TASK_STATE_DELAYED (1 << 1) 10 | #define OS_TASK_STATE_SUSPEND (1 << 2) 11 | typedef uint32_t task_stack_t; 12 | /*Task Control block*/ 13 | typedef struct task_tag { 14 | 15 | task_stack_t *stack; 16 | uint32_t delay_ticks; 17 | uint32_t prio; 18 | 19 | /*Delay list*/ 20 | list_node_t delay_node; 21 | uint32_t state; 22 | 23 | /*Same prioity slice scheduling*/ 24 | list_node_t prio_list_node; 25 | uint32_t slice; 26 | 27 | /*Suspend resume*/ 28 | uint32_t suspend_cnt; 29 | }task_t; 30 | 31 | extern task_t *g_current_task; 32 | extern task_t *g_next_task; 33 | extern list_t g_task_table[OS_PRIO_COUNT]; 34 | 35 | extern void task_init (task_t * task, void (*entry)(void *), void *param, uint32_t prio, uint32_t * stack); 36 | extern void task_sched(void); 37 | extern void task_switch(void); 38 | extern void task_run_first(void); 39 | extern void task_delay(uint32_t ticks); 40 | extern void task_delay_s(uint32_t seconds); 41 | extern void task_system_tick_handler(void); 42 | extern void init_task_module(void); 43 | extern uint32_t task_enter_critical(void); 44 | extern void task_exit_critical(uint32_t status); 45 | extern void task_sched_disable(void); 46 | extern void task_sched_enable(void); 47 | extern task_t *task_highest_ready(void); 48 | extern void task_ready(task_t *task); 49 | extern void task_unready(task_t *task); 50 | extern void task_delay_wait(task_t *task, uint32_t ticks); 51 | extern void task_delay_wakeup(task_t *task); 52 | extern void task_suspend(task_t *task); 53 | extern void task_resume(task_t *task); 54 | 55 | #endif /*TASK_H*/ 56 | -------------------------------------------------------------------------------- /09_suspend_resume/int_vector.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/int_vector.o -------------------------------------------------------------------------------- /09_suspend_resume/lib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/lib.o -------------------------------------------------------------------------------- /09_suspend_resume/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | 6 | extern uint32_t _bss; 7 | extern uint32_t _ebss; 8 | 9 | static inline void clear_bss(void) 10 | { 11 | uint8_t *start = (uint8_t *)_bss; 12 | while ((uint32_t)start < _ebss) { 13 | *start = 0; 14 | start++; 15 | } 16 | } 17 | 18 | task_t task1; 19 | task_t task2; 20 | task_t task3; 21 | task_stack_t task1_stk[1024]; 22 | task_stack_t task2_stk[1024]; 23 | task_stack_t task3_stk[1024]; 24 | 25 | void task1_entry(void *param) 26 | { 27 | init_systick(10); 28 | for(;;) { 29 | printk("%s:before suspend\n", __func__); 30 | task_suspend(&task1); 31 | printk("%s:after suspend\n", __func__); 32 | } 33 | } 34 | 35 | void delay(uint32_t delay) 36 | { 37 | while(delay--); 38 | } 39 | 40 | void task2_entry(void *param) 41 | { 42 | 43 | for(;;) { 44 | printk("%s\n", __func__); 45 | task_delay_s(1); 46 | task_resume(&task1); 47 | } 48 | } 49 | 50 | void task3_entry(void *param) 51 | { 52 | for(;;) { 53 | printk("%s\n", __func__); 54 | } 55 | } 56 | 57 | 58 | int main() 59 | { 60 | 61 | clear_bss(); 62 | 63 | DEBUG("Hello RTOS C03_Delay_List\n"); 64 | 65 | DEBUG("psp:0x%x\n", get_psp()); 66 | DEBUG("msp:0x%x\n", get_msp()); 67 | 68 | init_task_module(); 69 | 70 | task_init(&task1, task1_entry, (void *)0x11111111, 0, &task1_stk[1024]); 71 | task_init(&task2, task2_entry, (void *)0x22222222, 1, &task2_stk[1024]); 72 | //task_init(&task3, task3_entry, (void *)0x33333333, 1, &task3_stk[1024]); 73 | 74 | g_next_task = task_highest_ready(); 75 | task_run_first(); 76 | 77 | for(;;); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /09_suspend_resume/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/main.o -------------------------------------------------------------------------------- /09_suspend_resume/os_stdio.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/os_stdio.o -------------------------------------------------------------------------------- /09_suspend_resume/rtos.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/rtos.bin -------------------------------------------------------------------------------- /09_suspend_resume/rtos.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/rtos.elf -------------------------------------------------------------------------------- /09_suspend_resume/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /09_suspend_resume/task.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/09_suspend_resume/task.o -------------------------------------------------------------------------------- /10_task_delete/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /10_task_delete/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /10_task_delete/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /10_task_delete/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /10_task_delete/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /10_task_delete/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /10_task_delete/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /11_task_select/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /11_task_select/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /11_task_select/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /11_task_select/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /11_task_select/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /11_task_select/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /11_task_select/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /12_event/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /12_event/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /12_event/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | .global set_primask 14 | .global get_primask 15 | .global disable_irq 16 | .global enable_irq 17 | 18 | /*Import*/ 19 | .global g_current_task 20 | .global g_next_task 21 | .global main 22 | 23 | reset_handler: 24 | 25 | /*Set the stack as process stack*/ 26 | mov r0, #33 27 | mrs r0, CONTROL 28 | mov r1, #2 29 | orr r0, r1 30 | msr CONTROL, r0 31 | 32 | ldr r0, =_p_stack_top 33 | mov sp, r0 34 | 35 | ldr r0, =main 36 | blx r0 37 | b . 38 | 39 | get_psp: 40 | mrs r0, PSP 41 | blx lr 42 | 43 | set_psp: 44 | msr PSP, r0 45 | blx lr 46 | 47 | get_msp: 48 | mrs r0, MSP 49 | blx lr 50 | 51 | get_control_reg: 52 | mrs r0, CONTROL 53 | blx lr 54 | 55 | pendsv_handler: 56 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 57 | mrs r0, psp 58 | cbz r0, pendsv_handler_nosave 59 | 60 | /* g_current_task->psp-- = r11; 61 | * ... 62 | * g_current_task->psp-- = r4; 63 | * g_current_task->stack = psp; 64 | */ 65 | stmdb r0!, {r4-r11} 66 | ldr r1, =g_current_task 67 | ldr r1, [r1] 68 | str r0, [r1] 69 | 70 | pendsv_handler_nosave: 71 | 72 | /* *g_current_task = *g_next_task */ 73 | ldr r0, =g_current_task 74 | ldr r1, =g_next_task 75 | ldr r2, [r1] 76 | str r2, [r0] 77 | 78 | /*r0 = g_current_task->stack*/ 79 | ldr r0, [r2] 80 | ldmia r0!, {r4-r11} 81 | 82 | msr psp, r0 83 | orr lr, lr, #0x04 /*Swtich to PSP*/ 84 | bx lr 85 | 86 | get_primask: 87 | mrs r0, PRIMASK 88 | blx lr 89 | 90 | set_primask: 91 | msr PRIMASK, r0 92 | blx lr 93 | 94 | disable_irq: 95 | cpsid i 96 | blx lr 97 | 98 | enable_irq: 99 | cpsie i 100 | blx lr 101 | -------------------------------------------------------------------------------- /12_event/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /12_event/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /12_event/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | typedef enum event_type_tag { 10 | EVENT_TYPE_UNKNOWN = 0, 11 | }event_type_e; 12 | 13 | typedef struct event_tag { 14 | event_type_e type; 15 | list_t wait_list; 16 | }event_t; 17 | 18 | extern void event_init(event_t *event, event_type_e type); 19 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 20 | extern void event_wakeup(event_t *event, void *msg, uint32_t result); 21 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 22 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 23 | extern uint32_t event_wait_count(event_t *event); 24 | 25 | #endif /*EVENT_H*/ 26 | -------------------------------------------------------------------------------- /12_event/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /12_event/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | }error_e; 9 | 10 | #endif /*OS_H*/ 11 | -------------------------------------------------------------------------------- /12_event/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /12_event/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /13_semaphore/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /13_semaphore/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /13_semaphore/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /13_semaphore/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /13_semaphore/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | typedef enum event_type_tag { 10 | EVENT_TYPE_UNKNOWN = 0, 11 | EVENT_TYPE_SEM = 1, 12 | }event_type_e; 13 | 14 | typedef struct event_tag { 15 | event_type_e type; 16 | list_t wait_list; 17 | }event_t; 18 | 19 | extern void event_init(event_t *event, event_type_e type); 20 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 21 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 22 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 23 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 24 | extern uint32_t event_wait_count(event_t *event); 25 | 26 | #endif /*EVENT_H*/ 27 | -------------------------------------------------------------------------------- /13_semaphore/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /13_semaphore/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | }error_e; 10 | 11 | #endif /*OS_H*/ 12 | -------------------------------------------------------------------------------- /13_semaphore/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /13_semaphore/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /13_semaphore/main.c: -------------------------------------------------------------------------------- 1 | #include "os_stdio.h" 2 | #include 3 | #include "cm3.h" 4 | #include "task.h" 5 | #include "sem.h" 6 | 7 | extern uint32_t _bss; 8 | extern uint32_t _ebss; 9 | 10 | static inline void clear_bss(void) 11 | { 12 | uint8_t *start = (uint8_t *)_bss; 13 | while ((uint32_t)start < _ebss) { 14 | *start = 0; 15 | start++; 16 | } 17 | } 18 | 19 | task_t task1; 20 | task_t task2; 21 | task_t task3; 22 | task_t task4; 23 | task_stack_t task1_stk[1024]; 24 | task_stack_t task2_stk[1024]; 25 | task_stack_t task3_stk[1024]; 26 | task_stack_t task4_stk[1024]; 27 | 28 | sem_t sem1; 29 | sem_t sem2; 30 | 31 | void task1_entry(void *param) 32 | { 33 | init_systick(10); 34 | 35 | sem_init(&sem1, 0, 10); 36 | for(;;) { 37 | sem_acquire(&sem1, 0); 38 | printk("%s\n", __func__); 39 | task_delay_s(1); 40 | } 41 | } 42 | 43 | void delay(uint32_t delay) 44 | { 45 | while(delay--); 46 | } 47 | 48 | void task2_entry(void *param) 49 | { 50 | for(;;) { 51 | 52 | printk("%s\n", __func__); 53 | task_delay_s(1); 54 | sem_release(&sem1); 55 | } 56 | } 57 | 58 | void task3_entry(void *param) 59 | { 60 | sem_init(&sem2, 0, 10); 61 | for(;;) { 62 | sem_acquire(&sem2, 500); 63 | printk("%s\n", __func__); 64 | task_delay_s(1); 65 | } 66 | } 67 | 68 | void task4_entry(void *param) 69 | { 70 | for(;;) { 71 | printk("%s\n", __func__); 72 | task_delay_s(1); 73 | } 74 | } 75 | 76 | int main() 77 | { 78 | 79 | clear_bss(); 80 | 81 | DEBUG("Hello RTOS C03_Delay_List\n"); 82 | 83 | DEBUG("psp:0x%x\n", get_psp()); 84 | DEBUG("msp:0x%x\n", get_msp()); 85 | 86 | init_task_module(); 87 | 88 | task_init(&task1, task1_entry, (void *)0x11111111, 0, &task1_stk[1024]); 89 | task_init(&task2, task2_entry, (void *)0x22222222, 1, &task2_stk[1024]); 90 | task_init(&task3, task3_entry, (void *)0x33333333, 0, &task3_stk[1024]); 91 | //task_init(&task4, task4_entry, (void *)0x44444444, 1, &task4_stk[1024]); 92 | g_next_task = task_highest_ready(); 93 | task_run_first(); 94 | 95 | for(;;); 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /13_semaphore/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /14_mailbox/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o mailbox.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /14_mailbox/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /14_mailbox/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /14_mailbox/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /14_mailbox/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | typedef enum event_type_tag { 10 | EVENT_TYPE_UNKNOWN = 0, 11 | EVENT_TYPE_SEM = 1, 12 | EVENT_TYPE_MAILBOX = 2, 13 | }event_type_e; 14 | 15 | typedef struct event_tag { 16 | event_type_e type; 17 | list_t wait_list; 18 | }event_t; 19 | 20 | extern void event_init(event_t *event, event_type_e type); 21 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 22 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 23 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 24 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 25 | extern uint32_t event_wait_count(event_t *event); 26 | 27 | #endif /*EVENT_H*/ 28 | -------------------------------------------------------------------------------- /14_mailbox/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /14_mailbox/include/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef MAILBOX_H 2 | #define MAILBOX_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | #define MBOX_SEND_FRONT 0x12345678 8 | #define MBOX_SEND_NORMAL 0 9 | typedef struct mbox_tag { 10 | 11 | event_t event; 12 | uint32_t count; 13 | uint32_t read; 14 | uint32_t write; 15 | uint32_t max_count; 16 | void **msg_buffer; 17 | 18 | }mbox_t; 19 | 20 | typedef struct mbox_info_tag { 21 | uint32_t count; 22 | uint32_t max_count; 23 | uint32_t task_count; 24 | }mbox_info_t; 25 | 26 | extern void mbox_init(mbox_t *mbox, void **msg_buffer, uint32_t max_count); 27 | extern uint32_t mbox_get(mbox_t *mbox, void **msg, uint32_t wait_ticks); 28 | extern uint32_t mbox_get_no_wait(mbox_t *mbox, void **msg); 29 | extern uint32_t mbox_send(mbox_t *mbox, void *msg, uint32_t notify_opition); 30 | extern void mbox_flush(mbox_t *mbox); 31 | extern uint32_t mbox_destory(mbox_t *mbox); 32 | extern void mbox_get_info(mbox_t *mbox, mbox_info_t *info); 33 | #endif /*MAILBOX_H*/ 34 | -------------------------------------------------------------------------------- /14_mailbox/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | ERROR_RESOURCE_FULL, 10 | }error_e; 11 | 12 | #endif /*OS_H*/ 13 | -------------------------------------------------------------------------------- /14_mailbox/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /14_mailbox/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /14_mailbox/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /15_mem_block/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o mailbox.o memblock.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /15_mem_block/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /15_mem_block/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /15_mem_block/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #endif /*CONFIG*/ 8 | -------------------------------------------------------------------------------- /15_mem_block/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | typedef enum event_type_tag { 10 | EVENT_TYPE_UNKNOWN = 0, 11 | EVENT_TYPE_SEM = 1, 12 | EVENT_TYPE_MAILBOX = 2, 13 | EVENT_TYPE_MEM_BLOCK = 3, 14 | }event_type_e; 15 | 16 | typedef struct event_tag { 17 | event_type_e type; 18 | list_t wait_list; 19 | }event_t; 20 | 21 | extern void event_init(event_t *event, event_type_e type); 22 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 23 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 24 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 25 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 26 | extern uint32_t event_wait_count(event_t *event); 27 | 28 | #endif /*EVENT_H*/ 29 | -------------------------------------------------------------------------------- /15_mem_block/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /15_mem_block/include/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef MAILBOX_H 2 | #define MAILBOX_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | #define MBOX_SEND_FRONT 0x12345678 8 | #define MBOX_SEND_NORMAL 0 9 | typedef struct mbox_tag { 10 | 11 | event_t event; 12 | uint32_t count; 13 | uint32_t read; 14 | uint32_t write; 15 | uint32_t max_count; 16 | void **msg_buffer; 17 | 18 | }mbox_t; 19 | 20 | typedef struct mbox_info_tag { 21 | uint32_t count; 22 | uint32_t max_count; 23 | uint32_t task_count; 24 | }mbox_info_t; 25 | 26 | extern void mbox_init(mbox_t *mbox, void **msg_buffer, uint32_t max_count); 27 | extern uint32_t mbox_get(mbox_t *mbox, void **msg, uint32_t wait_ticks); 28 | extern uint32_t mbox_get_no_wait(mbox_t *mbox, void **msg); 29 | extern uint32_t mbox_send(mbox_t *mbox, void *msg, uint32_t notify_opition); 30 | extern void mbox_flush(mbox_t *mbox); 31 | extern uint32_t mbox_destory(mbox_t *mbox); 32 | extern void mbox_get_info(mbox_t *mbox, mbox_info_t *info); 33 | #endif /*MAILBOX_H*/ 34 | -------------------------------------------------------------------------------- /15_mem_block/include/memblock.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_BLOCK_H 2 | #define MEM_BLOCK_H 3 | 4 | #include "event.h" 5 | #include "os.h" 6 | #include "task.h" 7 | #include "config.h" 8 | #include 9 | #include "lib.h" 10 | 11 | typedef struct mem_block_tag { 12 | event_t event; 13 | void *start; 14 | uint32_t block_size; 15 | uint32_t max_count; 16 | list_t block_list; 17 | }mem_block_t; 18 | 19 | typedef struct mem_block_info_tag { 20 | uint32_t count; 21 | uint32_t max_count; 22 | uint32_t block_size; 23 | uint32_t task_count; 24 | }mem_block_info_t; 25 | 26 | extern void mem_block_init(mem_block_t *mem_block, uint8_t *start, uint32_t size, uint32_t block_cnt); 27 | extern uint32_t mem_block_alloc(mem_block_t *mem_block, uint8_t **mem, uint32_t wait_ticks); 28 | extern uint32_t mem_block_alloc_no_wait(mem_block_t *mem_block, uint8_t **mem); 29 | extern void mem_block_free(mem_block_t *mem_block, uint8_t *mem); 30 | extern void mem_block_get_info(mem_block_t *mem_block, mem_block_info_t *info); 31 | extern uint32_t mem_block_destory(mem_block_t *mem_block); 32 | 33 | #endif /*MEM_BLOCK_H*/ 34 | -------------------------------------------------------------------------------- /15_mem_block/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | ERROR_RESOURCE_FULL, 10 | }error_e; 11 | 12 | #endif /*OS_H*/ 13 | -------------------------------------------------------------------------------- /15_mem_block/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /15_mem_block/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /15_mem_block/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /16_timer/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o mailbox.o memblock.o timer.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /16_timer/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /16_timer/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | .global set_primask 14 | .global get_primask 15 | .global disable_irq 16 | .global enable_irq 17 | 18 | /*Import*/ 19 | .global g_current_task 20 | .global g_next_task 21 | .global main 22 | 23 | reset_handler: 24 | 25 | /*Set the stack as process stack*/ 26 | mov r0, #33 27 | mrs r0, CONTROL 28 | mov r1, #2 29 | orr r0, r1 30 | msr CONTROL, r0 31 | 32 | ldr r0, =_p_stack_top 33 | mov sp, r0 34 | 35 | ldr r0, =main 36 | blx r0 37 | b . 38 | 39 | get_psp: 40 | mrs r0, PSP 41 | blx lr 42 | 43 | set_psp: 44 | msr PSP, r0 45 | blx lr 46 | 47 | get_msp: 48 | mrs r0, MSP 49 | blx lr 50 | 51 | get_control_reg: 52 | mrs r0, CONTROL 53 | blx lr 54 | 55 | pendsv_handler: 56 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 57 | mrs r0, psp 58 | cbz r0, pendsv_handler_nosave 59 | 60 | /* g_current_task->psp-- = r11; 61 | * ... 62 | * g_current_task->psp-- = r4; 63 | * g_current_task->stack = psp; 64 | */ 65 | stmdb r0!, {r4-r11} 66 | ldr r1, =g_current_task 67 | ldr r1, [r1] 68 | str r0, [r1] 69 | 70 | pendsv_handler_nosave: 71 | 72 | /* *g_current_task = *g_next_task */ 73 | ldr r0, =g_current_task 74 | ldr r1, =g_next_task 75 | ldr r2, [r1] 76 | str r2, [r0] 77 | 78 | /*r0 = g_current_task->stack*/ 79 | ldr r0, [r2] 80 | ldmia r0!, {r4-r11} 81 | 82 | msr psp, r0 83 | orr lr, lr, #0x04 /*Swtich to PSP*/ 84 | bx lr 85 | 86 | get_primask: 87 | mrs r0, PRIMASK 88 | blx lr 89 | 90 | set_primask: 91 | msr PRIMASK, r0 92 | blx lr 93 | 94 | disable_irq: 95 | cpsid i 96 | blx lr 97 | 98 | enable_irq: 99 | cpsie i 100 | blx lr 101 | -------------------------------------------------------------------------------- /16_timer/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /16_timer/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #define OS_TIMERTASK_STACK_SIZE 1024 8 | #define OS_TIMERTASK_PRIO 1 9 | 10 | #endif /*CONFIG*/ 11 | -------------------------------------------------------------------------------- /16_timer/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | typedef enum event_type_tag { 10 | EVENT_TYPE_UNKNOWN = 0, 11 | EVENT_TYPE_SEM = 1, 12 | EVENT_TYPE_MAILBOX = 2, 13 | EVENT_TYPE_MEM_BLOCK = 3, 14 | }event_type_e; 15 | 16 | typedef struct event_tag { 17 | event_type_e type; 18 | list_t wait_list; 19 | }event_t; 20 | 21 | extern void event_init(event_t *event, event_type_e type); 22 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 23 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 24 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 25 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 26 | extern uint32_t event_wait_count(event_t *event); 27 | 28 | #endif /*EVENT_H*/ 29 | -------------------------------------------------------------------------------- /16_timer/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /16_timer/include/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef MAILBOX_H 2 | #define MAILBOX_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | #define MBOX_SEND_FRONT 0x12345678 8 | #define MBOX_SEND_NORMAL 0 9 | typedef struct mbox_tag { 10 | 11 | event_t event; 12 | uint32_t count; 13 | uint32_t read; 14 | uint32_t write; 15 | uint32_t max_count; 16 | void **msg_buffer; 17 | 18 | }mbox_t; 19 | 20 | typedef struct mbox_info_tag { 21 | uint32_t count; 22 | uint32_t max_count; 23 | uint32_t task_count; 24 | }mbox_info_t; 25 | 26 | extern void mbox_init(mbox_t *mbox, void **msg_buffer, uint32_t max_count); 27 | extern uint32_t mbox_get(mbox_t *mbox, void **msg, uint32_t wait_ticks); 28 | extern uint32_t mbox_get_no_wait(mbox_t *mbox, void **msg); 29 | extern uint32_t mbox_send(mbox_t *mbox, void *msg, uint32_t notify_opition); 30 | extern void mbox_flush(mbox_t *mbox); 31 | extern uint32_t mbox_destory(mbox_t *mbox); 32 | extern void mbox_get_info(mbox_t *mbox, mbox_info_t *info); 33 | #endif /*MAILBOX_H*/ 34 | -------------------------------------------------------------------------------- /16_timer/include/memblock.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_BLOCK_H 2 | #define MEM_BLOCK_H 3 | 4 | #include "event.h" 5 | #include "os.h" 6 | #include "task.h" 7 | #include "config.h" 8 | #include 9 | #include "lib.h" 10 | 11 | typedef struct mem_block_tag { 12 | event_t event; 13 | void *start; 14 | uint32_t block_size; 15 | uint32_t max_count; 16 | list_t block_list; 17 | }mem_block_t; 18 | 19 | typedef struct mem_block_info_tag { 20 | uint32_t count; 21 | uint32_t max_count; 22 | uint32_t block_size; 23 | uint32_t task_count; 24 | }mem_block_info_t; 25 | 26 | extern void mem_block_init(mem_block_t *mem_block, uint8_t *start, uint32_t size, uint32_t block_cnt); 27 | extern uint32_t mem_block_alloc(mem_block_t *mem_block, uint8_t **mem, uint32_t wait_ticks); 28 | extern uint32_t mem_block_alloc_no_wait(mem_block_t *mem_block, uint8_t **mem); 29 | extern void mem_block_free(mem_block_t *mem_block, uint8_t *mem); 30 | extern void mem_block_get_info(mem_block_t *mem_block, mem_block_info_t *info); 31 | extern uint32_t mem_block_destory(mem_block_t *mem_block); 32 | 33 | #endif /*MEM_BLOCK_H*/ 34 | -------------------------------------------------------------------------------- /16_timer/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | ERROR_RESOURCE_FULL, 10 | }error_e; 11 | 12 | #endif /*OS_H*/ 13 | -------------------------------------------------------------------------------- /16_timer/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /16_timer/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /16_timer/include/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | #include "event.h" 4 | #include "lib.h" 5 | 6 | typedef enum timer_state{ 7 | TIMER_CREATED, 8 | TIMER_STARTED, 9 | TIMER_RUNNING, 10 | TIMER_STOPPED, 11 | TIMER_DESTORYED, 12 | }timer_state_e; 13 | 14 | typedef struct timer_tag { 15 | 16 | list_node_t link_node; 17 | uint32_t duration_ticks; 18 | uint32_t start_delay_ticks; 19 | uint32_t delay_ticks; 20 | void (*timer_func)(void *arg); 21 | void *arg; 22 | uint32_t config; 23 | 24 | timer_state_e state; 25 | }timer_t; 26 | 27 | #define TIMER_CONFIG_TYPE_HARD (1 << 0) 28 | #define TIMER_CONFIG_TYPE_SOFT (0 << 0) 29 | 30 | extern void timer_init(timer_t *timer, uint32_t delay_ticks, uint32_t duration_ticks, 31 | void(*timer_func)(void *arg), void *arg, uint32_t config); 32 | extern void timer_module_init(void); 33 | extern void timer_start(timer_t *timer); 34 | extern void timer_stop(timer_t *timer); 35 | extern void timer_module_tick_notify(void); 36 | extern void timer_destory(timer_t *timer); 37 | 38 | #endif /*TIMER_H*/ 39 | -------------------------------------------------------------------------------- /16_timer/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /17_mutex/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o mailbox.o memblock.o timer.o mutex.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /17_mutex/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /17_mutex/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | .global set_primask 14 | .global get_primask 15 | .global disable_irq 16 | .global enable_irq 17 | 18 | /*Import*/ 19 | .global g_current_task 20 | .global g_next_task 21 | .global main 22 | 23 | reset_handler: 24 | 25 | /*Set the stack as process stack*/ 26 | mov r0, #33 27 | mrs r0, CONTROL 28 | mov r1, #2 29 | orr r0, r1 30 | msr CONTROL, r0 31 | 32 | ldr r0, =_p_stack_top 33 | mov sp, r0 34 | 35 | ldr r0, =main 36 | blx r0 37 | b . 38 | 39 | get_psp: 40 | mrs r0, PSP 41 | blx lr 42 | 43 | set_psp: 44 | msr PSP, r0 45 | blx lr 46 | 47 | get_msp: 48 | mrs r0, MSP 49 | blx lr 50 | 51 | get_control_reg: 52 | mrs r0, CONTROL 53 | blx lr 54 | 55 | pendsv_handler: 56 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 57 | mrs r0, psp 58 | cbz r0, pendsv_handler_nosave 59 | 60 | /* g_current_task->psp-- = r11; 61 | * ... 62 | * g_current_task->psp-- = r4; 63 | * g_current_task->stack = psp; 64 | */ 65 | stmdb r0!, {r4-r11} 66 | ldr r1, =g_current_task 67 | ldr r1, [r1] 68 | str r0, [r1] 69 | 70 | pendsv_handler_nosave: 71 | 72 | /* *g_current_task = *g_next_task */ 73 | ldr r0, =g_current_task 74 | ldr r1, =g_next_task 75 | ldr r2, [r1] 76 | str r2, [r0] 77 | 78 | /*r0 = g_current_task->stack*/ 79 | ldr r0, [r2] 80 | ldmia r0!, {r4-r11} 81 | 82 | msr psp, r0 83 | orr lr, lr, #0x04 /*Swtich to PSP*/ 84 | bx lr 85 | 86 | get_primask: 87 | mrs r0, PRIMASK 88 | blx lr 89 | 90 | set_primask: 91 | msr PRIMASK, r0 92 | blx lr 93 | 94 | disable_irq: 95 | cpsid i 96 | blx lr 97 | 98 | enable_irq: 99 | cpsie i 100 | blx lr 101 | -------------------------------------------------------------------------------- /17_mutex/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /17_mutex/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #define OS_TIMERTASK_STACK_SIZE 1024 8 | #define OS_TIMERTASK_PRIO 1 9 | 10 | #endif /*CONFIG*/ 11 | -------------------------------------------------------------------------------- /17_mutex/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | #if 0 10 | typedef enum event_type_tag { 11 | EVENT_TYPE_UNKNOWN = (0 << 16), 12 | EVENT_TYPE_SEM = (1 << 16), 13 | EVENT_TYPE_MAILBOX = (2 << 16), 14 | EVENT_TYPE_MEM_BLOCK = (3 << 16), 15 | EVENT_TYPE_MUTEX = (4 << 16), 16 | }event_type_e; 17 | #endif 18 | 19 | typedef uint32_t event_type_e; 20 | #define EVENT_TYPE_UNKNOWN (0 << 16) 21 | #define EVENT_TYPE_SEM (1 << 16) 22 | #define EVENT_TYPE_MAILBOX (2 << 16) 23 | #define EVENT_TYPE_MEM_BLOCK (3 << 16) 24 | #define EVENT_TYPE_MUTEX (4 << 16) 25 | 26 | typedef struct event_tag { 27 | event_type_e type; 28 | list_t wait_list; 29 | }event_t; 30 | 31 | extern void event_init(event_t *event, event_type_e type); 32 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 33 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 34 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 35 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 36 | extern uint32_t event_wait_count(event_t *event); 37 | 38 | #endif /*EVENT_H*/ 39 | -------------------------------------------------------------------------------- /17_mutex/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /17_mutex/include/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef MAILBOX_H 2 | #define MAILBOX_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | #define MBOX_SEND_FRONT 0x12345678 8 | #define MBOX_SEND_NORMAL 0 9 | typedef struct mbox_tag { 10 | 11 | event_t event; 12 | uint32_t count; 13 | uint32_t read; 14 | uint32_t write; 15 | uint32_t max_count; 16 | void **msg_buffer; 17 | 18 | }mbox_t; 19 | 20 | typedef struct mbox_info_tag { 21 | uint32_t count; 22 | uint32_t max_count; 23 | uint32_t task_count; 24 | }mbox_info_t; 25 | 26 | extern void mbox_init(mbox_t *mbox, void **msg_buffer, uint32_t max_count); 27 | extern uint32_t mbox_get(mbox_t *mbox, void **msg, uint32_t wait_ticks); 28 | extern uint32_t mbox_get_no_wait(mbox_t *mbox, void **msg); 29 | extern uint32_t mbox_send(mbox_t *mbox, void *msg, uint32_t notify_opition); 30 | extern void mbox_flush(mbox_t *mbox); 31 | extern uint32_t mbox_destory(mbox_t *mbox); 32 | extern void mbox_get_info(mbox_t *mbox, mbox_info_t *info); 33 | #endif /*MAILBOX_H*/ 34 | -------------------------------------------------------------------------------- /17_mutex/include/memblock.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_BLOCK_H 2 | #define MEM_BLOCK_H 3 | 4 | #include "event.h" 5 | #include "os.h" 6 | #include "task.h" 7 | #include "config.h" 8 | #include 9 | #include "lib.h" 10 | 11 | typedef struct mem_block_tag { 12 | event_t event; 13 | void *start; 14 | uint32_t block_size; 15 | uint32_t max_count; 16 | list_t block_list; 17 | }mem_block_t; 18 | 19 | typedef struct mem_block_info_tag { 20 | uint32_t count; 21 | uint32_t max_count; 22 | uint32_t block_size; 23 | uint32_t task_count; 24 | }mem_block_info_t; 25 | 26 | extern void mem_block_init(mem_block_t *mem_block, uint8_t *start, uint32_t size, uint32_t block_cnt); 27 | extern uint32_t mem_block_alloc(mem_block_t *mem_block, uint8_t **mem, uint32_t wait_ticks); 28 | extern uint32_t mem_block_alloc_no_wait(mem_block_t *mem_block, uint8_t **mem); 29 | extern void mem_block_free(mem_block_t *mem_block, uint8_t *mem); 30 | extern void mem_block_get_info(mem_block_t *mem_block, mem_block_info_t *info); 31 | extern uint32_t mem_block_destory(mem_block_t *mem_block); 32 | 33 | #endif /*MEM_BLOCK_H*/ 34 | -------------------------------------------------------------------------------- /17_mutex/include/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef MUTEX_H 2 | #define MUTEX_H 3 | 4 | #include "event.h" 5 | #include "task.h" 6 | 7 | typedef struct mutex_tag { 8 | 9 | event_t event; 10 | uint32_t lock_count; 11 | task_t *owner; 12 | uint32_t owner_original_prio; 13 | }mutex_t; 14 | 15 | 16 | typedef struct mutex_info_tag { 17 | uint32_t task_count; 18 | uint32_t owner_prio; 19 | uint32_t inhe_prio; 20 | task_t *owner; 21 | uint32_t locked_count; 22 | }mutex_info_t; 23 | 24 | extern void mutex_init(mutex_t *mutex); 25 | extern uint32_t mutex_lock_no_wait(mutex_t *mutex); 26 | extern uint32_t mutex_lock(mutex_t *mutex, uint32_t wait_ticks); 27 | extern uint32_t mutex_unlock(mutex_t *mutex); 28 | extern uint32_t mutex_destory(mutex_t *mutex); 29 | extern void mutex_get_info(mutex_t *mutex, mutex_info_t *info); 30 | #endif /*MUTEX_H*/ 31 | -------------------------------------------------------------------------------- /17_mutex/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | ERROR_RESOURCE_FULL, 10 | ERROR_NOT_OWNER, 11 | }error_e; 12 | 13 | #endif /*OS_H*/ 14 | -------------------------------------------------------------------------------- /17_mutex/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /17_mutex/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /17_mutex/include/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | #include "event.h" 4 | #include "lib.h" 5 | 6 | typedef enum timer_state{ 7 | TIMER_CREATED, 8 | TIMER_STARTED, 9 | TIMER_RUNNING, 10 | TIMER_STOPPED, 11 | TIMER_DESTORYED, 12 | }timer_state_e; 13 | 14 | typedef struct timer_tag { 15 | 16 | list_node_t link_node; 17 | uint32_t duration_ticks; 18 | uint32_t start_delay_ticks; 19 | uint32_t delay_ticks; 20 | void (*timer_func)(void *arg); 21 | void *arg; 22 | uint32_t config; 23 | 24 | timer_state_e state; 25 | }timer_t; 26 | 27 | #define TIMER_CONFIG_TYPE_HARD (1 << 0) 28 | #define TIMER_CONFIG_TYPE_SOFT (0 << 0) 29 | 30 | extern void timer_init(timer_t *timer, uint32_t delay_ticks, uint32_t duration_ticks, 31 | void(*timer_func)(void *arg), void *arg, uint32_t config); 32 | extern void timer_module_init(void); 33 | extern void timer_start(timer_t *timer); 34 | extern void timer_stop(timer_t *timer); 35 | extern void timer_module_tick_notify(void); 36 | extern void timer_destory(timer_t *timer); 37 | 38 | #endif /*TIMER_H*/ 39 | -------------------------------------------------------------------------------- /17_mutex/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /18_flag/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o mailbox.o memblock.o timer.o mutex.o flag_group.o 13 | 14 | rtos.bin: $(objs) 15 | ${LD} -T rtos.ld -o rtos.elf $^ 16 | ${OBJCOPY} -O binary -S rtos.elf $@ 17 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 18 | 19 | run: $(objs) 20 | ${LD} -T rtos.ld -o rtos.elf $^ 21 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 22 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 23 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 24 | 25 | debug: $(objs) 26 | ${LD} -T rtos.ld -o rtos.elf $^ 27 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 28 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 29 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 30 | 31 | %.o:%.c 32 | ${CC} $(CFLAGS) -c -o $@ $< 33 | 34 | %.o:%.s 35 | ${CC} $(CFLAGS) -c -o $@ $< 36 | 37 | clean: 38 | rm -rf *.o *.elf *.bin *.dis 39 | -------------------------------------------------------------------------------- /18_flag/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | void init_systick(uint32_t ms) 6 | { 7 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 8 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 9 | *sys_prio_p = 0xf0; 10 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 11 | systick_p->val = 0; 12 | systick_p->ctrl = 0x7; 13 | } 14 | 15 | void systick_handler(void) 16 | { 17 | /*DEBUG("systick_handler\n");*/ 18 | task_system_tick_handler(); 19 | } 20 | 21 | void trigger_pend_sv(void) 22 | { 23 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 24 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 25 | } 26 | -------------------------------------------------------------------------------- /18_flag/cm3_s.s: -------------------------------------------------------------------------------- 1 | 2 | .text 3 | .code 16 4 | .syntax unified 5 | /*Export*/ 6 | .global reset_handler 7 | .global _p_stack_top 8 | .global get_psp 9 | .global set_psp 10 | .global get_msp 11 | .global get_control_reg 12 | .global pendsv_handler 13 | .global set_primask 14 | .global get_primask 15 | .global disable_irq 16 | .global enable_irq 17 | 18 | /*Import*/ 19 | .global g_current_task 20 | .global g_next_task 21 | .global main 22 | 23 | reset_handler: 24 | 25 | /*Set the stack as process stack*/ 26 | mov r0, #33 27 | mrs r0, CONTROL 28 | mov r1, #2 29 | orr r0, r1 30 | msr CONTROL, r0 31 | 32 | ldr r0, =_p_stack_top 33 | mov sp, r0 34 | 35 | ldr r0, =main 36 | blx r0 37 | b . 38 | 39 | get_psp: 40 | mrs r0, PSP 41 | blx lr 42 | 43 | set_psp: 44 | msr PSP, r0 45 | blx lr 46 | 47 | get_msp: 48 | mrs r0, MSP 49 | blx lr 50 | 51 | get_control_reg: 52 | mrs r0, CONTROL 53 | blx lr 54 | 55 | pendsv_handler: 56 | /*CM3 will push the r0-r3, r12, r14, r15, xpsr by hardware*/ 57 | mrs r0, psp 58 | cbz r0, pendsv_handler_nosave 59 | 60 | /* g_current_task->psp-- = r11; 61 | * ... 62 | * g_current_task->psp-- = r4; 63 | * g_current_task->stack = psp; 64 | */ 65 | stmdb r0!, {r4-r11} 66 | ldr r1, =g_current_task 67 | ldr r1, [r1] 68 | str r0, [r1] 69 | 70 | pendsv_handler_nosave: 71 | 72 | /* *g_current_task = *g_next_task */ 73 | ldr r0, =g_current_task 74 | ldr r1, =g_next_task 75 | ldr r2, [r1] 76 | str r2, [r0] 77 | 78 | /*r0 = g_current_task->stack*/ 79 | ldr r0, [r2] 80 | ldmia r0!, {r4-r11} 81 | 82 | msr psp, r0 83 | orr lr, lr, #0x04 /*Swtich to PSP*/ 84 | bx lr 85 | 86 | get_primask: 87 | mrs r0, PRIMASK 88 | blx lr 89 | 90 | set_primask: 91 | msr PRIMASK, r0 92 | blx lr 93 | 94 | disable_irq: 95 | cpsid i 96 | blx lr 97 | 98 | enable_irq: 99 | cpsie i 100 | blx lr 101 | -------------------------------------------------------------------------------- /18_flag/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /18_flag/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #define OS_TIMERTASK_STACK_SIZE 1024 8 | #define OS_TIMERTASK_PRIO 1 9 | 10 | #endif /*CONFIG*/ 11 | -------------------------------------------------------------------------------- /18_flag/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | #if 0 10 | typedef enum event_type_tag { 11 | EVENT_TYPE_UNKNOWN = (0 << 16), 12 | EVENT_TYPE_SEM = (1 << 16), 13 | EVENT_TYPE_MAILBOX = (2 << 16), 14 | EVENT_TYPE_MEM_BLOCK = (3 << 16), 15 | EVENT_TYPE_MUTEX = (4 << 16), 16 | }event_type_e; 17 | #endif 18 | 19 | typedef uint32_t event_type_e; 20 | #define EVENT_TYPE_UNKNOWN (0 << 16) 21 | #define EVENT_TYPE_SEM (1 << 16) 22 | #define EVENT_TYPE_MAILBOX (2 << 16) 23 | #define EVENT_TYPE_MEM_BLOCK (3 << 16) 24 | #define EVENT_TYPE_MUTEX (4 << 16) 25 | #define EVENT_TYPE_FLAG_GROUP (5 << 16) 26 | 27 | typedef struct event_tag { 28 | event_type_e type; 29 | list_t wait_list; 30 | }event_t; 31 | 32 | extern void event_init(event_t *event, event_type_e type); 33 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 34 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 35 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 36 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 37 | extern uint32_t event_wait_count(event_t *event); 38 | extern task_t *event_wakeup_task(event_t *event, task_t *task, void *msg, uint32_t result); 39 | 40 | #endif /*EVENT_H*/ 41 | -------------------------------------------------------------------------------- /18_flag/include/flag_group.h: -------------------------------------------------------------------------------- 1 | #ifndef FLAG_GROUP_H 2 | #define FLAG_GROUP_H 3 | 4 | #include "event.h" 5 | typedef struct flag_group_tag { 6 | 7 | event_t event; 8 | uint32_t flag; 9 | }flag_group_t; 10 | 11 | typedef struct flag_group_info_tag { 12 | 13 | uint32_t flags; 14 | uint32_t task_count; 15 | }flag_group_info_t; 16 | 17 | #define FLAGGROUP_CLEAR (0x0 << 0) 18 | #define FLAGGROUP_SET (0x1 << 0) 19 | #define FLAGGROUP_ANY (0x0 << 1) 20 | #define FLAGGROUP_ALL (0x1 << 1) 21 | 22 | #define FLAGGROUP_SET_ALL (FLAGGROUP_SET | FLAGGROUP_ALL) 23 | #define FLAGGROUP_SET_ANY (FLAGGROUP_SET | FLAGGROUP_ANY) 24 | #define FLAGGROUP_CLEAR_ALL (FLAGGROUP_CLEAR | FLAGGROUP_ALL) 25 | #define FLAGGROUP_CLEAR_ANY (FLAGGROUP_CLEAR | FLAGGROUP_ANY) 26 | 27 | #define FLAGGROUP_CONSUME (1 << 7) 28 | 29 | 30 | extern void flag_group_init(flag_group_t *flag_group, uint32_t flags); 31 | extern uint32_t flag_group_wait(flag_group_t *flag_group, uint32_t wait_type, 32 | uint32_t request_flag, uint32_t *result_flag, uint32_t wait_ticks); 33 | extern uint32_t flag_group_no_wait_get(flag_group_t *flag_group, uint32_t wait_type, uint32_t request_flag, 34 | uint32_t *result_flag); 35 | extern void flag_group_notify(flag_group_t *flag_group, uint8_t is_set, uint32_t flag); 36 | extern void flag_group_get_info(flag_group_t *flag_group, flag_group_info_t *info); 37 | extern uint32_t flag_group_destory(flag_group_t *flag_group); 38 | 39 | #endif /*FLAG_GROUP_H*/ 40 | -------------------------------------------------------------------------------- /18_flag/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /18_flag/include/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef MAILBOX_H 2 | #define MAILBOX_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | #define MBOX_SEND_FRONT 0x12345678 8 | #define MBOX_SEND_NORMAL 0 9 | typedef struct mbox_tag { 10 | 11 | event_t event; 12 | uint32_t count; 13 | uint32_t read; 14 | uint32_t write; 15 | uint32_t max_count; 16 | void **msg_buffer; 17 | 18 | }mbox_t; 19 | 20 | typedef struct mbox_info_tag { 21 | uint32_t count; 22 | uint32_t max_count; 23 | uint32_t task_count; 24 | }mbox_info_t; 25 | 26 | extern void mbox_init(mbox_t *mbox, void **msg_buffer, uint32_t max_count); 27 | extern uint32_t mbox_get(mbox_t *mbox, void **msg, uint32_t wait_ticks); 28 | extern uint32_t mbox_get_no_wait(mbox_t *mbox, void **msg); 29 | extern uint32_t mbox_send(mbox_t *mbox, void *msg, uint32_t notify_opition); 30 | extern void mbox_flush(mbox_t *mbox); 31 | extern uint32_t mbox_destory(mbox_t *mbox); 32 | extern void mbox_get_info(mbox_t *mbox, mbox_info_t *info); 33 | #endif /*MAILBOX_H*/ 34 | -------------------------------------------------------------------------------- /18_flag/include/memblock.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_BLOCK_H 2 | #define MEM_BLOCK_H 3 | 4 | #include "event.h" 5 | #include "os.h" 6 | #include "task.h" 7 | #include "config.h" 8 | #include 9 | #include "lib.h" 10 | 11 | typedef struct mem_block_tag { 12 | event_t event; 13 | void *start; 14 | uint32_t block_size; 15 | uint32_t max_count; 16 | list_t block_list; 17 | }mem_block_t; 18 | 19 | typedef struct mem_block_info_tag { 20 | uint32_t count; 21 | uint32_t max_count; 22 | uint32_t block_size; 23 | uint32_t task_count; 24 | }mem_block_info_t; 25 | 26 | extern void mem_block_init(mem_block_t *mem_block, uint8_t *start, uint32_t size, uint32_t block_cnt); 27 | extern uint32_t mem_block_alloc(mem_block_t *mem_block, uint8_t **mem, uint32_t wait_ticks); 28 | extern uint32_t mem_block_alloc_no_wait(mem_block_t *mem_block, uint8_t **mem); 29 | extern void mem_block_free(mem_block_t *mem_block, uint8_t *mem); 30 | extern void mem_block_get_info(mem_block_t *mem_block, mem_block_info_t *info); 31 | extern uint32_t mem_block_destory(mem_block_t *mem_block); 32 | 33 | #endif /*MEM_BLOCK_H*/ 34 | -------------------------------------------------------------------------------- /18_flag/include/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef MUTEX_H 2 | #define MUTEX_H 3 | 4 | #include "event.h" 5 | #include "task.h" 6 | 7 | typedef struct mutex_tag { 8 | 9 | event_t event; 10 | uint32_t lock_count; 11 | task_t *owner; 12 | uint32_t owner_original_prio; 13 | }mutex_t; 14 | 15 | 16 | typedef struct mutex_info_tag { 17 | uint32_t task_count; 18 | uint32_t owner_prio; 19 | uint32_t inhe_prio; 20 | task_t *owner; 21 | uint32_t locked_count; 22 | }mutex_info_t; 23 | 24 | extern void mutex_init(mutex_t *mutex); 25 | extern uint32_t mutex_lock_no_wait(mutex_t *mutex); 26 | extern uint32_t mutex_lock(mutex_t *mutex, uint32_t wait_ticks); 27 | extern uint32_t mutex_unlock(mutex_t *mutex); 28 | extern uint32_t mutex_destory(mutex_t *mutex); 29 | extern void mutex_get_info(mutex_t *mutex, mutex_info_t *info); 30 | #endif /*MUTEX_H*/ 31 | -------------------------------------------------------------------------------- /18_flag/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | ERROR_RESOURCE_FULL, 10 | ERROR_NOT_OWNER, 11 | }error_e; 12 | 13 | #endif /*OS_H*/ 14 | -------------------------------------------------------------------------------- /18_flag/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /18_flag/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /18_flag/include/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | #include "event.h" 4 | #include "lib.h" 5 | 6 | typedef enum timer_state{ 7 | TIMER_CREATED, 8 | TIMER_STARTED, 9 | TIMER_RUNNING, 10 | TIMER_STOPPED, 11 | TIMER_DESTORYED, 12 | }timer_state_e; 13 | 14 | typedef struct timer_tag { 15 | 16 | list_node_t link_node; 17 | uint32_t duration_ticks; 18 | uint32_t start_delay_ticks; 19 | uint32_t delay_ticks; 20 | void (*timer_func)(void *arg); 21 | void *arg; 22 | uint32_t config; 23 | 24 | timer_state_e state; 25 | }timer_t; 26 | 27 | #define TIMER_CONFIG_TYPE_HARD (1 << 0) 28 | #define TIMER_CONFIG_TYPE_SOFT (0 << 0) 29 | 30 | extern void timer_init(timer_t *timer, uint32_t delay_ticks, uint32_t duration_ticks, 31 | void(*timer_func)(void *arg), void *arg, uint32_t config); 32 | extern void timer_module_init(void); 33 | extern void timer_start(timer_t *timer); 34 | extern void timer_stop(timer_t *timer); 35 | extern void timer_module_tick_notify(void); 36 | extern void timer_destory(timer_t *timer); 37 | 38 | #endif /*TIMER_H*/ 39 | -------------------------------------------------------------------------------- /18_flag/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /cmsis_rtos/CMSIS_RV/RTE_Components.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Auto generated Run-Time-Environment Component Configuration File 4 | * *** Do not modify ! *** 5 | * 6 | * Project: 'CMSIS_RV' 7 | * Target: 'Debug' 8 | */ 9 | 10 | #ifndef RTE_COMPONENTS_H 11 | #define RTE_COMPONENTS_H 12 | 13 | 14 | /* 15 | * Define the Device Header File: 16 | */ 17 | #define CMSIS_device_header "ARMCM3.h" 18 | 19 | #define RTE_CMSIS_RTOS /* CMSIS-RTOS */ 20 | #define RTE_CMSIS_RTOS_RTX /* CMSIS-RTOS Keil RTX */ 21 | #define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ 22 | #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ 23 | #define RTE_RV_GENWAIT /* RTOS Validation - GenWait test enabled */ 24 | #define RTE_RV_MAILQUEUE /* RTOS Validation - MailQueue test enabled */ 25 | #define RTE_RV_MEMORYPOOL /* RTOS Validation - MemoryPool test enabled */ 26 | #define RTE_RV_MSGQUEUE /* RTOS Validation - MsgQueue test enabled */ 27 | #define RTE_RV_MUTEX /* RTOS Validation - Mutex test enabled */ 28 | #define RTE_RV_SEMAPHORE /* RTOS Validation - Semaphore test enabled */ 29 | #define RTE_RV_SIGNAL /* RTOS Validation - Signal test enabled */ 30 | #define RTE_RV_THREAD /* RTOS Validation - Thread test enabled */ 31 | #define RTE_RV_TIMER /* RTOS Validation - Timer test enabled */ 32 | #define RTE_RV_WAITFUNC /* RTOS Validation - WaitFunc test enabled */ 33 | 34 | #endif /* RTE_COMPONENTS_H */ 35 | -------------------------------------------------------------------------------- /cmsis_rtos/CMSIS_RV/RV_Config.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | * Name: RV_Config.h 3 | * Purpose: RV Config header 4 | *---------------------------------------------------------------------------- 5 | * Copyright(c) KEIL - An ARM Company 6 | *----------------------------------------------------------------------------*/ 7 | #ifndef __RV_CONFIG_H 8 | #define __RV_CONFIG_H 9 | 10 | #include "ARMCM3.h" 11 | 12 | //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- 13 | 14 | // Common Test Settings 15 | // Print Output Format <0=> Plain Text <1=> XML 16 | // Set the test results output format to plain text or XML 17 | #ifndef PRINT_XML_REPORT 18 | #define PRINT_XML_REPORT 0 19 | #endif 20 | // Buffer size for assertions results 21 | // Set the buffer size for assertions results buffer 22 | #define BUFFER_ASSERTIONS 128 23 | // 24 | 25 | #endif /* __RV_CONFIG_H */ 26 | -------------------------------------------------------------------------------- /cmsis_rtos/CMSIS_RV/RV_Typedefs.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | * Name: DV_Typedefs.h 3 | * Purpose: Test framework filetypes and structures description 4 | *---------------------------------------------------------------------------- 5 | * Copyright(c) KEIL - An ARM Company 6 | *----------------------------------------------------------------------------*/ 7 | #ifndef __TYPEDEFS_H__ 8 | #define __TYPEDEFS_H__ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | typedef unsigned int BOOL; 16 | 17 | #ifndef __TRUE 18 | #define __TRUE 1 19 | #endif 20 | #ifndef __FALSE 21 | #define __FALSE 0 22 | #endif 23 | 24 | #ifndef ENABLED 25 | #define ENABLED 1 26 | #endif 27 | #ifndef DISABLED 28 | #define DISABLED 0 29 | #endif 30 | 31 | #ifndef NULL 32 | #ifdef __cplusplus // EC++ 33 | #define NULL 0 34 | #else 35 | #define NULL ((void *) 0) 36 | #endif 37 | #endif 38 | 39 | #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) 40 | 41 | #define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) 42 | 43 | /* Assertions and test results */ 44 | #define SET_RESULT(res, desc) __set_result(__FILENAME__, __LINE__, res, desc); 45 | #define ASSERT_TRUE(cond) __assert_true (__FILENAME__, __LINE__, cond); 46 | 47 | #endif /* __TYPEDEFS_H__ */ 48 | -------------------------------------------------------------------------------- /cmsis_rtos/Makefile: -------------------------------------------------------------------------------- 1 | TOOL_CHAIN = arm-none-eabi- 2 | CC = ${TOOL_CHAIN}gcc 3 | AS = ${TOOL_CHAIN}as 4 | LD = ${TOOL_CHAIN}ld 5 | OBJCOPY = ${TOOL_CHAIN}objcopy 6 | OBJDUMP = $(TOOL_CHAIN)objdump 7 | 8 | CFLAGS := -Wall -g -fno-builtin -gdwarf-2 -gstrict-dwarf -mcpu=cortex-m3 -mthumb -nostartfiles --specs=nosys.specs -std=c11 \ 9 | -O0 -Iinclude -ICMSIS_RV -ICMSIS_RV/Include 10 | LDFLAGS := -g 11 | 12 | objs := int_vector.o main.o cm3.o os_stdio.o cm3_s.o task.o lib.o event.o sem.o mailbox.o memblock.o timer.o mutex.o flag_group.o \ 13 | cmsis_os.o 14 | #CMSIS_RV/RV_Framework.o CMSIS_RV/cmsis_rv.o 15 | 16 | rtos.bin: $(objs) 17 | ${LD} -T rtos.ld -o rtos.elf $^ 18 | ${OBJCOPY} -O binary -S rtos.elf $@ 19 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 20 | 21 | run: $(objs) 22 | ${LD} -T rtos.ld -o rtos.elf $^ 23 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 24 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 25 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic 26 | 27 | debug: $(objs) 28 | ${LD} -T rtos.ld -o rtos.elf $^ 29 | ${OBJCOPY} -O binary -S rtos.elf rtos.bin 30 | ${OBJDUMP} -D -m arm rtos.elf > rtos.dis 31 | qemu-system-arm -M lm3s6965evb --kernel rtos.bin -nographic -s -S 32 | 33 | %.o:%.c 34 | ${CC} $(CFLAGS) -c -o $@ $< 35 | 36 | %.o:%.s 37 | ${CC} $(CFLAGS) -c -o $@ $< 38 | 39 | clean: 40 | rm -rf *.o *.elf *.bin *.dis 41 | -------------------------------------------------------------------------------- /cmsis_rtos/cm3.c: -------------------------------------------------------------------------------- 1 | #include "cm3.h" 2 | #include "os_stdio.h" 3 | #include "task.h" 4 | 5 | /* 6 | * @breif init cm3 system tick hardware 7 | * @param ms time unit 8 | * @return void 9 | */ 10 | void init_systick(uint32_t ms) 11 | { 12 | systick_t *systick_p = (systick_t *)SYSTICK_BASE; 13 | uint8_t *sys_prio_p = (uint8_t *)SYSTICK_PRIO_REG; 14 | *sys_prio_p = 0xf0; 15 | systick_p->load = ms * (SystemCoreClock / 1000) - 1; 16 | systick_p->val = 0; 17 | systick_p->ctrl = 0x7; 18 | } 19 | 20 | void systick_handler(void) 21 | { 22 | /*DEBUG("systick_handler\n");*/ 23 | task_system_tick_handler(); 24 | } 25 | 26 | void trigger_pend_sv(void) 27 | { 28 | MEM8(NVIC_SYSPRI2) = NVIC_PENDSV_PRI; /*Set PENDSVC loweset priority*/ 29 | MEM32(NVIC_INT_CTRL) = NVIC_PENDSVSET; /*Trigger PendSV*/ 30 | } 31 | -------------------------------------------------------------------------------- /cmsis_rtos/include/cm3.h: -------------------------------------------------------------------------------- 1 | #ifndef CM3_H 2 | #define CM3_H 3 | #include 4 | 5 | #define SCS_BASE (0xE000E000) /*System Control Space Base Address */ 6 | #define SYSTICK_BASE (SCS_BASE + 0x0010) /*SysTick Base Address*/ 7 | #define SCB_BASE (SCS_BASE + 0x0D00) 8 | #define SystemCoreClock 12000000UL 9 | #define SYSTICK_PRIO_REG (0xE000ED23) 10 | 11 | #define NVIC_INT_CTRL 0xE000ED04 12 | #define NVIC_PENDSVSET 0x10000000 13 | #define NVIC_SYSPRI2 0xE000ED22 14 | #define NVIC_PENDSV_PRI 0x000000FF 15 | 16 | #define MEM32(addr) *(volatile uint32_t *)(addr) 17 | #define MEM8(addr) *(volatile uint8_t *)(addr) 18 | 19 | typedef struct systick_tag { 20 | volatile uint32_t ctrl; 21 | volatile uint32_t load; 22 | volatile uint32_t val; 23 | volatile uint32_t calrb; 24 | }systick_t; 25 | 26 | extern uint32_t get_psp(void); 27 | extern void set_psp(uint32_t psp); 28 | extern uint32_t get_msp(void); 29 | extern uint32_t get_control_reg(void); 30 | extern uint32_t get_primask(void); 31 | extern void set_primask(uint32_t primask); 32 | extern void disable_irq(void); 33 | extern void enable_irq(void); 34 | 35 | extern void init_systick(uint32_t ms); 36 | extern void trigger_pend_sv(void); 37 | extern void pendsv_handler(void); 38 | #endif /*CM3_H*/ 39 | -------------------------------------------------------------------------------- /cmsis_rtos/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define OS_PRIO_COUNT 32 5 | #define OS_SLICE_MAX 10 6 | 7 | #define OS_TIMERTASK_STACK_SIZE 1024 8 | #define OS_TIMERTASK_PRIO 1 9 | 10 | #endif /*CONFIG*/ 11 | -------------------------------------------------------------------------------- /cmsis_rtos/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | #include 5 | #include "os_stdio.h" 6 | #include "lib.h" 7 | #include "task.h" 8 | 9 | #if 0 10 | typedef enum event_type_tag { 11 | EVENT_TYPE_UNKNOWN = (0 << 16), 12 | EVENT_TYPE_SEM = (1 << 16), 13 | EVENT_TYPE_MAILBOX = (2 << 16), 14 | EVENT_TYPE_MEM_BLOCK = (3 << 16), 15 | EVENT_TYPE_MUTEX = (4 << 16), 16 | }event_type_e; 17 | #endif 18 | 19 | typedef uint32_t event_type_e; 20 | #define EVENT_TYPE_UNKNOWN (0 << 16) 21 | #define EVENT_TYPE_SEM (1 << 16) 22 | #define EVENT_TYPE_MAILBOX (2 << 16) 23 | #define EVENT_TYPE_MEM_BLOCK (3 << 16) 24 | #define EVENT_TYPE_MUTEX (4 << 16) 25 | #define EVENT_TYPE_FLAG_GROUP (5 << 16) 26 | 27 | typedef struct event_tag { 28 | event_type_e type; 29 | list_t wait_list; 30 | }event_t; 31 | 32 | extern void event_init(event_t *event, event_type_e type); 33 | extern void event_wait(event_t *event, task_t *task, void *msg, uint32_t state, uint32_t timeout); 34 | extern task_t *event_wakeup(event_t *event, void *msg, uint32_t result); 35 | extern void event_remove_task(task_t *task, void *msg, uint32_t result); 36 | extern uint32_t event_remove_all(event_t *event, void *msg, uint32_t result); 37 | extern uint32_t event_wait_count(event_t *event); 38 | extern task_t *event_wakeup_task(event_t *event, task_t *task, void *msg, uint32_t result); 39 | 40 | #endif /*EVENT_H*/ 41 | -------------------------------------------------------------------------------- /cmsis_rtos/include/flag_group.h: -------------------------------------------------------------------------------- 1 | #ifndef FLAG_GROUP_H 2 | #define FLAG_GROUP_H 3 | 4 | #include "event.h" 5 | typedef struct flag_group_tag { 6 | 7 | event_t event; 8 | uint32_t flag; 9 | }flag_group_t; 10 | 11 | typedef struct flag_group_info_tag { 12 | 13 | uint32_t flags; 14 | uint32_t task_count; 15 | }flag_group_info_t; 16 | 17 | #define FLAGGROUP_CLEAR (0x0 << 0) 18 | #define FLAGGROUP_SET (0x1 << 0) 19 | #define FLAGGROUP_ANY (0x0 << 1) 20 | #define FLAGGROUP_ALL (0x1 << 1) 21 | 22 | #define FLAGGROUP_SET_ALL (FLAGGROUP_SET | FLAGGROUP_ALL) 23 | #define FLAGGROUP_SET_ANY (FLAGGROUP_SET | FLAGGROUP_ANY) 24 | #define FLAGGROUP_CLEAR_ALL (FLAGGROUP_CLEAR | FLAGGROUP_ALL) 25 | #define FLAGGROUP_CLEAR_ANY (FLAGGROUP_CLEAR | FLAGGROUP_ANY) 26 | 27 | #define FLAGGROUP_CONSUME (1 << 7) 28 | 29 | 30 | extern void flag_group_init(flag_group_t *flag_group, uint32_t flags); 31 | extern uint32_t flag_group_wait(flag_group_t *flag_group, uint32_t wait_type, 32 | uint32_t request_flag, uint32_t *result_flag, uint32_t wait_ticks); 33 | extern uint32_t flag_group_no_wait_get(flag_group_t *flag_group, uint32_t wait_type, uint32_t request_flag, 34 | uint32_t *result_flag); 35 | extern void flag_group_notify(flag_group_t *flag_group, uint8_t is_set, uint32_t flag); 36 | extern void flag_group_get_info(flag_group_t *flag_group, flag_group_info_t *info); 37 | extern uint32_t flag_group_destory(flag_group_t *flag_group); 38 | 39 | #endif /*FLAG_GROUP_H*/ 40 | -------------------------------------------------------------------------------- /cmsis_rtos/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | /*Bitmap*/ 7 | typedef struct bitmap_tag { 8 | uint32_t bitmap; 9 | }bitmap_t; 10 | 11 | extern void bitmap_init(bitmap_t *bitmap); 12 | extern uint32_t bitmap_count(void); 13 | extern void bitmap_set(bitmap_t *bitmap, uint32_t pos); 14 | extern void bitmap_clear(bitmap_t *bitmap, uint32_t pos); 15 | extern uint32_t bitmap_get_first_set(bitmap_t *bitmap); 16 | 17 | /*Double Linked List*/ 18 | typedef struct list_node_tag { 19 | struct list_node_tag *prev; 20 | struct list_node_tag *next; 21 | }list_node_t; 22 | 23 | extern void list_node_init(list_node_t *node); 24 | 25 | typedef struct list_tag { 26 | list_node_t head; 27 | uint32_t node_count; 28 | }list_t; 29 | 30 | #define container_of(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name) 31 | extern void list_init(list_t *list); 32 | extern uint32_t list_count(list_t *list); 33 | extern list_node_t *list_head(list_t *list); 34 | extern list_node_t *list_tail(list_t *list); 35 | extern list_node_t *node_prev(list_node_t *list_node); 36 | extern list_node_t *node_next(list_node_t *list_node); 37 | extern void list_remove_all(list_t *list); 38 | extern void list_insert_head(list_t *list, list_node_t *list_node); 39 | extern void list_append_last(list_t *list, list_node_t *list_node); 40 | extern list_node_t *list_remove_first(list_t *list); 41 | extern void list_remove(list_t *list, list_node_t *node); 42 | 43 | #endif /*LIB_H*/ 44 | -------------------------------------------------------------------------------- /cmsis_rtos/include/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef MAILBOX_H 2 | #define MAILBOX_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | #define MBOX_SEND_FRONT 0x12345678 8 | #define MBOX_SEND_NORMAL 0 9 | typedef struct mbox_tag { 10 | 11 | event_t event; 12 | uint32_t count; 13 | uint32_t read; 14 | uint32_t write; 15 | uint32_t max_count; 16 | void **msg_buffer; 17 | 18 | }mbox_t; 19 | 20 | typedef struct mbox_info_tag { 21 | uint32_t count; 22 | uint32_t max_count; 23 | uint32_t task_count; 24 | }mbox_info_t; 25 | 26 | extern void mbox_init(mbox_t *mbox, void **msg_buffer, uint32_t max_count); 27 | extern uint32_t mbox_get(mbox_t *mbox, void **msg, uint32_t wait_ticks); 28 | extern uint32_t mbox_get_no_wait(mbox_t *mbox, void **msg); 29 | extern uint32_t mbox_send(mbox_t *mbox, void *msg, uint32_t notify_opition); 30 | extern void mbox_flush(mbox_t *mbox); 31 | extern uint32_t mbox_destory(mbox_t *mbox); 32 | extern void mbox_get_info(mbox_t *mbox, mbox_info_t *info); 33 | #endif /*MAILBOX_H*/ 34 | -------------------------------------------------------------------------------- /cmsis_rtos/include/memblock.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_BLOCK_H 2 | #define MEM_BLOCK_H 3 | 4 | #include "event.h" 5 | #include "os.h" 6 | #include "task.h" 7 | #include "config.h" 8 | #include 9 | #include "lib.h" 10 | 11 | typedef struct mem_block_tag { 12 | event_t event; 13 | void *start; 14 | uint32_t block_size; 15 | uint32_t max_count; 16 | list_t block_list; 17 | }mem_block_t; 18 | 19 | typedef struct mem_block_info_tag { 20 | uint32_t count; 21 | uint32_t max_count; 22 | uint32_t block_size; 23 | uint32_t task_count; 24 | }mem_block_info_t; 25 | 26 | extern void mem_block_init(mem_block_t *mem_block, uint8_t *start, uint32_t size, uint32_t block_cnt); 27 | extern uint32_t mem_block_alloc(mem_block_t *mem_block, uint8_t **mem, uint32_t wait_ticks); 28 | extern uint32_t mem_block_alloc_no_wait(mem_block_t *mem_block, uint8_t **mem); 29 | extern void mem_block_free(mem_block_t *mem_block, uint8_t *mem); 30 | extern void mem_block_get_info(mem_block_t *mem_block, mem_block_info_t *info); 31 | extern uint32_t mem_block_destory(mem_block_t *mem_block); 32 | 33 | #endif /*MEM_BLOCK_H*/ 34 | -------------------------------------------------------------------------------- /cmsis_rtos/include/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef MUTEX_H 2 | #define MUTEX_H 3 | 4 | #include "event.h" 5 | #include "task.h" 6 | 7 | typedef struct mutex_tag { 8 | 9 | event_t event; 10 | uint32_t lock_count; 11 | task_t *owner; 12 | uint32_t owner_original_prio; 13 | }mutex_t; 14 | 15 | 16 | typedef struct mutex_info_tag { 17 | uint32_t task_count; 18 | uint32_t owner_prio; 19 | uint32_t inhe_prio; 20 | task_t *owner; 21 | uint32_t locked_count; 22 | }mutex_info_t; 23 | 24 | extern void mutex_init(mutex_t *mutex); 25 | extern uint32_t mutex_lock_no_wait(mutex_t *mutex); 26 | extern uint32_t mutex_lock(mutex_t *mutex, uint32_t wait_ticks); 27 | extern uint32_t mutex_unlock(mutex_t *mutex); 28 | extern uint32_t mutex_destory(mutex_t *mutex); 29 | extern void mutex_get_info(mutex_t *mutex, mutex_info_t *info); 30 | #endif /*MUTEX_H*/ 31 | -------------------------------------------------------------------------------- /cmsis_rtos/include/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | 4 | #include 5 | typedef enum error_type_enum { 6 | NO_ERROR = 0, 7 | ERROR_TIMEOUT = 1, 8 | ERROR_DEL = 2, 9 | ERROR_RESOURCE_FULL, 10 | ERROR_NOT_OWNER, 11 | }error_e; 12 | 13 | #endif /*OS_H*/ 14 | -------------------------------------------------------------------------------- /cmsis_rtos/include/os_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_STDIO_H 2 | #define OS_STDIO_H 3 | 4 | #include 5 | 6 | #define NULL 0 7 | extern void printk(const char *fmt, ...); 8 | extern int memset(void *mem, uint8_t val, uint32_t sz); 9 | extern int memcpy(void *dst, const void *src, uint32_t sz); 10 | extern int memcmp(void *mem1, void *mem2, uint32_t sz); 11 | extern int strcmp(char *str1, char *str2); 12 | extern int strncmp(char *str1, char *str2, uint32_t sz); 13 | extern int strtoul(char *str, uint32_t *val); 14 | extern int strtol(char *str, int *val); 15 | extern uint32_t strlen(char *str); 16 | extern int strcpy(char *dst, char *src); 17 | extern void no_printk(const char *fmt, ...); 18 | 19 | #define NEED_DEBUG 20 | #ifdef NEED_DEBUG 21 | #define DEBUG printk 22 | #else 23 | #define DEBUG no_printk 24 | #endif /*DEBUG*/ 25 | 26 | #endif /*OS_STDIO_H*/ 27 | -------------------------------------------------------------------------------- /cmsis_rtos/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef SEM_H 2 | #define SEM_H 3 | 4 | #include "event.h" 5 | #include "config.h" 6 | 7 | typedef struct sem_tag { 8 | 9 | event_t event; 10 | uint32_t count; 11 | uint32_t max_count; 12 | }sem_t; 13 | 14 | typedef struct sem_info_tag { 15 | uint32_t count; 16 | uint32_t max_count; 17 | uint32_t task_count; 18 | }sem_info_t; 19 | 20 | extern void sem_init(sem_t *sem, uint32_t count, uint32_t max_count); 21 | extern uint32_t sem_acquire(sem_t *sem, uint32_t wait_ticks); 22 | extern uint32_t sem_acquire_no_wait(sem_t *sem); 23 | extern void sem_release(sem_t *sem); 24 | extern void sem_get_info(sem_t *sem, sem_info_t *info); 25 | extern uint32_t sem_destory(sem_t *sem); 26 | 27 | #endif /*SEM_H*/ 28 | -------------------------------------------------------------------------------- /cmsis_rtos/include/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | #include "event.h" 4 | #include "lib.h" 5 | 6 | typedef enum timer_state{ 7 | TIMER_CREATED, 8 | TIMER_STARTED, 9 | TIMER_RUNNING, 10 | TIMER_STOPPED, 11 | TIMER_DESTORYED, 12 | }timer_state_e; 13 | 14 | typedef struct timer_tag { 15 | 16 | list_node_t link_node; 17 | uint32_t duration_ticks; 18 | uint32_t start_delay_ticks; 19 | uint32_t delay_ticks; 20 | void (*timer_func)(void *arg); 21 | void *arg; 22 | uint32_t config; 23 | 24 | timer_state_e state; 25 | }timer_t; 26 | 27 | #define TIMER_CONFIG_TYPE_HARD (1 << 0) 28 | #define TIMER_CONFIG_TYPE_SOFT (0 << 0) 29 | 30 | extern void timer_init(timer_t *timer, uint32_t delay_ticks, uint32_t duration_ticks, 31 | void(*timer_func)(void *arg), void *arg, uint32_t config); 32 | extern void timer_module_init(void); 33 | extern void timer_start(timer_t *timer); 34 | extern void timer_stop(timer_t *timer); 35 | extern void timer_module_tick_notify(void); 36 | extern void timer_destory(timer_t *timer); 37 | 38 | #endif /*TIMER_H*/ 39 | -------------------------------------------------------------------------------- /cmsis_rtos/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cmsis_os.h" 3 | 4 | /* Because CMSIS RTOS use CamelNaming, so the app 5 | * use the same naming type 6 | * */ 7 | osThreadId threadId0; 8 | osThreadId threadId1; 9 | 10 | void thread0(const void *arg) 11 | { 12 | init_systick(1); 13 | 14 | for (;;) { 15 | printk("%s\n", __func__); 16 | osDelay(1000); 17 | } 18 | } 19 | 20 | void thread1(const void *arg) 21 | { 22 | for (;;) { 23 | printk("%s\n", __func__); 24 | osDelay(1000); 25 | } 26 | } 27 | 28 | osThreadDef(thread0, 0, 1, 1024); 29 | osThreadDef(thread1, 1, 1, 1024); 30 | 31 | int main() 32 | { 33 | osKernelInitialize(); 34 | 35 | threadId0 = osThreadCreate(osThread(thread0), (void *)NULL); 36 | threadId1 = osThreadCreate(osThread(thread1), (void *)NULL); 37 | 38 | osKernelStart(); 39 | 40 | for(;;); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /cmsis_rtos/rtos.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K 4 | SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : 10 | { 11 | _text = .; 12 | KEEP(*(.isr_vector)) 13 | *(.text*) 14 | *(.rodata*) 15 | _etext = .; 16 | } > FLASH 17 | 18 | /DISCARD/ : 19 | { 20 | *(.ARM.exidx*) 21 | *(.gnu.linkonce.armexidx.*) 22 | } 23 | 24 | .data : AT(ADDR(.text) + SIZEOF(.text)) 25 | { 26 | _data = .; 27 | *(vtable) 28 | *(.data*) 29 | _edata = .; 30 | } > SRAM 31 | 32 | .bss : 33 | { 34 | _bss = .; 35 | *(.bss*) 36 | *(COMMON) 37 | _ebss = .; 38 | } > SRAM 39 | 40 | . = ALIGN(32); /*Not sure if this needs to be done, but why not.*/ 41 | _p_stack_bottom = .; 42 | . = . + 0x4000; 43 | _p_stack_top = 0x20008000; 44 | . = . + 0x4000; /*Allocate 4K for the Stack.*/ 45 | _stack_top = 0x2000c000; /*Address of the top of the heap, also end of RAM.*/ 46 | } 47 | -------------------------------------------------------------------------------- /kill_qemu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | 4 | ret = os.popen("ps aux | grep qemu") 5 | line = ret.read().split(" ") 6 | print line 7 | kill_cmd = "kill -9 {}".format(line[7]) 8 | os.system(kill_cmd) 9 | -------------------------------------------------------------------------------- /tools/qemu-system-arm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiaminMa/write_rtos_in_3days/3d6a56ba2f96b1dd923aeb885f4786d8d1d7ca00/tools/qemu-system-arm --------------------------------------------------------------------------------