2021-04-28 06:02 AM
I try optimize to maximum MCU offload this operation:
I2S DMA stores sample LRLRLRLR... circular
i need reorder it to LLLLLLRRRRR in other memory place.
I mean DMA or other hw methods cant copy mem to mem with skip defined, mean every other.
Then i try write ISR and asm result is
08000c00 <SPI2_IRQHandler>:
* @brief This function handles SPI2 global interrupt.
*/
void SPI2_IRQHandler(void)
{
/* USER CODE BEGIN SPI2_IRQn 0 */
*(int *)a = *(int *)b++;
8000c00: f859 3b01 ldr.w r3, [r9], #1
8000c04: f8c8 3000 str.w r3, [r8]
*(int *)(a+256) = *(int *)b++;
8000c08: f859 3b01 ldr.w r3, [r9], #1
8000c0c: f8c8 3100 str.w r3, [r8, #256] ; 0x100
a++;
8000c10: f108 0801 add.w r8, r8, #1
/* USER CODE END SPI2_IRQn 0 */
// HAL_I2S_IRQHandler(&hi2s2);
/* USER CODE BEGIN SPI2_IRQn 1 */
/* USER CODE END SPI2_IRQn 1 */
}
8000c14: 4770 bx lr
8000c16: bf00 nop
Registers r8 and r9 i declare in main.h as
register unsigned int a asm("r8");
register unsigned int b asm("r9");
Seems ISR is compiled good, but in all asm i found, that r8 and r9 is used on other places in many functions. Howto prevent this ???
2021-04-30 08:18 AM
08000c00 <SPI2_IRQHandler>:
* @brief This function handles SPI2 global interrupt.
*/
void SPI2_IRQHandler(void)
{
/* USER CODE BEGIN SPI2_IRQn 0 */
*(int *)a = *(int *)b++;
8000c00: 4b08 ldr r3, [pc, #32] ; (8000c24 <SPI2_IRQHandler+0x24>)
8000c02: 4a09 ldr r2, [pc, #36] ; (8000c28 <SPI2_IRQHandler+0x28>)
8000c04: 6819 ldr r1, [r3, #0]
8000c06: 1c48 adds r0, r1, #1
8000c08: 6018 str r0, [r3, #0]
8000c0a: 6810 ldr r0, [r2, #0]
8000c0c: 6809 ldr r1, [r1, #0]
8000c0e: 6001 str r1, [r0, #0]
*(int *)(a++ +256) = *(int *)b++;
8000c10: 6819 ldr r1, [r3, #0]
8000c12: 1c48 adds r0, r1, #1
8000c14: 6018 str r0, [r3, #0]
8000c16: 6813 ldr r3, [r2, #0]
8000c18: 1c58 adds r0, r3, #1
8000c1a: 6010 str r0, [r2, #0]
8000c1c: 680a ldr r2, [r1, #0]
8000c1e: f8c3 2100 str.w r2, [r3, #256] ; 0x100
/* USER CODE END SPI2_IRQn 0 */
// HAL_I2S_IRQHandler(&hi2s2);
/* USER CODE BEGIN SPI2_IRQn 1 */
/* USER CODE END SPI2_IRQn 1 */
}
8000c22: 4770 bx lr
8000c24: 20000288 .word 0x20000288
8000c28: 20000284 .word 0x20000284
Nobody helps ? This is for compare normal variable build. As you can see register code use 5 instruction and normal code 16 when variables is __IO.
Without __IO build add 2 next instruction complete 18.
2021-04-30 08:33 AM
You know some of us have other jobs, and can't be chasing bizarre corner cases people paint themselves into. You might need to dig into the specifics of GNU GCC/GAS as it relates to the features you're trying to use, and the system level expectations they are based on.
R9 is often used in relocatable or address-independent code, when the LOADER is responsible for setting R9 to the beginning of the DATA section for a specific instance of the code, think DLLs, think thread-safe. It is going to be less prevalent on ROM based code, and will be based on settings you've used related to the compiler/linker.
Why have these variables as IO/volatile ? If they only change in this interrupt, presumably that's not going to enter multiple times.
2021-04-30 01:09 PM
Bizzarre maybe ... Speed difference x3 is realy bizzare. I read all i found about register variables, but STCubeIDE gcc result with code , that use register too on other places for example
0800026c <__udivmoddi4>:
800026c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
8000270: 9d08 ldr r5, [sp, #32]
8000272: 4604 mov r4, r0
...
Next bizzare , that i dont understand for example register sl here is r10 in arm debuger.
Variable is changed on other place , because need reset , and check it on every step isnt effective.