Перейти к содержанию
    

VladislavS

Свой
  • Постов

    1 240
  • Зарегистрирован

  • Посещение

  • Победитель дней

    9

Сообщения, опубликованные VladislavS


  1. И всё же, виноват порванный презерватив. IAR 9.10.1

     

    #include <atomic>
    
    struct FocQ {
      union {             
        struct {          
          uint32_t amplitude;  
          uint32_t angle;      
        };                
        std::atomic<uint64_t> ampl_angle;
      };                  
      int64_t reduI;          
    };
    
    __attribute__ ((aligned (4))) FocQ focQ;

    На результат влияет либо наличие atomic, либо выравнивание на 8. __packed влияет на выравнивание и соответственно на результат.

  2.  Вы слишком много хотите от компилятора. Меня, например, больше напрягает, когда он (по моей указке) молча вот так делает

    constexpr uint8_t *x = (uint8_t *)1;
    volatile uint64_t y = *(uint64_t *)x;
            MOVS     R0,#+1         
            LDRD     R0,R1,[R0, #+0]
            STRD     R0,R1,[SP, #+0]

     

  3. 8 минут назад, jcxz сказал:

    Таким приведением типа указателя я явно говорю компилятору что u64 - выровнено.

    Что именно в приведении к (u64 *) говорит о том что до приведения там всё было выровнено?

  4. Когда программист начинает мудрить с упаковками, выравниваниями и приведениями типов указателей, то компилятор правильно делает, что перестраховывается. Ну не смог он на 100% гарантировать, что SRD в этом месте будет по слову выровнен. Пусть уж лучше два str будет. У меня был на компиляторе ARM v6 случай, когда я схлопотал LDM с невыровненым адресом из-за приведения типов указателей.

  5. Вот такая последовательность обмена.

    Int_USBRST
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_Device_Descriptor 64 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_USBRST
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> SET_ADDRESS 6
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_Device_Descriptor 18 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_Configuration_Descriptor 255 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_String_Descriptor 0x3 255 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_String_Descriptor 0x0 255 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_String_Descriptor 0x2 255 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_Device_qualifier_Descriptor 10 bytes
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> SET_CONTROL_LINE_STATE
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_LINE_CODING
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> SET_LINE_CODING
    Int_RXFLVL EP0 DATA_UPDT CNT=7
    SET_LINE_CODING DATA
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_LINE_CODING
    Int_OEPINT EP0 XFRC ZLP Received
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> SET_CONTROL_LINE_STATE
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> SET_LINE_CODING
    Int_RXFLVL EP0 DATA_UPDT CNT=7
    SET_LINE_CODING DATA
    Int_RXFLVL EP0 SETUP_UPDT CNT=8
    Int_OEPINT EP0 STUP -> GET_LINE_CODING
    Int_OEPINT EP0 XFRC ZLP Received
  6. Да, должен сам тухнуть. Вот функции чтения FIFO. Не забыть позаботиться о выравнивании буфера куда читаете. Иначе лучше через временную uint32_t переменную и из неё побайтно.

    static inline void ReadSetupFIFO(uint8_t *adr)
    {
      //Прочитать SETUP пакет из FIFO, он всегда 8 байт
      *(uint32_t *)adr = *otg_dfifo<0>();
      *((uint32_t *)adr+1) = *otg_dfifo<0>();
    }
    
    static inline void ReadFIFO(uint8_t *dest, uint16_t len)
    {
      for ( uint32_t words2read = (len+3)>>2; words2read--; dest += 4 )
        *(uint32_t *)dest = *otg_dfifo<0>();
    }

    Ну и немножко отомщу за асм. :)

    В файлах обработчик прерываний. Там для FS и HS сразу, поэтому немного раздуто, но работу с битами видно хорошо.

    stm32_usb_otg.cpp

    stm32_usb_otg.hpp

  7. Что-то вы проблему из ничего создаёте. Отлаживая оптимизированный код надо быть готовым к разного рода приколам. Сравниваем ваши два числа и, казалось бы, сейчас получим false1.png.a2ec795ebc775e504e24221eb833ec1c.png

    Однако, природу не обманешь. Равны они.

    2.png.f91624180a52b6cc18d2c99110eb1aa2.png

     

  8. Куда-то вас занесло. У ТС проблема в том что в стартапах от разных тулчейнов разные имена процедур обработки прерываний. В одном из стартапов накосячено, ибо в заголовочном файле от производителя все эти имена есть, надо их использовать. Кто конкретно делал этот косячный стартап дело десятое. Я же предлагаю использовать один стартап для разных тулчейнов, чтобы подобные несоответствия не вылазили. Причём тут RTOS-ы вообще?

×
×
  • Создать...