Czy wolisz polską wersję strony elektroda?
Nie, dziękuję Przekieruj mnie tamFreddie Chopin napisał:A masz wyrównane stosy do 8-miu bajtów? Kiedyś o tym pisałem - bez tego właśnie CZASEM dzieją się problemy - np z funkcjami variadic, czyli m.in. z printfem...
4\/3!!
Freddie Chopin napisał:Zmiana w samym mallocu może nie pomóc - zależy jaki będzie najwyższy adres "stosu" dostępny dla wątku, a malloc pewnie wyrównuje początek...
4\/3!!
Freddie Chopin napisał:Istotny oczywiście jest SP. Wyrównanie w funkcji malloc dotyczy na 99% adresu "od dołu", a Ciebie właśnie interesuje to co będzie "na górze".
No i nikt nie mówił o wyrównywaniu "początku" stosu [;
4\/3!!
Freddie Chopin napisał:A masz wyrównane stosy do 8-miu bajtów?
Freddie Chopin napisał:Raczej nic to nie zmieni. W funkcjach variadic float jest traktowany jak double (zajmuje 8 bajtów lub 2 rejestry), stąd problem. Kompilator dba o stos podczas pracy programu, ale to co dostaje na wejściu musi być wyrównane do 8-miu bajtów.
Jeśli chcesz znaleźć źródło problemów, to olej na chwilę FreeRTOSa i po prostu w jakimś programiku zwykłym przetestuj tego sprintfa wyrównując stos do 8, a potem do 4.
Gdy miałem stosy wyrównane do 4, to również działy się cuda - wyświetlało przeważnie 0, czasem jakieś bezsensowne liczby, zmiana abstrakcyjnych opcji kompilacji powodowała poprawę, ale tylko do czasu aż znów było źle. Dopiero wyrównanie stosu do 8 rozwiązało problem w 100%.
Mam zainstalowany ten najnowszy kompilator i u mnie sprintf z wykorzystaniem float działa tak jak działał. Szczerze mówiąc pomiędzy obecną a poprzednią wersją różnica jest baaaaaardzo mała (wersje głównych narzędzie pozostały takie same) - głównie są to poprawki jakichś bugów.
4\/3!!
sprintf((char*)buf,"%s %u %6.2f",puch,uint,flt);sprintf((char*)buf,"%s %6.2f %u",puch,flt,uint);sprintf((char*)buf,"%6.2f %s %u",flt ,puch,uint);Cytat:LINKER_FLAGS=-nostartfiles -Xlinker -oOutput.axf -Xlinker -M -Xlinker -Map=Output.map -Xlinker --gc-sections -Xlinker -lm
michalko12 napisał:Co rozumiesz przez pojęcie wyrównać stos do 8 lub 4?
Cytat:Cały obszar stosu mogę wyrównać ale jaki mam wpływ na odkładanie danych na stos?
Cytat:Wyrównanie całego obszaru stosu do 8 nic nie daje dalej mam ten błąd przy optymalizacji -O2.
Freddie Chopin napisał:michalko12 napisał:Co rozumiesz przez pojęcie wyrównać stos do 8 lub 4?
Wyrównać początkową wartość rejestru SP do wielokrotności 8.
.stack :
{
. = ALIGN(8);
__stack_start = .;
PROVIDE(__stack_start = __stack_start);
. = ALIGN(8);
__main_stack_start = .;
PROVIDE(__main_stack_start = __main_stack_start);
. += __main_stack_size;
. = ALIGN(8); // !!!! -=-=-=-=-=- TUTAJ -=-=-=-=-=- !!!!
__main_stack_end = .;
PROVIDE(__main_stack_end = __main_stack_end);
. = ALIGN(8);
__process_stack_start = .;
PROVIDE(__process_stack_start = __process_stack_start);
. += __process_stack_size;
. = ALIGN(8); // !!!! -=-=-=-=-=- TUTAJ -=-=-=-=-=- !!!!
__process_stack_end = .;
PROVIDE(__process_stack_end = __process_stack_end);
. = ALIGN(8);
__stack_end = .;
PROVIDE(__stack_end = __stack_end);
} > ram AT > ramFreddie Chopin napisał:A masz wyrównane stosy do 8-miu bajtów? Kiedyś o tym pisałem - bez tego właśnie CZASEM dzieją się problemy - np z funkcjami variadic, czyli m.in. z printfem...
static unsigned long pulStack[STACK_SIZE];static unsigned long pulStack[STACK_SIZE] __attribute__((aligned(8)));michalko12 napisał:
i po problemie (przynajmniej na razie).
Freddie Chopin napisał:Pamiętaj, że atrybutem aligned wyrównujesz najmłodszy adres stosu, a tobie zależy niejako na najstarszym, bo stos jest "descending". STACK_SIZE musi być podzielny przez 8, tak samo jak rozmia stosów dla wątków.
static struct xRTOS_HEAP
{
unsigned portLONG ulDummy;
unsigned portCHAR ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;static struct xRTOS_HEAP
{
unsigned portCHAR ucHeap[ configTOTAL_HEAP_SIZE ];
unsigned portLONG ulDummy;
} xHeap __attribute__((aligned(8)));Cytat:/* Allocate the memory for the heap. The struct is used to force byte
alignment without using any non-portable code. */
static struct xRTOS_HEAP
{
unsigned portCHAR ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap __attribute__((aligned(8)));michalko12 napisał:
Ufff...
przed:static unsigned long pulStack[STACK_SIZE];
po:static unsigned long pulStack[STACK_SIZE] __attribute__((aligned(8)));
i po problemie (przynajmniej na razie).
/* Allocate the memory for the heap. The struct is used to force byte
alignment without using any non-portable code. */
static union xRTOS_HEAP
{
#if portBYTE_ALIGNMENT == 8
volatile portDOUBLE dDummy;
#else
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
Cytat:/* Constants required to setup the initial stack. */
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
Cytat:/**
* Initialize the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called. The registers have to be placed on the stack in
* the order that the port expects to find them.
*
* @Param pxTopOfStack Pointer to the task stack.
* @Param pxCode Pointer to the task control function.
* @Param pvParameters Pointer to the parameter to be passed to the task entry function.
* @return_ The new top of the stack.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
/* The status register is set for system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
#ifdef THUMB_INTERWORK
{
/* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
#endif
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/