Reply by pozz May 22, 20182018-05-22
Il 22/05/2018 14:24, Tauno Voipio ha scritto:
> On 22.5.18 10:05, pozz wrote: >> Il 21/05/2018 19:31, David Brown ha scritto: >>> On 21/05/18 17:15, Joe Chisolm wrote: >>>> On Fri, 18 May 2018 09:51:50 +0200, David Brown wrote: >>>> >>>>> On 18/05/18 09:07, pozz wrote: >>>>>> Il 17/05/2018 17:06, David Brown ha scritto: >>>>>>> On 17/05/18 14: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? >>>>>>> >>>>>>> There is, AFAIK, no way to force this.  It is not normally a problem >>>>>>> as ISRs should generally be as short and fast as possible. >>>>>> >>>>>> I always try to keep the ISR short, simple and fast.  However a >>>>>> simple >>>>>> switch statement (a different way to write a sequence of if >>>>>> statements) >>>>>> is compiled in assembler code that uses "libgcc functions". >>>>> >>>>> Can you give an small example here?  That sounds very strange.  gcc >>>>> can >>>>> use a variety of tactics for switch statements, including jump tables, >>>>> calculated jumps, sequences of conditional tests, and binary trees of >>>>> conditional tests - and combinations of these.  But I can't think >>>>> of any >>>>> situation where it would use a language support function (at least, >>>>> not >>>>> on an ARM). >>>>> >>>> [ snip ] >>>> >>>> >>>> This all started back in 2009.  For the stated minor savings in code >>>> space vs all the headaches it causes I think there should be a specific >>>> switch to override this.  Maybe there is. >>>> >>>> https://gcc.gnu.org/ml/gcc-patches/2009-06/msg01698.html >>>> >>>> >>> >>> So we are talking about Thumb1 code - a mode that has been outdated >>> for many years, and is almost certainly irrelevant to the OP's >>> question? (Thumb1 is very different from Thumb2, used by the Cortex-M >>> devices.) >> >> I don't know if my compiler generates Thumb1 or Thumb2 (or a mix of) >> code.  Anyway I remember the libgcc function that is called is >> __gnu_thumb1_case_uqi. > > Your compiler command is missing the mcpu=cortex-m4 (or -mcpu=cortx-m3) > switch on the command line.
I'm using Cortex-M0+ MCU, so I use the switch -mcpu=cortex-m0plus. I hope this is correct.
Reply by Tauno Voipio May 22, 20182018-05-22
On 22.5.18 10:05, pozz wrote:
> Il 21/05/2018 19:31, David Brown ha scritto: >> On 21/05/18 17:15, Joe Chisolm wrote: >>> On Fri, 18 May 2018 09:51:50 +0200, David Brown wrote: >>> >>>> On 18/05/18 09:07, pozz wrote: >>>>> Il 17/05/2018 17:06, David Brown ha scritto: >>>>>> On 17/05/18 14: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? >>>>>> >>>>>> There is, AFAIK, no way to force this.  It is not normally a problem >>>>>> as ISRs should generally be as short and fast as possible. >>>>> >>>>> I always try to keep the ISR short, simple and fast.  However a simple >>>>> switch statement (a different way to write a sequence of if >>>>> statements) >>>>> is compiled in assembler code that uses "libgcc functions". >>>> >>>> Can you give an small example here?  That sounds very strange.  gcc can >>>> use a variety of tactics for switch statements, including jump tables, >>>> calculated jumps, sequences of conditional tests, and binary trees of >>>> conditional tests - and combinations of these.  But I can't think of >>>> any >>>> situation where it would use a language support function (at least, not >>>> on an ARM). >>>> >>> [ snip ] >>> >>> >>> This all started back in 2009.  For the stated minor savings in code >>> space vs all the headaches it causes I think there should be a specific >>> switch to override this.  Maybe there is. >>> >>> https://gcc.gnu.org/ml/gcc-patches/2009-06/msg01698.html >>> >>> >> >> So we are talking about Thumb1 code - a mode that has been outdated >> for many years, and is almost certainly irrelevant to the OP's >> question? (Thumb1 is very different from Thumb2, used by the Cortex-M >> devices.) > > I don't know if my compiler generates Thumb1 or Thumb2 (or a mix of) > code.  Anyway I remember the libgcc function that is called is > __gnu_thumb1_case_uqi.
Your compiler command is missing the mcpu=cortex-m4 (or -mcpu=cortx-m3) switch on the command line. -- -TV
Reply by David Brown May 22, 20182018-05-22
On 22/05/18 09:05, pozz wrote:
> Il 21/05/2018 19:31, David Brown ha scritto: >> On 21/05/18 17:15, Joe Chisolm wrote: >>> On Fri, 18 May 2018 09:51:50 +0200, David Brown wrote: >>> >>>> On 18/05/18 09:07, pozz wrote: >>>>> Il 17/05/2018 17:06, David Brown ha scritto: >>>>>> On 17/05/18 14: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? >>>>>> >>>>>> There is, AFAIK, no way to force this. It is not normally a problem >>>>>> as ISRs should generally be as short and fast as possible. >>>>> >>>>> I always try to keep the ISR short, simple and fast. However a simple >>>>> switch statement (a different way to write a sequence of if >>>>> statements) >>>>> is compiled in assembler code that uses "libgcc functions". >>>> >>>> Can you give an small example here? That sounds very strange. gcc can >>>> use a variety of tactics for switch statements, including jump tables, >>>> calculated jumps, sequences of conditional tests, and binary trees of >>>> conditional tests - and combinations of these. But I can't think of >>>> any >>>> situation where it would use a language support function (at least, not >>>> on an ARM). >>>> >>> [ snip ] >>> >>> >>> This all started back in 2009. For the stated minor savings in code >>> space vs all the headaches it causes I think there should be a specific >>> switch to override this. Maybe there is. >>> >>> https://gcc.gnu.org/ml/gcc-patches/2009-06/msg01698.html >>> >>> >> >> So we are talking about Thumb1 code - a mode that has been outdated >> for many years, and is almost certainly irrelevant to the OP's >> question? (Thumb1 is very different from Thumb2, used by the Cortex-M >> devices.) > > I don't know if my compiler generates Thumb1 or Thumb2 (or a mix of) > code. Anyway I remember the libgcc function that is called is > __gnu_thumb1_case_uqi.
Since the Cortex families, there have been no ARM devices that support only Thumb-1 or mixtures of 32-bit ARM and Thumb-1. The Cortex-M are all Thumb-2. The Thumb-1 instructions were all 16-bit, while Thumb-2 supports those same 16-bit instructions plus a number of 32-bit instructions (eliminating the need for 32-bit ARM instruction set.) There is, as far as I can see, some inconsistencies as to whether the "Thumb-1" refers to the 16-bit instructions and "Thumb-2" refers to the 32-bit instructions, so that Cortex-M devices support Thumb-2 and Thumb-1, or whether "Thumb-1" refers to the instruction set consisting of only 16-bit instructions while "Thumb-2" refers to the instruction set consisting of a mix of 16-bit and 32-bit instructions (where the 16-bit instructions are, conveniently, the same as in "Thumb-1"). Adding to the confusion, the details of the instruction sets and the supported instructions varies by ARM architecture generation and details of the device. Your compiler supports them all - though gcc 9 will deprecate some of the older ARMs. What is important to know is the type of core you have on the microcontroller, and make sure the compiler flags match it.
Reply by pozz May 22, 20182018-05-22
Il 21/05/2018 19:31, David Brown ha scritto:
> On 21/05/18 17:15, Joe Chisolm wrote: >> On Fri, 18 May 2018 09:51:50 +0200, David Brown wrote: >> >>> On 18/05/18 09:07, pozz wrote: >>>> Il 17/05/2018 17:06, David Brown ha scritto: >>>>> On 17/05/18 14: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? >>>>> >>>>> There is, AFAIK, no way to force this.  It is not normally a problem >>>>> as ISRs should generally be as short and fast as possible. >>>> >>>> I always try to keep the ISR short, simple and fast.  However a simple >>>> switch statement (a different way to write a sequence of if statements) >>>> is compiled in assembler code that uses "libgcc functions". >>> >>> Can you give an small example here?  That sounds very strange.  gcc can >>> use a variety of tactics for switch statements, including jump tables, >>> calculated jumps, sequences of conditional tests, and binary trees of >>> conditional tests - and combinations of these.  But I can't think of any >>> situation where it would use a language support function (at least, not >>> on an ARM). >>> >> [ snip ] >> >> >> This all started back in 2009.  For the stated minor savings in code >> space vs all the headaches it causes I think there should be a specific >> switch to override this.  Maybe there is. >> >> https://gcc.gnu.org/ml/gcc-patches/2009-06/msg01698.html >> >> > > So we are talking about Thumb1 code - a mode that has been outdated for > many years, and is almost certainly irrelevant to the OP's question? > (Thumb1 is very different from Thumb2, used by the Cortex-M devices.)
I don't know if my compiler generates Thumb1 or Thumb2 (or a mix of) code. Anyway I remember the libgcc function that is called is __gnu_thumb1_case_uqi.
Reply by David Brown May 21, 20182018-05-21
On 21/05/18 17:15, Joe Chisolm wrote:
> On Fri, 18 May 2018 09:51:50 +0200, David Brown wrote: > >> On 18/05/18 09:07, pozz wrote: >>> Il 17/05/2018 17:06, David Brown ha scritto: >>>> On 17/05/18 14: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? >>>> >>>> There is, AFAIK, no way to force this. It is not normally a problem >>>> as ISRs should generally be as short and fast as possible. >>> >>> I always try to keep the ISR short, simple and fast. However a simple >>> switch statement (a different way to write a sequence of if statements) >>> is compiled in assembler code that uses "libgcc functions". >> >> Can you give an small example here? That sounds very strange. gcc can >> use a variety of tactics for switch statements, including jump tables, >> calculated jumps, sequences of conditional tests, and binary trees of >> conditional tests - and combinations of these. But I can't think of any >> situation where it would use a language support function (at least, not >> on an ARM). >> > [ snip ] > > > This all started back in 2009. For the stated minor savings in code > space vs all the headaches it causes I think there should be a specific > switch to override this. Maybe there is. > > https://gcc.gnu.org/ml/gcc-patches/2009-06/msg01698.html > >
So we are talking about Thumb1 code - a mode that has been outdated for many years, and is almost certainly irrelevant to the OP's question? (Thumb1 is very different from Thumb2, used by the Cortex-M devices.) And perhaps it only applies to PIC - position independent code, another rare feature in this kind of microcontroller? It is common to use "-Os" optimisation flag, so if that enables this type of switch implementation then it will turn up more. (Personally, I use -O2 rather than -Os on ARM - it rarely makes code much bigger, but often a good deal faster.) Still, while I have not seen it myself in switch code, it is always possible for language support library calls to turn up in odd places when compiling code. On many targets, especially when optimising for space, they can turn up in things like function prologues or epilogues.
Reply by Joe Chisolm May 21, 20182018-05-21
On Fri, 18 May 2018 09:51:50 +0200, David Brown wrote:

> On 18/05/18 09:07, pozz wrote: >> Il 17/05/2018 17:06, David Brown ha scritto: >>> On 17/05/18 14: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? >>> >>> There is, AFAIK, no way to force this. It is not normally a problem >>> as ISRs should generally be as short and fast as possible. >> >> I always try to keep the ISR short, simple and fast. However a simple >> switch statement (a different way to write a sequence of if statements) >> is compiled in assembler code that uses "libgcc functions". > > Can you give an small example here? That sounds very strange. gcc can > use a variety of tactics for switch statements, including jump tables, > calculated jumps, sequences of conditional tests, and binary trees of > conditional tests - and combinations of these. But I can't think of any > situation where it would use a language support function (at least, not > on an ARM). >
[ snip ] This all started back in 2009. For the stated minor savings in code space vs all the headaches it causes I think there should be a specific switch to override this. Maybe there is. https://gcc.gnu.org/ml/gcc-patches/2009-06/msg01698.html -- Chisolm Republic of Texas
Reply by David Brown May 21, 20182018-05-21
On 21/05/18 09:14, pozz wrote:
> Il 18/05/2018 09:51, David Brown ha scritto: >> On 18/05/18 09:07, pozz wrote: >>> Il 17/05/2018 17:06, David Brown ha scritto: >>>> On 17/05/18 14: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? >>>> >>>> There is, AFAIK, no way to force this.� It is not normally a problem >>>> as ISRs should generally be as short and fast as possible. >>> >>> I always try to keep the ISR short, simple and fast.� However a simple >>> switch statement (a different way to write a sequence of if statements) >>> is compiled in assembler code that uses "libgcc functions". >> >> Can you give an small example here?� That sounds very strange.� gcc can >> use a variety of tactics for switch statements, including jump tables, >> calculated jumps, sequences of conditional tests, and binary trees of >> conditional tests - and combinations of these.� But I can't think of any >> situation where it would use a language support function (at least, not >> on an ARM). > > Read this: > https://www.freertos.org/FreeRTOS_Support_Forum_Archive/April_2016/freertos_Use_of_switch_case_in_FreeRTOS_code_a821b79ej.html >
That refreshes my memory! But I didn't get an example then, and haven't got one now. What sort of switch situations are you seeing calls to language support functions?
Reply by pozz May 21, 20182018-05-21
Il 18/05/2018 09:51, David Brown ha scritto:
> On 18/05/18 09:07, pozz wrote: >> Il 17/05/2018 17:06, David Brown ha scritto: >>> On 17/05/18 14: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? >>> >>> There is, AFAIK, no way to force this. It is not normally a problem >>> as ISRs should generally be as short and fast as possible. >> >> I always try to keep the ISR short, simple and fast. However a simple >> switch statement (a different way to write a sequence of if statements) >> is compiled in assembler code that uses "libgcc functions". > > Can you give an small example here? That sounds very strange. gcc can > use a variety of tactics for switch statements, including jump tables, > calculated jumps, sequences of conditional tests, and binary trees of > conditional tests - and combinations of these. But I can't think of any > situation where it would use a language support function (at least, not > on an ARM).
Read this: https://www.freertos.org/FreeRTOS_Support_Forum_Archive/April_2016/freertos_Use_of_switch_case_in_FreeRTOS_code_a821b79ej.html
Reply by Tauno Voipio May 18, 20182018-05-18
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
Reply by David Brown May 18, 20182018-05-18
On 18/05/18 09:07, pozz wrote:
> Il 17/05/2018 17:06, David Brown ha scritto: >> On 17/05/18 14: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? >> >> There is, AFAIK, no way to force this. It is not normally a problem >> as ISRs should generally be as short and fast as possible. > > I always try to keep the ISR short, simple and fast. However a simple > switch statement (a different way to write a sequence of if statements) > is compiled in assembler code that uses "libgcc functions".
Can you give an small example here? That sounds very strange. gcc can use a variety of tactics for switch statements, including jump tables, calculated jumps, sequences of conditional tests, and binary trees of conditional tests - and combinations of these. But I can't think of any situation where it would use a language support function (at least, not on an ARM). (I've snipping most of the rest of the post, because it all sounds sensible enough. Just remember that if you set callback functions, these also need to be short, in ram, etc., according to need.)
> >> And when you do, mark those functions as being in the RAM section, or >> as __attribute__((always_inline)). This doesn't work for language >> support functions - you avoid these by avoiding using such language >> features (such as division or software floating point). > > Or switch statements... > > >>> [*] 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. >> >> Note that you can't use ISRs during flash operations unless the vector >> table is also moved to ram. > > I know. > >> While you are erasing or writing flash, it is usually easiest to >> simply disable interrupts. If you really need an interrupt or two >> running, disable all but the critical ones and make sure these are >> short and fast. > > I'm trying to use MCU Flash to save some non-volatile configuration > parameters. The user can change the configuration when he wants. At this > moment, the Flash must be erase/written, however the device should work > as usual.
You may be asking the impossible here. Flash writes are usually quick, and can often be squeezed in by disabling most interrupts. (DMA on things like UARTs can help give you more leeway here.) But erases take time. Many devices allow erase suspend, which is one possibility for dealing with things that /have/ to use flash while you are trying to do an erase. It can be messy and fiddly, and regular erase suspend can reduce the erase/write lifetime of the flash. And of course many devices have separate flash planes, letting you read from one plane while the other is being erased or written. But if you have a single plane flash device, and need to erase (rather than just writing in a log structure), and need to run normally while erasing - there might not be a good solution at all. A small serial e�prom is a very cheap way to make a much better solution.