On 17.5.18 15:37, pozz wrote:
> I'm trying to put all ISRs in RAM[*]. Unfortunately, depending on the
> code, arm-gcc could call some system functions that are located in Flash.
>
> For example, if I use a switch statement, the compiler calls a piece of
> code of system libraries (that are in Flash) that use a table lookup to
> manage the switch.
>
> Is it possible to force arm-gcc to avoid calling system functions from
> ISRs, so it can be executed completely in RAM?
>
>
> [*] This is why I need to erase/write Flash memory and during these
> operations the Flash can't be read and code in Flash can't be executed.
Which ARM processor and which GCC version, which compilation switches?
I beg to differ. The following snippet of an interrupt handler is
compiled (GCC 4.8.2) for a Cortex-M4 with the compilation switches
-Os -mthumb -mcpu=cortex-m4:
C snippet:
switch (rstate)
{
case RXHUNT:
break;
case RXB0:
rcvb0(ch);
break;
case RXB0Q:
rcvb0q(ch);
break;
case RXB1:
rcvb1(ch);
break;
case RXB1Q:
rcvb1q(ch);
break;
case RXDATA:
rcvdata(ch);
break;
case RXQUOT:
rcvqdata(ch);
break;
default:
rstate = RIDLE;
break;
Assembler listing (create with: -Wa,-adhlmns=$(@:.o=.lst)):
129 .L19:
130 0036 2378 ldrb r3, [r4] @ zero_extendqisi2
131 0038 013B subs r3, r3, #1
132 003a 062B cmp r3, #6
133 003c 54D8 bhi .L20
134 003e DFE803F0 tbb [pc, r3]
135 .L21:
136 0042 55 .byte (.L17-.L21)/2
137 0043 04 .byte (.L22-.L21)/2
138 0044 0A .byte (.L23-.L21)/2
139 0045 13 .byte (.L24-.L21)/2
140 0046 19 .byte (.L25-.L21)/2
141 0047 24 .byte (.L26-.L21)/2
142 0048 44 .byte (.L27-.L21)/2
143 0049 00 .align 1
144 .L22:
145 004a 032D cmp r5, #3
146 004c 16D0 beq .L37
147 004e 7D2D cmp r5, #125
148 0050 07D1 bne .L96
149 0052 0323 movs r3, #3
150 0054 49E0 b .L91
151 .L23:
152 0056 032D cmp r5, #3
153 0058 10D0 beq .L37
154 005a 7D2D cmp r5, #125
155 005c 0ED0 beq .L37
156 005e 85F01005 eor r5, r5, #16
157 .L96:
158 0062 2574 strb r5, [r4, #16]
159 0064 0423 movs r3, #4
160 0066 40E0 b .L91
161 .L24:
162 0068 032D cmp r5, #3
163 006a 07D0 beq .L37
164 006c 7D2D cmp r5, #125
165 006e 09D1 bne .L95
166 0070 0523 movs r3, #5
167 0072 3AE0 b .L91
168 .L25:
169 0074 032D cmp r5, #3
170 0076 01D0 beq .L37
171 0078 7D2D cmp r5, #125
172 007a 01D1 bne .L88
173 .L37:
174 007c 0123 movs r3, #1
175 007e 34E0 b .L91
176 .L88:
177 0080 85F01005 eor r5, r5, #16
178 .L95:
179 0084 6574 strb r5, [r4, #17]
180 0086 0623 movs r3, #6
181 0088 2FE0 b .L91
182 .L26:
183 008a 032D cmp r5, #3
184 008c 03D0 beq .L39
185 008e 7D2D cmp r5, #125
186 0090 16D1 bne .L97
187 0092 0723 movs r3, #7
188 0094 29E0 b .L91
189 .L39:
190 0096 6268 ldr r2, [r4, #4]
191 0098 3C4B ldr r3, .L98+4
192 009a 032A cmp r2, #3
193 009c 19D9 bls .L43
194 009e 5969 ldr r1, [r3, #20]
195 00a0 187C ldrb r0, [r3, #16] @ zero_extendqisi2
196 00a2 0022 movs r2, #0
197 00a4 0A60 str r2, [r1]
198 00a6 597C ldrb r1, [r3, #17] @ zero_extendqisi2
199 00a8 1A70 strb r2, [r3]
200 00aa 41EA0021 orr r1, r1, r0, lsl #8
201 00ae 1983 strh r1, [r3, #24] @ movhi
202 00b0 374B ldr r3, .L98+8
203 00b2 0921 movs r1, #9
204 00b4 5A62 str r2, [r3, #36]
205 00b6 0122 movs r2, #1
206 00b8 1A61 str r2, [r3, #16]
207 00ba 1960 str r1, [r3]
208 00bc DA60 str r2, [r3, #12]
209 00be 15E0 b .L17
210 .L97:
211 00c0 6368 ldr r3, [r4, #4]
212 00c2 832B cmp r3, #131
213 00c4 05D8 bhi .L43
214 00c6 2846 mov r0, r5
215 00c8 0BE0 b .L92
216 .L27:
217 00ca 032D cmp r5, #3
218 00cc 01D0 beq .L43
219 00ce 7D2D cmp r5, #125
220 00d0 02D1 bne .L90
221 .L43:
222 00d2 FFF7FEFF bl initrcv
223 00d6 09E0 b .L17
224 .L90:
225 00d8 6368 ldr r3, [r4, #4]
226 00da 832B cmp r3, #131
227 00dc F9D8 bhi .L43
228 00de 85F01000 eor r0, r5, #16
229 .L92:
230 00e2 FFF7FEFF bl putrcv
231 00e6 01E0 b .L17
232 .L20:
233 00e8 0023 movs r3, #0
234 .L91:
235 00ea 2370 strb r3, [r4]
236 .L17:
There is not a single system or compiler support library call.
Even the local functions have been inlined.
---
To make a piece of code to reside in RAM, just declare it into
a section which is linked together with the .data section:
#define RAMCODE __attribute__((section(".ramcode")))
#define LONGCALL __attribute__((long_call))
#define NOINLINE __attribute__((noinline))
#define RAMFUNC NOINLINE LONGCALL RAMCODE
static RAMFUNC void my_ram_function(void)
{
/* My RAM code here */
;
}
Snippet of associated linker script:
/* Initialized data with ROM copy */
.data :
{
_rwstart = . ;
*(.ramcode)
*(.data*)
. = ALIGN(4);
_rwend = . ;
} > ram AT > flash
The .data initialization code at start will set up the code
into proper place in RAM.
--
-TV