Bir Garip Debug Durumu Union ve Parçaları

Başlatan e-zeki, 04 Ocak 2021, 15:32:36

e-zeki

Merhabalar. bir stm32F4 ve bir stm32F0 MCU ile proje geliştiriyorum. daha önce sıkça kullandığım bir şekilde union tanımladım CAN BUS üzerinden haberleşecekler.
fakat şöyle bir durum açığa çıktı
F4 tarafında union sorunsuz çalışmakta, tüm parçalara erşip değiştirebiliyorum. debugda da gözleyebiliyorum değişikliği
FAKAT:
F0 tarafında uint32_t olmayan parçalar (bit sınırlaması yaptıklarım)değiştirilemez halde kalıyor, elle yazdığımda kod tepki vermiyor. memcpy memset ile yaparsam ya da kod içinde değiştiryorsam değer değişiyor fakat elle müdahale ettirmiyor. Üstelik 0 olarak görünüyor her zaman. Örneğin Tester.a 15 bit olduğu için 0 görünürken b ve c sorunsuz şekilde hem gösteriyor hem değiştirilebiliyor.
 F4 debug da sıkıntısız müdahale edebiliyorken F0'da edemememin özel bir sebebi var mıdır?

Union:
#pragma pack(push,1)
typedef struct{
  struct{
    uint8_t DLC:4;
    uint8_t RTR:2;
  }Frame;
  
  union{
    uint32_t ID;
    struct{
    uint32_t node:7;
    uint32_t COB:4;
    uint32_t :21; 
    }stdID;
  }CanID;
  union{
    uint8_t whole[8];
    struct{
      uint32_t s:1;
      uint32_t e:1; 
      uint32_t n:2; 
      uint32_t :1;
      uint32_t ccs:3;
      uint32_t index:16;
      uint32_t subIndex:8;
      uint32_t variable;
    }Parts;
    struct{
      uint16_t a:15;
      uint16_t:1;
      uint16_t b;
      uint32_t c;
    }Tester;
  }Data;
} CAN_PackTypeDef;
#pragma pack(pop)
Bu da debug ekranı:


Tagli

Değerleri kod içinden mi atamaya çalışıyorsun yoksa debugging sırasında IDE üzerinden mi?

Konuyla doğrudan ilgili olmayabilir ama ilk deneyeceğim şey strict aliasing optimizasyonunu kapatmak olurdu. CubeIDE'de optimizayon ayarlarıda çıkıyor. GCC için -fno-strict-aliasing bayrağı da kullanılabiliyor. Ben zaten hep kapalı tutarım bunu.

F0 ve F4 arasında ilk aklıma gelen fark unaligned access destekleyip desteklememeleri. Gerçi F0 için GCC bunu göz önünde bulundurarak kod üretiyor struct ve union'lar için. Hem zaten bunu ihlal edersen doğrudan hard fault alırsın, yani debug sırasında kendini belli eder. Ama acaba debug session üzerinde atama yapmaya çalıştığında, derleyicinin yapabildiğini debugger yapamıyor olabilir mi? İlk paragraftaki soruyu o yüzden sormuştum.
Gökçe Tağlıoğlu

e-zeki

@Tagli hocam merhaba cevabınızı yeni gördüm.
Hem kod içinde hem elle değiştirmeye çalışıyorum. aslında istediğim değeri alıyor kod içinde değiştirirsem, çünkü başka bir MCU üzerinden ekrana yazdırıyorum ben bu struct'ın parametrelerini. fakat debug hiçbir şekilde göstermiyor. fakat elle değiştirmeme müsade etmiyor garip bir şekilde.

Emre_Tuncay_

#3
Buna benzer bir durumla bugun karşılaştım 2 saat'te yakın uğraştırdı.

Bir struct içine ADC'den ölçtüğüm verileri yazdırıyorum. Oradan da bir haberleşme protokolünün class'ı içindeki bir değişkene veri yazıyorum. Aşağıdaki gibi.

x = y; (Veri tipleri aynı)

y değeri analog ölçüme göre değişsene ne oluyorsa y değeri x değişkenine atanmıyordu. İlk optimizasyondan kaynaklı sandım ama çözüme ulaşamadım. Bu durum sadece struct'ın ilk elemanı için oluyordu.
Sonra #pragma pack(1) kullanmak geldi aklıma bu şekilde çözüldü. Sanırım pragma pack kullanmadığımda ilk eleman başka bir struct'ın son elemanı ile birleşiyor gibi bir durum oluşuyor.(Literatürde ne diye geçer bilmiyorum)

Diğer struct'larda da #pragma pack(1) kullanmayı denediniz mi?

e-zeki

@Emre_Tuncay_  kullandım hocam zaten yukarıda kodda da var.

Emre_Tuncay_

#5
Ben yanlış görmüşüm bunlar hep bir struct içindeymiş. Ben ayrı ayrı gibi görmüştüm.