amaora 25 13 ноября, 2021 Опубликовано 13 ноября, 2021 (изменено) · Жалоба Для теста собрал один свой проект с разными ключами компиляции, и обнаружил вот это, Quote In function ‘memcpy’, inlined from ‘prvCopyDataFromQueue’ at freertos/queue.c:2162:12, inlined from ‘xQueueReceiveFromISR’ at freertos/queue.c:1817:4, inlined from ‘irq_USART3’ at hal/usart.c:74:7: libc.c:77:31: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 77 | *xd++ = *xs++; | ^ hal/usart.c: In function ‘irq_USART3’: hal/usart.c:43:9: note: at offset 8 into destination object ‘u’ of size 1 43 | u; | ^ hal/usart.c:43:9: note: at offset [4, 2147483644] into destination object ‘u’ of size 1 hal/usart.c:43:9: note: at offset [4, 2147483644] into destination object ‘u’ of size 1 ... а происходит оно при компиляции вот такого кода (сократил до минимального) с ключами "-O3 -flto -g3 -pipe" компилятором armv7m-none-eabi-gcc (11.2.0 (Gentoo 11.2.0 p1)), void irq_USART3() { union { //u32_t q[2]; char xC; } u; if (xQueueReceiveFromISR(hal_USART.queue_TX, &u.xC, NULL) == pdTRUE) { USART3->DR = u.xC; } } На других уровнях оптимизации предупреждений нет, так же проверял clang (12.0.1) ни с каким уровнем оптимизации предупреждений нет. Исходно там была одиночная переменная типа char, но в процессе поиска причины сделал union. Если размер этого union будет 8 байт (элемент q[2]) то компиляция проходит без предупреждений. Хотел так же посмотреть итоговый код после компиляции, но на -O3 он подставляет все внутренности freertos и разобрать там что либо сложно. Воспроизвести проблему с помощью лишь вызова memcpy (без freertos) пока не удаётся. В чем причина не понял, видимо связана с выравниванием стека на 8 байт. Spoiler Исходник memcpy. void *memcpy(void *d, const void *s, int n) { u32_t *ld = (u32_t *) d; const u32_t *ls = (const u32_t *) s; if (((u32_t) ld & 3UL) == 0 && ((u32_t) ls & 3UL) == 0) { while (n >= 4) { *ld++ = *ls++; n += - 4; } } { u8_t *xd = (u8_t *) ld; const u8_t *xs = (const u8_t *) ls; while (n >= 1) { *xd++ = *xs++; n += - 1; } } return d; } Изменено 13 ноября, 2021 пользователем amaora Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба 28 минут назад, amaora сказал: видимо связана с выравниванием стека на 8 байт. Скорее всего, хотя странно. Попробуйте static добавить переменной, чтоб она не на стеке выделялась. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба 1 час назад, amaora сказал: В чем причина не понял, видимо связана с выравниванием стека на 8 байт. С чего сделан такой странный вывод? Вангую: Где-то внутри цепочки вызовов производится вычисление какого-то адреса со смещениями =4 и =8 относительно переданного внутрь адреса &u. Пока эти функции компилируются отдельно от irq_USART3() компилятор не имеет информации о размере переменных, указатели на которые передаются внутрь. И у него не возникает возражений. При включении высокого уровня оптимизации и инлайнинга всей цепочки вызовов внутрь irq_USART3() (а тем более если у вас там ещё включается и режим компиляции "единым файлом" (в IAR - "multi-file compilation")), компилятор видит размер u. И это вызывает у него несварение. 1 час назад, amaora сказал: Хотел так же посмотреть итоговый код после компиляции, но на -O3 он подставляет все внутренности freertos и разобрать там что либо сложно. В таких случаях, в интересующем месте исходника, я вставляю код, который не может быть перемещён оптимизатором или удалён, и который легко найти в листинге (генерящий команды, которых больше нигде нет). Например в IAR это интрсинки: __ISB() или __SEV() или аналогичные. Они просто вставляют соответствующие команды ISB или SEV, которые потом легко найти в листинге. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба 1 час назад, amaora сказал: а происходит оно при компиляции вот такого кода (сократил до минимального) А покажите прототип xQueueReceiveFromISR и prvCopyDataFromQueue. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба 1 hour ago, adnega said: Попробуйте static добавить переменной, чтоб она не на стеке выделялась. Не помогает. 36 minutes ago, jcxz said: Где-то внутри цепочки вызовов производится вычисление какого-то адреса со смещениями =4 и =8 относительно переданного внутрь адреса &u. Цепочка не большая, по коду видно, что манипуляций с адресами нет, передаётся как есть в memcpy. Но эффект похожий, если прибавить руками к адресу передаваемому в memcpy то будут такие же предупреждения. Знать бы ещё в каком месте берётся адрес, поставил бы туда маркер. 7 minutes ago, Сергей Борщ said: А покажите прототип xQueueReceiveFromISR и prvCopyDataFromQueue. BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба 12 минут назад, amaora сказал: Цепочка не большая, по коду видно, что манипуляций с адресами нет, передаётся как есть в memcpy. Но эффект похожий, если прибавить руками к адресу передаваемому в memcpy то будут такие же предупреждения. Знать бы ещё в каком месте берётся адрес, поставил бы туда маркер. Так если "небольшая", то впендюрьте сюда весь листинг. Под спойлер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 13 ноября, 2021 Опубликовано 13 ноября, 2021 (изменено) · Жалоба 1 hour ago, jcxz said: Так если "небольшая", то впендюрьте сюда весь листинг. Под спойлер. Spoiler BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); /* RTOS ports that support interrupt nesting have the concept of a maximum system call (or maximum API call) interrupt priority. Interrupts that are above the maximum system call priority are kept permanently enabled, even when the RTOS kernel is in a critical section, but cannot make any calls to FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion failure if a FreeRTOS API function is called from an interrupt that has been assigned a priority above the configured maximum system call priority. Only FreeRTOS functions that end in FromISR can be called from interrupts that have been assigned a priority at or (logically) below the maximum system call interrupt priority. FreeRTOS maintains a separate interrupt safe API to ensure interrupt entry is as fast and as simple as possible. More information (albeit Cortex-M specific) is provided on the following link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; /* Cannot block in an ISR, so check there is data available. */ if( uxMessagesWaiting > ( UBaseType_t ) 0 ) { const int8_t cRxLock = pxQueue->cRxLock; traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); prvCopyDataFromQueue( pxQueue, pvBuffer ); pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; /* If the queue is locked the event list will not be modified. Instead update the lock count so the task that unlocks the queue will know that an ISR has removed data while the queue was locked. */ if( cRxLock == queueUNLOCKED ) { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { /* The task waiting has a higher priority than us so force a context switch. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } } else { /* Increment the lock count so the task that unlocks the queue knows that data was removed while it was locked. */ pxQueue->cRxLock = ( int8_t ) ( cRxLock + 1 ); } xReturn = pdPASS; } else { xReturn = pdFAIL; traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); } } portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) { if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) { pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ { pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; } else { mtCOVERAGE_TEST_MARKER(); } __DSB(); __DSB(); __DSB(); ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ __ISB(); __ISB(); __ISB(); } } ... void irq_USART3() { BaseType_t xWoken = pdFALSE; u32_t SR; char xC; #if defined(STM32F4) SR = USART3->SR; #elif defined(STM32F7) SR = USART3->ISR; #endif /* STM32Fx */ #if defined(STM32F4) if (SR & USART_SR_RXNE) { #elif defined(STM32F7) if (SR & USART_ISR_RXNE) { #endif /* STM32Fx */ #if defined(STM32F4) xC = USART3->DR; #elif defined(STM32F7) xC = USART3->RDR; #endif /* STM32Fx */ xQueueSendToBackFromISR(hal_USART.queue_RX, &xC, &xWoken); IODEF_TO_USART(); } #if defined(STM32F4) if (SR & USART_SR_TXE) { #elif defined(STM32F7) if (SR & USART_ISR_TXE) { #endif /* STM32Fx */ if (xQueueReceiveFromISR(hal_USART.queue_TX, &xC, &xWoken) == pdTRUE) { #if defined(STM32F4) USART3->DR = xC; #elif defined(STM32F7) USART3->TDR = xC; #endif /* STM32Fx */ } else { USART3->CR1 &= ~USART_CR1_TXEIE; } } portYIELD_FROM_ISR(xWoken); } ... 08001d40 <irq_USART3>: 8001d40: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} 8001d44: 4b98 ldr r3, [pc, #608] ; (8001fa8 <irq_USART3+0x268>) 8001d46: 681c ldr r4, [r3, #0] 8001d48: f014 0220 ands.w r2, r4, #32 8001d4c: b084 sub sp, #16 8001d4e: d12a bne.n 8001da6 <irq_USART3+0x66> 8001d50: 0621 lsls r1, r4, #24 8001d52: d402 bmi.n 8001d5a <irq_USART3+0x1a> 8001d54: b004 add sp, #16 8001d56: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} 8001d5a: 4e94 ldr r6, [pc, #592] ; (8001fac <irq_USART3+0x26c>) 8001d5c: f8d6 33a8 ldr.w r3, [r6, #936] ; 0x3a8 8001d60: f3ef 8611 mrs r6, BASEPRI 8001d64: f04f 0150 mov.w r1, #80 ; 0x50 8001d68: f381 8811 msr BASEPRI, r1 8001d6c: f3bf 8f4f dsb sy 8001d70: f3bf 8f6f isb sy 8001d74: 6b99 ldr r1, [r3, #56] ; 0x38 8001d76: 2900 cmp r1, #0 8001d78: d136 bne.n 8001de8 <irq_USART3+0xa8> 8001d7a: f386 8811 msr BASEPRI, r6 8001d7e: 498a ldr r1, [pc, #552] ; (8001fa8 <irq_USART3+0x268>) 8001d80: 68cb ldr r3, [r1, #12] 8001d82: f023 0380 bic.w r3, r3, #128 ; 0x80 8001d86: 60cb str r3, [r1, #12] 8001d88: 2a00 cmp r2, #0 8001d8a: d0e3 beq.n 8001d54 <irq_USART3+0x14> 8001d8c: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 8001d90: f04f 5280 mov.w r2, #268435456 ; 0x10000000 8001d94: f8c3 2d04 str.w r2, [r3, #3332] ; 0xd04 8001d98: f3bf 8f4f dsb sy 8001d9c: f3bf 8f6f isb sy 8001da0: b004 add sp, #16 8001da2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} 8001da6: 4e81 ldr r6, [pc, #516] ; (8001fac <irq_USART3+0x26c>) 8001da8: 685b ldr r3, [r3, #4] 8001daa: f8d6 53a4 ldr.w r5, [r6, #932] ; 0x3a4 8001dae: f88d 3008 strb.w r3, [sp, #8] 8001db2: f3ef 8811 mrs r8, BASEPRI 8001db6: f04f 0350 mov.w r3, #80 ; 0x50 8001dba: f383 8811 msr BASEPRI, r3 8001dbe: f3bf 8f4f dsb sy 8001dc2: f3bf 8f6f isb sy 8001dc6: 6baa ldr r2, [r5, #56] ; 0x38 8001dc8: 6beb ldr r3, [r5, #60] ; 0x3c 8001dca: 429a cmp r2, r3 8001dcc: d370 bcc.n 8001eb0 <irq_USART3+0x170> 8001dce: 2200 movs r2, #0 8001dd0: f388 8811 msr BASEPRI, r8 8001dd4: 4b76 ldr r3, [pc, #472] ; (8001fb0 <irq_USART3+0x270>) 8001dd6: f8d6 1114 ldr.w r1, [r6, #276] ; 0x114 8001dda: 4299 cmp r1, r3 8001ddc: bf18 it ne 8001dde: f8c6 3114 strne.w r3, [r6, #276] ; 0x114 8001de2: 0620 lsls r0, r4, #24 8001de4: d5d0 bpl.n 8001d88 <irq_USART3+0x48> 8001de6: e7b9 b.n 8001d5c <irq_USART3+0x1c> 8001de8: f893 0044 ldrb.w r0, [r3, #68] ; 0x44 8001dec: 6c1d ldr r5, [r3, #64] ; 0x40 8001dee: b240 sxtb r0, r0 8001df0: 2d00 cmp r5, #0 8001df2: d04e beq.n 8001e92 <irq_USART3+0x152> 8001df4: 68dc ldr r4, [r3, #12] 8001df6: 442c add r4, r5 8001df8: 689d ldr r5, [r3, #8] 8001dfa: 60dc str r4, [r3, #12] 8001dfc: 42ac cmp r4, r5 8001dfe: bf24 itt cs 8001e00: 681c ldrcs r4, [r3, #0] 8001e02: 60dc strcs r4, [r3, #12] 8001e04: f3bf 8f4f dsb sy 8001e08: f3bf 8f4f dsb sy 8001e0c: f3bf 8f4f dsb sy 8001e10: f8d3 800c ldr.w r8, [r3, #12] 8001e14: f8d3 c040 ldr.w ip, [r3, #64] ; 0x40 8001e18: f018 0f03 tst.w r8, #3 8001e1c: ad02 add r5, sp, #8 8001e1e: d055 beq.n 8001ecc <irq_USART3+0x18c> 8001e20: f1bc 0f00 cmp.w ip, #0 8001e24: dd2f ble.n 8001e86 <irq_USART3+0x146> 8001e26: f108 0401 add.w r4, r8, #1 8001e2a: 1b2f subs r7, r5, r4 8001e2c: 2f02 cmp r7, #2 8001e2e: f240 80a2 bls.w 8001f76 <irq_USART3+0x236> 8001e32: f10c 37ff add.w r7, ip, #4294967295 ; 0xffffffff 8001e36: 2f05 cmp r7, #5 8001e38: f240 809d bls.w 8001f76 <irq_USART3+0x236> 8001e3c: f02c 0903 bic.w r9, ip, #3 8001e40: 44c1 add r9, r8 8001e42: 4644 mov r4, r8 8001e44: 462f mov r7, r5 8001e46: f854 eb04 ldr.w lr, [r4], #4 8001e4a: f847 eb04 str.w lr, [r7], #4 8001e4e: 454c cmp r4, r9 8001e50: d1f9 bne.n 8001e46 <irq_USART3+0x106> 8001e52: f02c 0403 bic.w r4, ip, #3 8001e56: 45a4 cmp ip, r4 8001e58: eb08 0904 add.w r9, r8, r4 8001e5c: eb05 0e04 add.w lr, r5, r4 8001e60: ebac 0704 sub.w r7, ip, r4 8001e64: d00f beq.n 8001e86 <irq_USART3+0x146> 8001e66: f818 c004 ldrb.w ip, [r8, r4] 8001e6a: f805 c004 strb.w ip, [r5, r4] 8001e6e: 2f01 cmp r7, #1 8001e70: d009 beq.n 8001e86 <irq_USART3+0x146> 8001e72: f899 4001 ldrb.w r4, [r9, #1] 8001e76: f88e 4001 strb.w r4, [lr, #1] 8001e7a: 2f02 cmp r7, #2 8001e7c: d003 beq.n 8001e86 <irq_USART3+0x146> 8001e7e: f899 4002 ldrb.w r4, [r9, #2] 8001e82: f88e 4002 strb.w r4, [lr, #2] 8001e86: f3bf 8f6f isb sy 8001e8a: f3bf 8f6f isb sy 8001e8e: f3bf 8f6f isb sy 8001e92: 3901 subs r1, #1 8001e94: 6399 str r1, [r3, #56] ; 0x38 8001e96: 1c41 adds r1, r0, #1 8001e98: d059 beq.n 8001f4e <irq_USART3+0x20e> 8001e9a: 3001 adds r0, #1 8001e9c: b240 sxtb r0, r0 8001e9e: f883 0044 strb.w r0, [r3, #68] ; 0x44 8001ea2: f386 8811 msr BASEPRI, r6 8001ea6: 4b40 ldr r3, [pc, #256] ; (8001fa8 <irq_USART3+0x268>) 8001ea8: f89d 1008 ldrb.w r1, [sp, #8] 8001eac: 6059 str r1, [r3, #4] 8001eae: e76b b.n 8001d88 <irq_USART3+0x48> 8001eb0: f895 7045 ldrb.w r7, [r5, #69] ; 0x45 8001eb4: a902 add r1, sp, #8 8001eb6: b27f sxtb r7, r7 8001eb8: 4628 mov r0, r5 8001eba: f015 fa19 bl 80172f0 <prvCopyDataToQueue.constprop.0> 8001ebe: 1c7b adds r3, r7, #1 8001ec0: d039 beq.n 8001f36 <irq_USART3+0x1f6> 8001ec2: 3701 adds r7, #1 8001ec4: b27f sxtb r7, r7 8001ec6: f885 7045 strb.w r7, [r5, #69] ; 0x45 8001eca: e780 b.n 8001dce <irq_USART3+0x8e> 8001ecc: f1bc 0f03 cmp.w ip, #3 8001ed0: dda6 ble.n 8001e20 <irq_USART3+0xe0> 8001ed2: f1ac 0c04 sub.w ip, ip, #4 8001ed6: f108 0404 add.w r4, r8, #4 8001eda: ea4f 099c mov.w r9, ip, lsr #2 8001ede: 42a5 cmp r5, r4 8001ee0: bf18 it ne 8001ee2: f1bc 0f1f cmpne.w ip, #31 8001ee6: f109 0a01 add.w sl, r9, #1 8001eea: d94f bls.n 8001f8c <irq_USART3+0x24c> 8001eec: f018 0f07 tst.w r8, #7 8001ef0: d14c bne.n 8001f8c <irq_USART3+0x24c> 8001ef2: f1a8 0408 sub.w r4, r8, #8 8001ef6: ea4f 0e5a mov.w lr, sl, lsr #1 8001efa: eb04 0ece add.w lr, r4, lr, lsl #3 8001efe: 462f mov r7, r5 8001f00: ed94 7b02 vldr d7, [r4, #8] 8001f04: 3408 adds r4, #8 8001f06: 4574 cmp r4, lr 8001f08: eca7 7b02 vstmia r7!, {d7} 8001f0c: d1f8 bne.n 8001f00 <irq_USART3+0x1c0> 8001f0e: f01a 0f01 tst.w sl, #1 8001f12: f02a 0701 bic.w r7, sl, #1 8001f16: d003 beq.n 8001f20 <irq_USART3+0x1e0> 8001f18: f858 4027 ldr.w r4, [r8, r7, lsl #2] 8001f1c: f845 4027 str.w r4, [r5, r7, lsl #2] 8001f20: f109 0401 add.w r4, r9, #1 8001f24: ebc9 7989 rsb r9, r9, r9, lsl #30 8001f28: eb0c 0c89 add.w ip, ip, r9, lsl #2 8001f2c: eb05 0584 add.w r5, r5, r4, lsl #2 8001f30: eb08 0884 add.w r8, r8, r4, lsl #2 8001f34: e774 b.n 8001e20 <irq_USART3+0xe0> 8001f36: 6a6b ldr r3, [r5, #36] ; 0x24 8001f38: 2b00 cmp r3, #0 8001f3a: f43f af48 beq.w 8001dce <irq_USART3+0x8e> 8001f3e: f105 0024 add.w r0, r5, #36 ; 0x24 8001f42: f7ff fdcf bl 8001ae4 <xTaskRemoveFromEventList> 8001f46: 1e02 subs r2, r0, #0 8001f48: bf18 it ne 8001f4a: 2201 movne r2, #1 8001f4c: e740 b.n 8001dd0 <irq_USART3+0x90> 8001f4e: 6919 ldr r1, [r3, #16] 8001f50: b911 cbnz r1, 8001f58 <irq_USART3+0x218> 8001f52: f386 8811 msr BASEPRI, r6 8001f56: e7a6 b.n 8001ea6 <irq_USART3+0x166> 8001f58: f103 0010 add.w r0, r3, #16 8001f5c: 9201 str r2, [sp, #4] 8001f5e: f7ff fdc1 bl 8001ae4 <xTaskRemoveFromEventList> 8001f62: 9a01 ldr r2, [sp, #4] 8001f64: 2800 cmp r0, #0 8001f66: d0f4 beq.n 8001f52 <irq_USART3+0x212> 8001f68: f386 8811 msr BASEPRI, r6 8001f6c: 4b0e ldr r3, [pc, #56] ; (8001fa8 <irq_USART3+0x268>) 8001f6e: f89d 2008 ldrb.w r2, [sp, #8] 8001f72: 605a str r2, [r3, #4] 8001f74: e70a b.n 8001d8c <irq_USART3+0x4c> 8001f76: 44c4 add ip, r8 8001f78: 3d01 subs r5, #1 8001f7a: e000 b.n 8001f7e <irq_USART3+0x23e> 8001f7c: 3401 adds r4, #1 8001f7e: f814 7c01 ldrb.w r7, [r4, #-1] 8001f82: f805 7f01 strb.w r7, [r5, #1]! 8001f86: 45a4 cmp ip, r4 8001f88: d1f8 bne.n 8001f7c <irq_USART3+0x23c> 8001f8a: e77c b.n 8001e86 <irq_USART3+0x146> 8001f8c: eb08 0a8a add.w sl, r8, sl, lsl #2 8001f90: 462f mov r7, r5 8001f92: 4644 mov r4, r8 8001f94: 469e mov lr, r3 8001f96: f854 3b04 ldr.w r3, [r4], #4 8001f9a: f847 3b04 str.w r3, [r7], #4 8001f9e: 4554 cmp r4, sl 8001fa0: d1f9 bne.n 8001f96 <irq_USART3+0x256> 8001fa2: 4673 mov r3, lr 8001fa4: e7bc b.n 8001f20 <irq_USART3+0x1e0> 8001fa6: bf00 nop 8001fa8: 40004800 andmi r4, r0, r0, lsl #16 8001fac: 20000334 andcs r0, r0, r4, lsr r3 8001fb0: 20000830 andcs r0, r0, r0, lsr r8 Изменено 13 ноября, 2021 пользователем amaora Добавил маркеры вокруг функции memcpy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба А листинг где? Ну ок, смотрим. Находим: ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); листинг этого куска? Здесь у вас pvBuffer указывает на переменную размером ==1байт. А чему равно pxQueue->uxItemSize? Возможно после инлайнинга компилятор видит, что она >1. Отсюда и варнинги. PS: Что за странный способ описания указателей? Зачем Вы в аргументах функций везде передаёте константные указатели void * const p вместо указателей на константу void const *p ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 13 ноября, 2021 Опубликовано 13 ноября, 2021 (изменено) · Жалоба По листингу (обновил предыдущее сообщение), значение uxItemSize компилятор не смог отследить (не может знать, какой из обработчиков прерываний вызовется раньше, irq_USART или irq_Reset) и подставил полный код memcpy со всеми проверками и циклом по длине. Заменил memcpy на вот это, u8_t *xd = (u8_t *) d; const u8_t *xs = (const u8_t *) s; if (n == 1) *(xd) = *xs; if (n == 2) *(xd + 1) = *xs; получил предупреждение и такой результат, 8001e02: f3bf 8f4f dsb sy 8001e06: f3bf 8f4f dsb sy 8001e0a: f3bf 8f4f dsb sy 8001e0e: 6c1d ldr r5, [r3, #64] ; 0x40 8001e10: 68de ldr r6, [r3, #12] 8001e12: 2d01 cmp r5, #1 8001e14: d028 beq.n 8001e68 <irq_USART3+0x128> 8001e16: 2d02 cmp r5, #2 8001e18: bf04 itt eq 8001e1a: 7835 ldrbeq r5, [r6, #0] 8001e1c: f88d 5010 strbeq.w r5, [sp, #16] 8001e20: f3bf 8f6f isb sy 8001e24: f3bf 8f6f isb sy 8001e28: f3bf 8f6f isb sy ... 8001e68: 7835 ldrb r5, [r6, #0] 8001e6a: f88d 500f strb.w r5, [sp, #15] 8001e6e: e7d7 b.n 8001e20 <irq_USART3+0xe0> Что не так? Вот clang выдаёт (без предупреждений), 800386e: f3bf 8f4f dsb sy 8003872: f3bf 8f4f dsb sy 8003876: f3bf 8f4f dsb sy 800387a: 6c14 ldr r4, [r2, #64] ; 0x40 800387c: 68d5 ldr r5, [r2, #12] 800387e: 2c02 cmp r4, #2 8003880: d00f beq.n 80038a2 <irq_USART3+0x1da> 8003882: 2c01 cmp r4, #1 8003884: d110 bne.n 80038a8 <irq_USART3+0x1e0> 8003886: f895 8000 ldrb.w r8, [r5] 800388a: f807 8c19 strb.w r8, [r7, #-25] 800388e: e00b b.n 80038a8 <irq_USART3+0x1e0> 8003890: f38c 8811 msr BASEPRI, ip 8003894: f8d9 1008 ldr.w r1, [r9, #8] 8003898: f021 0180 bic.w r1, r1, #128 ; 0x80 800389c: f8c9 1008 str.w r1, [r9, #8] 80038a0: e083 b.n 80039aa <irq_USART3+0x2e2> 80038a2: 7829 ldrb r1, [r5, #0] 80038a4: f807 1c18 strb.w r1, [r7, #-24] 80038a8: f3bf 8f6f isb sy 80038ac: f3bf 8f6f isb sy 80038b0: f3bf 8f6f isb sy посторонний кусок попал сюда и порядок копирования вывернут, но действия такие же. В чем смысл предупреждений GCC? Может надо было дальше пойти и предупреждать, что вся структура очереди может быть неициализирована? Он же не знает, что прерывания USART3 не будет пока его не разрешат, а до того очередь будет создана (с размером 1), где-то далеко в дебрях кода вызываемого из irq_Reset или даже через смены контекста в одной из задач. PS: Про объявления не ко мне, это код FreeRTOS. Изменено 13 ноября, 2021 пользователем amaora Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 14 ноября, 2021 Опубликовано 14 ноября, 2021 · Жалоба 6 часов назад, amaora сказал: По листингу (обновил предыдущее сообщение), значение uxItemSize компилятор не смог отследить Да, это видно: 8001e14: f8d3 c040 ldr.w ip, [r3, #64] ; 0x40 А если убрать (void) перед memcpy? Может с (void) подставляется какой-то оптимизированный вариант memcpy(), не умеющий работать с размерами <4 байт? Цитата Заменил memcpy на вот это, u8_t *xd = (u8_t *) d; const u8_t *xs = (const u8_t *) s; if (n == 1) *(xd) = *xs; if (n == 2) *(xd + 1) = *xs; получил предупреждение и такой результат, Трудно сказать что там не нравится, вроде всё ок. Может компилятор отследил все места присвоений значения в uxItemSize по всему коду и увидел, что везде ей присваивается >1? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться