Jump to content

    
Sign in to follow this  
amaora

Что такое с выраниванием в GCC

Recommended Posts

Для теста собрал один свой проект с разными ключами компиляции, и обнаружил вот это,

 

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;
}

 

 

Edited by amaora

Share this post


Link to post
Share on other sites
28 минут назад, amaora сказал:

видимо связана с выравниванием стека на 8 байт.

Скорее всего, хотя странно. Попробуйте static добавить переменной, чтоб она не на стеке выделялась.

Share this post


Link to post
Share on other sites
1 час назад, amaora сказал:

В чем причина не понял, видимо связана с выравниванием стека на 8 байт.

С чего сделан такой странный вывод?

Вангую:

Где-то внутри цепочки вызовов производится вычисление какого-то адреса со смещениями =4 и =8 относительно переданного внутрь адреса &u.

Пока эти функции компилируются отдельно от irq_USART3() компилятор не имеет информации о размере переменных, указатели на которые передаются внутрь. И у него не возникает возражений.

При включении высокого уровня оптимизации и инлайнинга всей цепочки вызовов внутрь irq_USART3() (а тем более если у вас там ещё включается и режим компиляции "единым файлом" (в IAR - "multi-file compilation")), компилятор видит размер u. И это вызывает у него несварение.  :bad:

1 час назад, amaora сказал:

Хотел так же посмотреть итоговый код после компиляции, но на -O3 он подставляет все внутренности freertos и разобрать там что либо сложно.

В таких случаях, в интересующем месте исходника, я вставляю код, который не может быть перемещён оптимизатором или удалён, и который легко найти в листинге (генерящий команды, которых больше нигде нет). Например в IAR это интрсинки: __ISB() или __SEV() или аналогичные. Они просто вставляют соответствующие команды ISB или SEV, которые потом легко найти в листинге.

Share this post


Link to post
Share on other sites
1 час назад, amaora сказал:

а происходит оно при компиляции вот такого кода (сократил до минимального)

А покажите прототип xQueueReceiveFromISR и prvCopyDataFromQueue.

Share this post


Link to post
Share on other sites
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 )

 

Share this post


Link to post
Share on other sites
12 минут назад, amaora сказал:

Цепочка не большая, по коду видно, что манипуляций с адресами нет, передаётся как есть в memcpy. Но эффект похожий, если прибавить руками к адресу передаваемому в memcpy то будут такие же предупреждения. Знать бы ещё в каком месте берётся адрес, поставил бы туда маркер.

Так если "небольшая", то впендюрьте сюда весь листинг. Под спойлер.

Share this post


Link to post
Share on other sites
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

 

 

Edited by amaora
Добавил маркеры вокруг функции memcpy

Share this post


Link to post
Share on other sites

А листинг где?

Ну ок, смотрим. Находим:

( 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 ?

Share this post


Link to post
Share on other sites

По листингу (обновил предыдущее сообщение), значение 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.

Edited by amaora

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this