SommarioGCC 4.7.2 problemi di ottimizzazione
sto porting USB OTG della ST Library per una scheda STM32F4 personalizzato utilizzando l'ultima versione di Sourcery CodeBench Lite toolchain (GCC braccio-nessuno-EABI 4.7.2).
Quando compilo il codice con -O0, il programma funziona correttamente. Quando compilo con -O1 o -O2 fallisce. Quando dico fallire, si ferma. No hard fault, nothing (Beh, ovviamente c'è qualcosa che sta facendo ma non ho un emulatore da usare per eseguire il debug e scoprire, mi dispiace. Il mio gestore di errori non viene chiamato).
dettagli
Sto cercando di fare una chiamata alla funzione seguente ...
void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBD_DEVICE *pDevice,
USBD_Class_cb_TypeDef *class_cb,
USBD_Usr_cb_TypeDef *usr_cb);
... ma non sembra farne del corpo della funzione. (È questo un sintomo di "stack-smashing"?)
Le strutture passati a questa funzione hanno le seguenti definizioni:
typedef struct USB_OTG_handle
{
USB_OTG_CORE_CFGS cfg;
USB_OTG_CORE_REGS regs;
DCD_DEV dev;
}
USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE;
typedef enum
{
USB_OTG_HS_CORE_ID = 0,
USB_OTG_FS_CORE_ID = 1
}USB_OTG_CORE_ID_TypeDef;
typedef struct _Device_TypeDef
{
uint8_t *(*GetDeviceDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetLangIDStrDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetManufacturerStrDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetProductStrDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetSerialStrDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetConfigurationStrDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetInterfaceStrDescriptor)(uint8_t speed , uint16_t *length);
} USBD_DEVICE, *pUSBD_DEVICE;
typedef struct _Device_cb
{
uint8_t (*Init) (void *pdev , uint8_t cfgidx);
uint8_t (*DeInit) (void *pdev , uint8_t cfgidx);
/* Control Endpoints*/
uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req);
uint8_t (*EP0_TxSent) (void *pdev);
uint8_t (*EP0_RxReady) (void *pdev);
/* Class Specific Endpoints*/
uint8_t (*DataIn) (void *pdev , uint8_t epnum);
uint8_t (*DataOut) (void *pdev , uint8_t epnum);
uint8_t (*SOF) (void *pdev);
uint8_t (*IsoINIncomplete) (void *pdev);
uint8_t (*IsoOUTIncomplete) (void *pdev);
uint8_t *(*GetConfigDescriptor)(uint8_t speed , uint16_t *length);
uint8_t *(*GetUsrStrDescriptor)(uint8_t speed ,uint8_t index, uint16_t *length);
} USBD_Class_cb_TypeDef;
typedef struct _USBD_USR_PROP
{
void (*Init)(void);
void (*DeviceReset)(uint8_t speed);
void (*DeviceConfigured)(void);
void (*DeviceSuspended)(void);
void (*DeviceResumed)(void);
void (*DeviceConnected)(void);
void (*DeviceDisconnected)(void);
}
USBD_Usr_cb_TypeDef;
ho cercato di includere tutto il codice sorgente relativo a questo problema. Se volete vedere l'intero codice sorgente è possibile scaricarlo qui: http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stm32_f105-07_f2_f4_usb-host-device_lib.zip
Solutions Tentato
ho provato a giocare con #pragma GCC optimize ("O0")
, __attribute__((optimize("O0")))
, e che dichiara alcune definizioni come volatile
, ma niente ha funzionato. Preferirei semplicemente modificare il codice per farlo funzionare bene con l'ottimizzatore comunque.
Domanda
Come posso modificare il codice per renderlo bel gioco con ottimizzatore di GCC?
È probabile che l'attivazione delle ottimizzazioni esponga UB nel codice. Ad esempio, il tuo codice è probabilmente sbagliato anche se le ottimizzazioni sono disabilitate, semplicemente non vedi alcun sintomo. – ildjarn
Questo è un file zip da 3,7 MB, non ho idea che qualcuno possa eseguire il debug di questo per te gratuitamente. Il codice postato è solo alcune dichiarazioni e non ci dice nulla. Dovresti ridurre il codice al minimo possibile e provare a eseguirne il debug. Inoltre, hai attivato tutti gli avvisi e prestato attenzione a loro? – nos
Perché nessun emulatore? Potresti voler investire $ 15 in una scheda STM32F4DISCOVERY con un JTAG incorporato. Non ne ho mai usato uno, e non so se la toolchain di Sourcery CodeBench Lite funzionerà facilmente con esso, ma dovresti essere in grado di far funzionare la libreria ST USB OTG con qualche toolchain (se non la toolchain di Sourcery) e vedi se hai qualche problema con il tuo codice che si interfaccia ad esso. –