I'm trying to relocate and dynamically change the vector table's contents. Keeping this in mind, I have the following code:
sample.c:
extern void svc_handler(void);volatile uint32_t *VTOR;stl_vect_t *vect = ptr; // I've ensured that ptr is aligned to 1024B and has sufficient spaceVTOR = 0xE000ED08u;vect->SVC = svc_handler; // svc_handler is a custom function defined elsewhere*VTOR = vect; // Don't care about the other exceptions.// ......// Some Code// ......svc #0
where,
sample.h:
typedef struct { uint32_t *SPMain; void (*Reset)(void); void (*NMI)(void); void (*HardFault)(void); void (*MemManage)(void); void (*BusFault)(void); void (*UsageFault)(void); void (*SecureFault)(void);uint32_t Res[3]; void (*SVC)(void); void (*DebugMonitor)(void); uint32_t Res4; void (*PendSV)(void); void (*SysTick)(void); void (*IRQ[NUMIRQ])(void);} stl_vect_t __attribute__((aligned(1024)));
typedef struct {
uint32_t *SPMain;
void (*Reset)(void);
void (*NMI)(void);
void (*HardFault)(void);
void (*MemManage)(void);
void (*BusFault)(void);
void (*UsageFault)(void);
void (*SecureFault)(void);
uint32_t Res[3];
void (*SVC)(void);
void (*DebugMonitor)(void);
uint32_t Res4;
void (*PendSV)(void);
void (*SysTick)(void);
void (*IRQ[NUMIRQ])(void);
} stl_vect_t __attribute__((aligned(1024)));
The code in sample.c seems to trigger an SVC, however, this keeps escalating to a HardFault due to the SVC. It seems like this is due to an INVST fault upon SVC entry. I've checked to ensure that the vect->SVC[0] is set to 1. Any other reason this can come up?
Thanks in advance.
Update 23/11/2020: I see that the EPSR.T bit is set to 0 upon the attempt to handle the SVC - Can't understand why. As noted earlier, I can see that vect->SVC's bit[0] is set to '1'. Also, there's definitely a thumb instruction at svc_handler.
Update 24/11/2020: I made the following changes:
extern void svc_handler(void);const stl_vect_t vect = {.SVC = svc_handler}; // Global allocated in CODE-Region....volatile uint32_t *VTOR;VTOR = 0xE000ED08u;*VTOR = (uint32_t) &vect;// ......// Some Code// ......svc #0
Now, this seems to work perfectly!
Again, after make just one change from this code,
extern void svc_handler(void);stl_vect_t vect; // Global allocated in SRAM-Region....volatile uint32_t *VTOR;VTOR = 0xE000ED08u;vect.SVC = svc_handler;*VTOR = (uint32_t) &vect;// ......// Some Code// ......svc #0
This causes an INVSTATE exception. Any idea why declaring vect as a non-const causes an INVSTATE fault? The v8M architecture specification clearly states that you locate the vector table in the CODE, SRAM, External RAM, or External Device areas of the system memory map. So I would assume that nothing in the architecture should stop anyone changing the VectorTable entries at runtime. Yet it seems this is the issue.
Are you sure, that the exception is caused by the SVC? (So if you do not call it, your code runs w/o problem.)Is vect (if in RAM) completely initialized (esp. Interrupts, systick)?
Did you double check bit[0]?
Regarding exception being caused by SVC - Yes. I can confirm after testing that the SVC causes the exception. Removing the SVC causes no problems with the code.
Regarding initialisation of vect - Not all handlers are initialized. Just the the SVC vector-table entry is initialized. Is this potentially problematic? In (Update 24/11/2020), the first example does not intialize all the other handlers, but this still works i.e., the SVC handler is taken and executed correctly.
Regarding bit[0] of the vector table entry - Yes. Double checked this. This is set to 0xe9d, where, bit[0] is 1'b1.
Thanks for all the help. Was finally able to figure out the solution. Caches!