Skip to content

Commit 36cbae6

Browse files
committed
Add a function to transfer control to another app
Add the function mbed_start_application() which allows a bootloader to transfer control to an application.
1 parent 7fc73e4 commit 36cbae6

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

mbed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
#include "platform/toolchain.h"
5151
#include "platform/platform.h"
52+
#include "platform/mbed_application.h"
5253

5354
// Useful C libraries
5455
#include <math.h>

platform/mbed_application.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017-2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <stdlib.h>
18+
#include <stdarg.h>
19+
#include "device.h"
20+
#include "platform/mbed_application.h"
21+
22+
#if MBED_APPLICATION_SUPPORT
23+
24+
static void powerdown_nvic(void);
25+
static void powerdown_scb(uint32_t vtor);
26+
static void start_new_application(void *sp, void *pc);
27+
28+
void mbed_start_application(uintptr_t address)
29+
{
30+
void *sp;
31+
void *pc;
32+
33+
// Interrupts are re-enabled in start_new_application
34+
__disable_irq();
35+
36+
SysTick->CTRL = 0x00000000;
37+
powerdown_nvic();
38+
powerdown_scb(address);
39+
40+
sp = *((void**)address + 0);
41+
pc = *((void**)address + 1);
42+
start_new_application(sp, pc);
43+
}
44+
45+
static void powerdown_nvic()
46+
{
47+
int isr_count;
48+
int i;
49+
int j;
50+
51+
isr_count = (SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos;
52+
for (i = 0; i < isr_count; i++) {
53+
NVIC->ICER[i] = 0xFFFFFFFF;
54+
NVIC->ICPR[i] = 0xFFFFFFFF;
55+
for (j = 0; j < 8; j++) {
56+
NVIC->IP[i * 8 + j] = 0x00000000;
57+
}
58+
}
59+
}
60+
61+
static void powerdown_scb(uint32_t vtor)
62+
{
63+
int i;
64+
65+
// SCB->CPUID - Read only CPU ID register
66+
SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
67+
SCB->VTOR = vtor;
68+
SCB->AIRCR = 0x05FA | 0x0000;
69+
SCB->SCR = 0x00000000;
70+
// SCB->CCR - Implementation defined value
71+
for (i = 0; i < 12; i++) {
72+
#if defined(__CORTEX_M7)
73+
SCB->SHPR[i] = 0x00;
74+
#else
75+
SCB->SHP[i] = 0x00;
76+
#endif
77+
}
78+
SCB->SHCSR = 0x00000000;
79+
SCB->CFSR = 0xFFFFFFFF;
80+
SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk;
81+
SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk |
82+
SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk;
83+
// SCB->MMFAR - Implementation defined value
84+
// SCB->BFAR - Implementation defined value
85+
// SCB->AFSR - Implementation defined value
86+
// SCB->PFR - Read only processor feature register
87+
// SCB->DFR - Read only debug feature registers
88+
// SCB->ADR - Read only auxiliary feature registers
89+
// SCB->MMFR - Read only memory model feature registers
90+
// SCB->ISAR - Read only instruction set attribute registers
91+
// SCB->CPACR - Implementation defined value
92+
}
93+
94+
#if defined (__CC_ARM)
95+
96+
__asm static void start_new_application(void *sp, void *pc)
97+
{
98+
MOV R2, #0
99+
MSR CONTROL, R2 // Switch to main stack
100+
MOV SP, R0
101+
MSR PRIMASK, R2 // Enable interrupts
102+
BX R1
103+
}
104+
105+
#elif defined (__GNUC__) || defined (__ICCARM__)
106+
107+
void start_new_application(void *sp, void *pc)
108+
{
109+
__asm volatile (
110+
"mov r2, #0 \n"
111+
"msr control, r2 \n" // Switch to main stack
112+
"mov sp, %0 \n"
113+
"msr primask, r2 \n" // Enable interrupts
114+
"bx %1 \n"
115+
:
116+
: "l" (sp), "l" (pc)
117+
: "r2", "cc", "memory"
118+
);
119+
}
120+
121+
#else
122+
123+
#error "Unsupported toolchain"
124+
125+
#endif
126+
127+
#endif /* MBED_APPLICATION_SUPPORT */

platform/mbed_application.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
/** \addtogroup platform */
3+
/** @{*/
4+
/* mbed Microcontroller Library
5+
* Copyright (c) 2017-2017 ARM Limited
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
#ifndef MBED_APPLICATION_H
20+
#define MBED_APPLICATION_H
21+
22+
#include<stdint.h>
23+
24+
#define MBED_APPLICATION_SUPPORT (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7))
25+
#if MBED_APPLICATION_SUPPORT
26+
#ifdef __cplusplus
27+
extern "C" {
28+
#endif
29+
30+
/**
31+
* Start the application at the given address. This function does
32+
* not return. It is the applications responsibility for flushing to
33+
* or powering down external components such as filesystems or
34+
* socket connections before calling this function. For Cortex-M
35+
* devices this function powers down generic system components such as
36+
* the NVIC and set the vector table to that of the new image followed
37+
* by jumping to the reset handler of the new image.
38+
*
39+
* @param address Starting address of next application to run
40+
*/
41+
void mbed_start_application(uintptr_t address);
42+
43+
#ifdef __cplusplus
44+
}
45+
#endif
46+
#endif
47+
48+
#endif
49+
50+
/** @}*/

0 commit comments

Comments
 (0)