Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45b1009

Browse files
committed
Convert assembly to inline assembly
- See the output in .lst file (with C functions) somehow this does not work very accurately when using .asm files (we cannot see prologue and epilogue sequences for functions written in assembly) - Can see register values with debugging - .asm file can be used to debug step by step (We can set breakpoints in the .asm file)
1 parent b0d68ee commit 45b1009

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

Systick_Scheduler/application/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
target_sources(${USER_PROJECT_TARGET} PRIVATE
22
osKernel.c
3-
osKernel.S
3+
4+
# NOTE, if the assembly file below is used, use INLINE_ASSEMBLY=0
5+
# osKernel.S
6+
)
7+
target_compile_definitions(${USER_PROJECT_TARGET} PRIVATE
8+
# INLINE_ASSEMBLY=0
9+
INLINE_ASSEMBLY=1
410
)
511
target_include_directories(${USER_PROJECT_TARGET} PRIVATE
612
.

Systick_Scheduler/application/osKernel.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,60 @@ static void osKernelStackInit(int thread_number) {
8888
// xPSR, PC, LR, r12, r3, r2, r1, r0
8989
// r11, r10, r9, r8, r7, r6, r5, r4
9090
TCB_STACK[thread_number][STACKSIZE - 1] = 0x01000000;
91+
92+
// Thread 0 - 100 onwards
93+
// Thread 1 - 200 onwards
94+
// Thread 2 - 300 onwards
95+
// We can see these values when debugging (register view)
96+
uint32_t tn = thread_number * 100 + 100;
97+
TCB_STACK[thread_number][STACKSIZE - 4] = tn + 4;
98+
TCB_STACK[thread_number][STACKSIZE - 5] = tn + 5;
99+
TCB_STACK[thread_number][STACKSIZE - 6] = tn + 6;
100+
TCB_STACK[thread_number][STACKSIZE - 7] = tn + 7;
101+
TCB_STACK[thread_number][STACKSIZE - 8] = tn + 8; // r0
102+
103+
TCB_STACK[thread_number][STACKSIZE - 9] = tn + 9; // r11
104+
TCB_STACK[thread_number][STACKSIZE - 10] = tn + 10;
105+
TCB_STACK[thread_number][STACKSIZE - 11] = tn + 11;
106+
TCB_STACK[thread_number][STACKSIZE - 12] = tn + 12;
107+
TCB_STACK[thread_number][STACKSIZE - 13] = tn + 13;
108+
TCB_STACK[thread_number][STACKSIZE - 14] = tn + 14;
109+
TCB_STACK[thread_number][STACKSIZE - 15] = tn + 15;
110+
TCB_STACK[thread_number][STACKSIZE - 16] = tn + 16; // r4
91111
}
112+
113+
#if INLINE_ASSEMBLY
114+
115+
// NOTE, Do not use the __attribute__((naked)) flag for both these functions
116+
// We want the function to pop their register values and exit (BX LR)
117+
118+
void SysTick_Handler() {
119+
__disable_irq();
120+
__ASM volatile("PUSH {R4-R11}\n"
121+
"LDR R0,=currentPt\n"
122+
"LDR R1,[R0]\n"
123+
"STR SP,[R1]\n"
124+
"LDR R1, [R1, #4]\n"
125+
"STR R1, [R0]\n"
126+
"LDR SP, [R1]\n"
127+
"POP {R4-R11}\n");
128+
__enable_irq();
129+
// NOTE, On exit this function POPs R0-R3 and R12 register
130+
}
131+
132+
void osSchedulerLaunch() {
133+
__ASM volatile("LDR R0,=currentPt\n"
134+
"LDR R2,[R0]\n"
135+
"LDR SP,[R2]\n"
136+
"POP {R4-R11}\n"
137+
"POP {R0-R3}\n"
138+
"POP {R12}\n"
139+
"ADD SP,SP,#4\n"
140+
"POP {LR}\n"
141+
"ADD SP,SP,#4\n");
142+
__enable_irq();
143+
// NOTE, here we manually pop the registers to initially load the values from
144+
// the thread stack
145+
}
146+
147+
#endif

0 commit comments

Comments
 (0)