diff options
| author | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
|---|---|---|
| committer | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
| commit | 33613a85afc4b1481367fbe92a17ee59c240250b (patch) | |
| tree | 670b842326116b376b505ec2263878912fca97e2 /Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM | |
| download | Studium-master.tar.gz Studium-master.tar.bz2 | |
Diffstat (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM')
3 files changed, 247 insertions, 0 deletions
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 <rom-base> -RW <ram-base>\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 <stdio.h>
+
+/* 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 <rom-base> -RW <ram-base>\r\n");
+ }
+
+ sprintf(s, "ROM is at address %p, RAM is at address %p\n", rom_code_base, ram_data_base);
+ Write0(s);
+}
|
