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

STM32H7 поведение буфера при передаче в функцию

On 7/26/2024 at 12:45 PM, EdgeAligned said:

Лично я бы не делал отдельной фукнции под названием "ReadFirmwareInfo()

Я бы и функций сериализации-десиреализации не делал бы.
А сразу бы читал в структуру.

  /// - чтение информации о прошивках из микросхемы флеш-памяти;
  int32_t res = MT25QL512ABB_ReadSTR_DMA(h_FLASHqspi,
                                         MT25QL512ABB_QPI_MODE,
                                         MT25QL512ABB_4BYTES_SIZE,
                                         (uint8_t*)FirmwareInfoPtr,
                                         START_ADDR_FIRMWARE_INFO,
                                         sizeof(*FirmwareInfoPtr));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Назначение ф-ции DeserializeSystemData я, если честно, не понял и не стал принимать во внимание. Потому что, как я ранее писал, достаточно указателя на структуру, который "одевается" как разметочный шаблон поверх любой области памяти, и она становится отформатированной как раз по разметке в структуре, с доступом к полям через ptr->xxx, как это сделано в том же GPIO->ODR

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, x893 сказал:

Не волнуйтесь. Мало ли говнокода на планете Земля. Одним больше, одним меньше.

Я и не волнуюсь. Говнокод уже не только на планете Земля. Недавно его успешно доставили на Луну. В составе миссии "Луна-25".  :biggrin:

 

Говнокод окружает нас. Он везде - от 3D-принтера, до космических аппаратов. Куда ни плюнь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/26/2024 at 2:17 PM, jcxz said:

 В составе миссии "Луна-25".  :biggrin:

То ли дело Вояджер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, EdgeAligned сказал:

достаточно указателя на структуру, который "одевается" как разметочный шаблон поверх любой области памяти,

То есть, вот о чем я говорил:

typedef struct {
	uint8_t a;
	uint8_t b;
	uint16_t c;
	uint32_t d;
	uint16_t b1 :4;
	uint16_t b2 :2;
	uint16_t b3 :1;
	uint16_t b4 :5;
	uint8_t e;
}*Info;

uint8_t block[11];

	Info firmware = (Info)block;
	uint8_t a = firmware->a;

или даже 

	Info firmware = (Info)0x200001D4;
	uint8_t a = firmware->a;
	uint8_t b = firmware->b;

и тогда:

 2024-07-26201740.jpg.598c7b181c64bcb075fc4f0461a7f021.jpg

то есть, на скриншоте видно, что тип указателя на структуру просто "натягивается" на последовательно расположенные байты с любого адреса, и эта область памяти без лишних телодвижений разбивается на поля структуры, при этом доступ к полям осуществляется через -> 

Изменено пользователем EdgeAligned

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, EdgeAligned said:

То есть, вот о чем я говорил:

typedef struct {
	uint8_t a;
	uint8_t b;
	uint16_t c;
	uint32_t d;
	uint16_t b1 :4;
	uint16_t b2 :2;
	uint16_t b3 :1;
	uint16_t b4 :5;
	uint8_t e;
}*Info;

uint8_t block[11];

	Info firmware = (Info)block;
	uint8_t a = firmware->a;

или даже 

	Info firmware = (Info)0x200001D4;
	uint8_t a = firmware->a;
	uint8_t b = firmware->b;

и тогда:

 2024-07-26200830.jpg.719f4c92607ae2c059473da26bb7ee65.jpg

то есть, на скриншоте видно, что тип указателя на структуру просто "натягивается" на последовательно расположенные байты с любого адреса, и эта область памяти без лишних телодвижений разбивается на поля структуры, при этом доступ к полям осуществляется через -> 

Ни чё себе ! А что, так можно было ?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 26.07.2024 в 09:24, tonyk_av сказал:

Опять то же самое, размещение данных в памяти по нужным адресам. Вроде, неделю назад обсуждали, и ссылки на доки Кейла был, где всё это описаны и показаны примеры.

У меня как-то не правильно/не оптимально или еще как-то размещено? Рискуя снова быть закиданным тапками: изучил темы в этой ветке форума до конца июня, но не увидел что-то похожее. Если с моим размещением что-то не так скажите, сам нагуглю.

 

В 26.07.2024 в 14:11, EdgeAligned сказал:

Назначение ф-ции DeserializeSystemData я, если честно, не понял и не стал принимать во внимание. Потому что, как я ранее писал, достаточно указателя на структуру, который "одевается" как разметочный шаблон поверх любой области памяти, и она становится отформатированной как раз по разметке в структуре, с доступом к полям через ptr->xxx, как это сделано в том же GPIO->ODR

Не реально полезно, попробую реализовать.

  

В 26.07.2024 в 12:45, EdgeAligned сказал:

Лично я бы не делал отдельной фукнции под названием

Не получиться, там есть свои особенности. Но как совет я понял, стремиться к универсальности, возьму на вооружение.

 

Чтобы функция из первого сообщения заработала я добавил мониторинг флага окончания чтения. Флаг внешний и устанавливается в колбеке, поэтому его постоянного надо таскать за собой через extern во все модули/библиотеки где это требуется. Возможно ли этот момент оптимизировать, в плане- не использовать глобальную переменную в функции, например, как у меня?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/31/2024 at 12:31 PM, Turgenev said:

Чтобы функция из первого сообщения заработала я добавил мониторинг флага окончания чтения. Флаг внешний и устанавливается в колбеке, поэтому его постоянного надо таскать за собой через extern во все модули/библиотеки где это требуется. Возможно ли этот момент оптимизировать, в плане- не использовать глобальную переменную в функции, например, как у меня?

Сделайте обращение к этой переменной через функцию, а не напрямую.
 

uint32_t tx_complete;

uint32_t is_tx_complete(void)
{
  return tx_complete;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так ведь не нужен программный флаг, коль есть флаг аппаратный! 🙂 В DMA же флаги для того и прикручены. Перед началом работы по DMA сбрасываем все флаги в используемом потоке и запускаем DMA. Когда DMA отработает всё, он выставит флаг Transfer Complete (TCIF). Этот флаг можно либо ожидать в цикле while, либо включить прерывание по этому событию. Но поскольку у вас алгоритм построен на ожидании, то можно использовать while TCIF

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 31.07.2024 в 17:06, EdgeAligned сказал:

Этот флаг можно либо ожидать в цикле while

Возьму на вооружение, но когда подучу LL. А пока перевел все флаги, устанавливаемые в колбэках на сеттеры и геттеры.

 

Понравилась идея с упрощением перевода массива в структуру. Захотелось сделать также обратную операцию: поля структуры записать в массив по указателю. Есть тема, где подобное обсуждалось:

Спойлер

 

Я сделал следующим образом:

Спойлер
typedef struct
{
  uint32_t start_address;
  uint32_t stop_address;
  uint8_t last_pack_size;
  uint8_t isActive;
  uint8_t isDataRecorded;
} __attribute__((packed)) FirmwareInfo_t;

typedef struct
{
  FirmwareInfo_t Firmware_info_1;
  FirmwareInfo_t Firmware_info_2;
  uint32_t checksum_CRC32;
} __attribute__((packed)) CommonFirmwareInfo_t;

...

  /// - копия массива для переворачивания 4 байтных полей;
  CommonFirmwareInfo_t localFirmwareInfoPtr = *FirmwareInfoPtr;

  /// - переворачивание 4 байтных полей;
  localFirmwareInfoPtr.Firmware_info_1.start_address = ntohl(localFirmwareInfoPtr.Firmware_info_1.start_address);
  localFirmwareInfoPtr.Firmware_info_1.stop_address = ntohl(localFirmwareInfoPtr.Firmware_info_1.stop_address);
  localFirmwareInfoPtr.Firmware_info_2.start_address = ntohl(localFirmwareInfoPtr.Firmware_info_2.start_address);
  localFirmwareInfoPtr.Firmware_info_2.stop_address = ntohl(localFirmwareInfoPtr.Firmware_info_2.stop_address);

  /// - копирование полей структуры в массив для отправки по QSPI;
  memcpy(pArrayTX_dataQSPI, &localFirmwareInfoPtr, sizeof(CommonFirmwareInfo_t)-sizeof(uint32_t));

 

Если не использовать обращение порядка байт (ntohl), то записывает 32-битные поля структуры в массив в обратном порядке. А в виде, представленном в спойлере все работает четко. 

Есть ли способ обойти этот разворот, чтобы не использовать переворачивание всех не однобайтных полей структуры?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/7/2024 at 3:33 PM, Turgenev said:

Если не использовать обращение порядка байт (ntohl), то записывает 32-битные поля структуры в массив в обратном порядке. А в виде, представленном в спойлере все работает четко. 

Есть ли способ обойти этот разворот, чтобы не использовать переворачивание всех не однобайтных полей структуры?

Какая разница в каком порядке у вас хранятся данные в памяти ?

И как вы определили какой порядок у вас прямой, а какой обратный ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 минут назад, dimka76 сказал:

Какая разница в каком порядке у вас хранятся данные в памяти ?

Да фундаментальная. Адрес в памяти 4х байтный, если его запомнить наоборот, то считаешь совсем из другого адреса, в какой-то момент все равно придется крутить байты адреса, если их записать в обратном порядке. 

45 минут назад, dimka76 сказал:

И как вы определили какой порядок у вас прямой, а какой обратный ?

Записываю число в uint32_t слева направо без проблем (например 0x01FD3400), адрес тот, который нужен. Распихиваю uint32_t по 4м байтам, начинает с конца (т.е. 0х0034FD01). Считываю в том же не правильном порядке. Я понимаю, что в цифровой технике это прямой порядок- брать по 8 бит начиная справа (LSB) 32х битной переменной. Но работать с прогой человеку и хочется продолжить записывать слева направо.

Изменено пользователем Turgenev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/7/2024 at 4:58 PM, Turgenev said:

Да фундаментальная. Адрес в памяти 4х байтный, если его запомнить наоборот, то считаешь совсем из другого адреса, в какой-то момент все равно придется крутить байты адреса, если их записать в обратном порядке. 

Компилятор все правильно вам разместил в памяти, а не наоборот. И это вы пытаетесь сделать наоборот. 

On 8/7/2024 at 4:58 PM, Turgenev said:

Но работать с прогой человеку и хочется продолжить записывать слева направо.

Например в окне отладчика вам будет представлено в удобном для человека виде.

Если смотреть не в отладчике, то для этого существуют средства преобразования двоичных чисел в их текстовое представление.

Например, функция printf.

On 8/7/2024 at 5:50 PM, x893 said:

Берёте версию для арабов или евреев. У них справа налево.

Еще можно взять версию для китайцев, чтобы сверху вниз смотреть :sarcastic:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, dimka76 сказал:

Например в окне отладчика вам будет представлено в удобном для человека виде.

Если смотреть не в отладчике, то для этого существуют средства преобразования двоичных чисел в их текстовое представление.

Да, разобрался. Похоже, что просто считываю не верно- старым способом, со сдвигами и тд, а надо также через указатель. Поэтому в переменную uint32_t записывается наоборот.

 

За шутки спасибо, хохмачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

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