Почему оптимизация меняет мой адрес указателя без причины? - PullRequest
0 голосов
/ 31 января 2019

У меня проблемы с оптимизацией во встроенном C-приложении.Адрес указателя неожиданно меняется на 0x0 и нарушает мой код.

Я использую инструментарий GNU MCU Eclipse ARM Embedded GCC.Я использую датчик, с которым я общаюсь через SPI.Датчик имеет 8 конфигурационных регистров по 16 бит каждый.Я храню локальную копию конфигураций в структуре с именем hallsensor_zTleConfig. Я регулярно читаю сохраненную конфигурацию датчика («zTleSensorConfig») и сравниваю ее с локальной копией, чтобы определить, не произошло ли повреждение памяти.

БезОптимизация, этот процесс работает.

При оптимизации в приведенном ниже коде указатель на главную / локальную копию неожиданно меняется на 0x0 без видимой причины.

// Master copy of configuration of the TLE chips
static TLE5012B_zCONFIG hallsensor_zTleConfig[ HALLSENSOR_COUNT ];

static void Hallsensor_VerifyConfig( HALLSENSOR_eUNIT eUnit )
{
    TLE5012B_zCONFIG zTleSensorConfig;
    uint16* pu16MasterConfigPointer = &hallsensor_zTleConfig[ eUnit ];
    uint16* pu16SensorConfigPointer = &zTleSensorConfig;
    uint8 u8Index;

    // Read all configuration parameters
    (void)Hallsensor_ReadRegister( TLE5012B_MOD_2, &zTleSensorConfig, sizeof( TLE5012B_zCONFIG ) );

    // Copy over configurations modified by Auto-calibration and reserved bits
    hallsensor_zTleConfig[ eUnit ].zMod3.u12ANG_BASE     =     zTleSensorConfig.zMod3.u12ANG_BASE;
    hallsensor_zTleConfig[ eUnit ].zSynch.i12AmpSynch    =     zTleSensorConfig.zSynch.i12AmpSynch;
    hallsensor_zTleConfig[ eUnit ].zOffsetX.i12XOffset   = zTleSensorConfig.zOffsetX.i12XOffset;
    hallsensor_zTleConfig[ eUnit ].zOffsetY.i12YOffset   = zTleSensorConfig.zOffsetY.i12YOffset;
    hallsensor_zTleConfig[ eUnit ].zMod4.u7TCO_X_T       = zTleSensorConfig.zMod4.u7TCO_X_T;
    hallsensor_zTleConfig[ eUnit ].zTcoY.u7TCO_Y_T       = zTleSensorConfig.zTcoY.u7TCO_Y_T;
    hallsensor_zTleConfig[ eUnit ].zMod2.u1Reserved      = zTleSensorConfig.zMod2.u1Reserved;
    hallsensor_zTleConfig[ eUnit ].zMod4.u1Reserved      = zTleSensorConfig.zMod4.u1Reserved;
    hallsensor_zTleConfig[ eUnit ].zOffsetX.u4Reserved   = zTleSensorConfig.zOffsetX.u4Reserved;
    hallsensor_zTleConfig[ eUnit ].zOffsetY.u4Reserved   = zTleSensorConfig.zOffsetY.u4Reserved;
    hallsensor_zTleConfig[ eUnit ].zSynch.u4Reserved     = zTleSensorConfig.zSynch.u4Reserved;

    // Compare local Master config setting to sensor settings and look for corrupted data
    for ( u8Index = 0; u8Index < TLE5012B_CONFIG_REG_COUNT; u8Index++ )
    {
        // Configuration invalid?
        if ( pu16MasterConfigPointer[u8Index] != pu16SensorConfigPointer[u8Index] )
        {
            hallsensor_bConfigOk[ eUnit ] = FALSE;
        }
    }

    // Data corrupted?
    if ( !hallsensor_bConfigOk[ eUnit ] )
    {
        // Do stuff
    }
}

В началеФункция pu16MasterConfigPointer и pu16SensorConfigPointer правильно содержат адрес соответствующих структур.Однако непосредственно перед первым циклом for значение pu16MasterConfigPointer изменяется на 0x0, и все условия цикла for приводят к значению TRUE.

Я пробовал множество комбинаций volatile для различных переменных и указателей, и результаты по-прежнему нарушают код в различных другихспособы (например, цикл for не разветвляется для оператора if, смотрящего на код asm, приводящий к тому, что оператор всегда переходит в "hallsensor_bConfigOk [eUnit] = FALSE;")

PS: хороший ресурс, чтобы узнать о том, как защититьВаш код от проблем оптимизации был бы очень кстати.

Снимок экрана отладчика с указателем = 0x0 с кодом asm

enter image description here

1 Ответ

0 голосов
/ 31 января 2019

@ Джон Боллинджер был прав, говоря, что указатели нарушают строгое правило псевдонимов, которое мне было неизвестно.В этом посте .

есть хорошее объяснение этого правила. Замена цикла for на memcmp сделала свое дело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...