Я не стану утверждать, что я умнее команды людей писавших/пишущих
компиляторы, но скажу, что ассемблер нужно знать(быть знакомым), Ну
и "ишака привязывать" Разбирал на днях проект.
TIM8_init
PUSH {R4,LR}
SUB SP, SP, #0x68
MOVS R1, #0x14
MOVS R2, #0
ADD R4, SP, #0x54 ; 'T'
MOVS R0, R4
BL memset
MOVS R1, #0x20 ; ' '
MOVS R2, #0
ADD R4, SP, #0x34 ; '4'
MOVS R0, R4
BL memset
MOVS R1, #0x18
MOVS R2, #0
ADD R4, SP, #0x1C
MOVS R0, R4
BL memset
MOVS R1, #0x18
MOVS R2, #0
ADD R4, SP, #4
MOVS R0, R4
BL memset
MOVS R0, #2 ; RCC_APB2Periph_TIM8
BL ADC_DeInit
LDR.W R4, =DMA2_LISR ; =0x40026400
MOVS.W R2, #0xE000000 ; #define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
MOVS R1, #2
MOVS R0, R4
BL LL_DMA_SetChannelSelection
Сверху код написанный на примере HAL/LL от ST.
Явно видно, что для читаемости в начале функции объявлены несколько структур. Эти структуры вызываются один раз за всю функцию.
Я бы разместил объявление структуры перед вызовом функции HAL ее использующей. Вдруг компилятор вычислит размер стека по самой большой структуре и сократит размер выделяемого стека?
Есть еще к вопрос к вызову функции LL_DMA_SetChannelSelection.
Она объявлена как инлайн,
__STATIC_INLINE void LL_DMA_SetChannelSelection(DMA_TypeDef *DMAx, uint32_t Stream, uint32_t Channel)
{
MODIFY_REG(((DMA_Stream_TypeDef*)((uint32_t)((uint32_t)DMAx + STREAM_OFFSET_TAB[Stream])))->CR, DMA_SxCR_CHSEL, Channel);
}
Но фактически компилятор все инлайны выкинул и вставил вызов функций.
В скорости будет потеря и стек нужно больше.