Wednesday, November 30, 2011

Odd/even value for Cortex M3 reset vector

After reset the CM3 loads it's startup address from address 0x00000004.
The value at that location should be odd (LSB set) denoting the thumb destination. All exception and interrupt vectors following reset vector should be odd.
The reset vector might not have the LSB set by the linker. This is when reset handler code is written in assembler.
It's label is usually used in exception handlers table, but the linker doesn't know that this is a THUMB function address, so it doesn't change the value in exception table. It actually shouldn't since it could be a label of some data table used elsewhere - linker doesn't know anything about exception table either!
We need to tell the linker that some label is a THUMB function. GCC provides '--thumb-entry' command line switch to tell the linker about this one function but I couldn't get it to work. What helped was marking the label as THUMB function with '.type' and/or '.thumb_func' directive - depends on the GCC build/version you are using.


.type Reset, %function
.thumb_func
Reset:
  <code here>

To have some other function exported and available for linkage also add .global for the symbol:

.global Reset

Tuesday, November 29, 2011

Enabling VFP on Cortex R4

Before VFP extension on Cortex can be used, it needs to be enabled.
Following is a C code that does that.
Tested on TMS570 with GCC compiler.
// enable coprocessor 10 and 11 access
asm(" MRC p15,0,R0,c1,c0,2"); // first read CPACR
asm(" ORR R0,R0,#0xF0,16");   // adjust CP10 and CP11 access bits
asm(" MCR p15,0,R0,c1,c0,2"); // write modified CPACR back
asm(" MRC p15,0,R0,c1,c0,2"); // read back - optionally could check:
                              // if 0x00F00000 mask not set the VFP is not present

// When the Security Extensions are implemented,
// the NSACR controls whether each coprocessor can be
// accessed from the Non-secure state

// enable the Advanced SIMD and VFP extensions  
asm(" FMRX R0,FPEXC");      // read FPEXC
asm(" ORR  R0,R0,#0x40,8"); // set EN bit
asm(" FMXR FPEXC,R0");      // write modified value back to FPEXC  

// VFP instruction execution is now allowed
asm(" VMOV S0,R0");

Test post

Welcome!

This is what I do.

This is test post in my new blog about embedded design.