From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../ARM202U/EXAMPLES/ROM/EX.C | 52 +++++++ .../ARM202U/EXAMPLES/ROM/INIT.S | 164 +++++++++++++++++++++ .../ARM202U/EXAMPLES/ROM/SPRINTF.C | 31 ++++ 3 files changed, 247 insertions(+) create mode 100644 Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C create mode 100644 Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S create mode 100644 Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM') diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C new file mode 100644 index 0000000..4430177 --- /dev/null +++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C @@ -0,0 +1,52 @@ +/* We use the following Debug Monitor SWIs to write things out + * in this example + */ +extern __swi(0) WriteC(char c); /* Write a character */ +extern __swi(2) Write0(char *s); /* Write a string */ + +/* The following symbols are defined by the linker and define + * various memory regions which may need to be copied or initialised + */ +extern char Image$$RO$$Limit[]; +extern char Image$$RW$$Base[]; + + +/* We define some more meaningfull names here */ +#define rom_data_base Image$$RO$$Limit +#define ram_data_base Image$$RW$$Base + +/* This is an example of a pre-initialised variable. */ +static unsigned factory_id = 0xAA55AA55; /* Factory set ID */ + +/* This is an example of an uninitialised (or 0 initialised) variable */ +static char display[8][40]; /* Screen buffer */ + +static const char hex[16] = "0123456789ABCDEF"; + +static void pr_hex(unsigned n) +{ + int i; + + for (i = 0; i < 8; i++) { + WriteC(hex[n >> 28]); + n <<= 4; + } +} + +void C_Entry(void) +{ + if (rom_data_base == ram_data_base) { + Write0("Warning: Image has been linked as an application. To link as a ROM image\r\n"); + Write0(" link with the options -RO -RW \r\n"); + } + + Write0("'factory_id' is at address "); + pr_hex((unsigned)&factory_id); + Write0(", contents = "); + pr_hex((unsigned)factory_id); + Write0("\r\n"); + + Write0("'display' is at address "); + pr_hex((unsigned)display); + Write0("\r\n"); +} diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S new file mode 100644 index 0000000..3786ac7 --- /dev/null +++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S @@ -0,0 +1,164 @@ +; +; The AREA must have the attribute READONLY, otherwise the linker will not +; place it in ROM. +; +; The AREA must have the attribute CODE, otherwise the assembler will not +; let us put any code in this AREA +; +; Note the '|' character is used to surround any symbols which contain +; non standard characters like '!'. + + AREA Init, CODE, READONLY + +; Now some standard definitions... + +Mode_IRQ EQU 0x12 +Mode_SVC EQU 0x13 + +I_Bit EQU 0x80 +F_Bit EQU 0x40 + +SWI_Exit EQU 0x11 + +; Locations of various things in our memory system + +RAM_Base EQU 0x10000000 ; 64k RAM at this base +RAM_Limit EQU 0x10010000 + +IRQ_Stack EQU RAM_Limit ; 1K IRQ stack at top of memory +SVC_Stack EQU RAM_Limit-1024 ; followed by SVC stack + +; --- Define __main & set entry point + ENTRY + +; --- Setup interrupt / exception vectors + IF :DEF: ROM_AT_ADDRESS_ZERO +; If the ROM is at address 0 this is just a sequence of branches + B Reset_Handler + B Undefined_Handler + B SWI_Handler + B Prefetch_Handler + B Abort_Handler + NOP ; Reserved vector + B IRQ_Handler + B FIQ_Handler + ELSE +; Otherwise we copy a sequence of LDR PC instructions over the vectors +; (Note: We copy LDR PC instructions because branch instructions +; could not simply be copied, the offset in the branch instruction +; would have to be modified so that it branched into ROM. Also, a +; branch instructions might not reach if the ROM is at an address +; > 32M). + MOV R8, #0 + ADR R9, Vector_Init_Block + LDMIA R9!, {R0-R7} + STMIA R8!, {R0-R7} + LDMIA R9!, {R0-R7} + STMIA R8!, {R0-R7} + +; Now fall into the LDR PC, Reset_Addr instruction which will continue +; execution at 'Reset_Handler' + +Vector_Init_Block + LDR PC, Reset_Addr + LDR PC, Undefined_Addr + LDR PC, SWI_Addr + LDR PC, Prefetch_Addr + LDR PC, Abort_Addr + NOP + LDR PC, IRQ_Addr + LDR PC, FIQ_Addr + +Reset_Addr DCD Reset_Handler +Undefined_Addr DCD Undefined_Handler +SWI_Addr DCD SWI_Handler +Prefetch_Addr DCD Prefetch_Handler +Abort_Addr DCD Abort_Handler + DCD 0 ; Reserved vector +IRQ_Addr DCD IRQ_Handler +FIQ_Addr DCD FIQ_Handler + ENDIF + +; The following handlers do not do anything useful in this example. +; +Undefined_Handler + B Undefined_Handler +SWI_Handler + B SWI_Handler +Prefetch_Handler + B Prefetch_Handler +Abort_Handler + B Abort_Handler +IRQ_Handler + B IRQ_Handler +FIQ_Handler + B FIQ_Handler + +; The RESET entry point +Reset_Handler + +; --- Initialise stack pointer registers +; Enter IRQ mode and set up the IRQ stack pointer + MOV R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts + MSR CPSR, R0 + LDR R13, =IRQ_Stack + +; Set up other stack pointers if necessary + ; ... + +; Set up the SVC stack pointer last and return to SVC mode + MOV R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts + MSR CPSR, R0 + LDR R13, =SVC_Stack + +; --- Initialise memory system + ; ... + +; --- Initialise critical IO devices + ; ... + +; --- Initialise interrupt system variables here + ; ... + +; --- Enable interrupts +; Now safe to enable interrupts, so do this and remain in SVC mode + MOV R0, #Mode_SVC:OR:F_Bit ; Only IRQ enabled + MSR CPSR, R0 + +; --- Initialise memory required by C code + + IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data) + IMPORT |Image$$RW$$Base| ; Base of RAM to initialise + IMPORT |Image$$ZI$$Base| ; Base and limit of area + IMPORT |Image$$ZI$$Limit| ; to zero initialise + + LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data + LDR r1, =|Image$$RW$$Base| ; and RAM copy + LDR r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data + CMP r0, r1 ; Check that they are different + BEQ %1 +0 CMP r1, r3 ; Copy init data + LDRCC r2, [r0], #4 + STRCC r2, [r1], #4 + BCC %0 +1 LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment + MOV r2, #0 +2 CMP r3, r1 ; Zero init + STRCC r2, [r3], #4 + BCC %2 + +; --- Now we enter the C code + + IMPORT C_Entry + [ :DEF:THUMB + ORR lr, pc, #1 + BX lr + CODE16 ; Next instruction will be Thumb + ] + BL C_Entry +; In a real application we wouldn't normally expect to return, however +; this example does so the debug monitor swi SWI_Exit is used to halt the +; application. + SWI SWI_Exit + + END diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C new file mode 100644 index 0000000..6a5d4c9 --- /dev/null +++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C @@ -0,0 +1,31 @@ +#include + +/* We use the following Debug Monitor SWIs to write things out + * in this example + */ +extern __swi(2) Write0(char *s); /* Write a string */ + +/* The following symbols are defined by the linker and define + * various memory regions which may need to be copied or initialised + */ +extern char Image$$RO$$Base[]; +extern char Image$$RO$$Limit[]; +extern char Image$$RW$$Base[]; + +/* We define some more meaningful names here */ +#define rom_code_base Image$$RO$$Base +#define rom_data_base Image$$RO$$Limit +#define ram_data_base Image$$RW$$Base + +void C_Entry(void) +{ + char s[80]; + + if (rom_data_base == ram_data_base) { + Write0("Warning: Image has been linked as an application. To link as a ROM image\r\n"); + Write0(" link with the options -RO -RW \r\n"); + } + + sprintf(s, "ROM is at address %p, RAM is at address %p\n", rom_code_base, ram_data_base); + Write0(s); +} -- cgit v1.2.3