Turgenev 1 25 июля Опубликовано 25 июля (изменено) · Жалоба Есть данные в флеш-памяти, хочу считать их и распихать по полям глобально объявленного экземпляра структуры. Написал для этого функцию, которую вызываю вот так: __attribute__((at(0x20000100))) uint8_t rx_data_QSPI[FLASH_PROGRAM_SIZE]; ReadFirmwareInfo(&hqspi, rx_data_QSPI, sizeof(rx_data_QSPI), &CommonFirmwareInfo); Реализация функции: Спойлер uint8_t ReadFirmwareInfo(QSPI_HandleTypeDef *h_FLASHqspi, uint8_t *pArrayRX_dataQSPI, uint32_t bufQSPI_size, CommonFirmwareInfo_t *FirmwareInfoPtr) { memset(pArrayRX_dataQSPI, 0xFF, bufQSPI_size); /// - обнуление массива, в который читается информация по QSPI; /// - чтение информации о прошивках из микросхемы флеш-памяти; int32_t res = MT25QL512ABB_ReadSTR_DMA(h_FLASHqspi, MT25QL512ABB_QPI_MODE, MT25QL512ABB_4BYTES_SIZE, pArrayRX_dataQSPI, START_ADDR_FIRMWARE_INFO, bufQSPI_size); /// - проверка результата чтения из флеш-памяти; if (res == MT25QL512ABB_ERROR) { return ERROR_READ_FIRMWARE_INFO; } /* ЗАКОММЕНТИРОВАНО!!! */ //uint8_t locbufQSPI[bufQSPI_size]; //memset(locbufQSPI, 0xFF, sizeof(locbufQSPI)); /// - обнуление массива, в который читается информация по QSPI; //memcpy(locbufQSPI, pArrayRX_dataQSPI, bufQSPI_size); /// - заполнения структуры с информацией о прошивках из прочитанного массива; uint8_t res_des = DeserializeSystemData(pArrayRX_dataQSPI, bufQSPI_size, FirmwareInfoPtr); /// - проверка КС дес. массива; if (res_des != true) { return ERROR_READ_FIRMWARE_INFO; } return SUCCESSFUL_READ_FIRMWARE_INFO; } static uint8_t DeserializeSystemData (const uint8_t *localbuf, uint32_t bufQSPI_size, CommonFirmwareInfo_t *FirmwareInfoPtr) { uint16_t Index = 0; /// - определение переменной Index, которая является индексом десериализуемого массива; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+0] << 24) & 0xFF000000; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+1] << 16) & 0xFF0000; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+2] << 8) & 0xFF00; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+3] << 0) & 0xFF; Index += sizeof(FirmwareInfoPtr->Firmware_info_1.start_address); FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+0] << 24) & 0xFF000000; FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+1] << 16) & 0xFF0000; FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+2] << 8) & 0xFF00; FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+3] << 0) & 0xFF; Index += sizeof(FirmwareInfoPtr->Firmware_info_1.stop_address); FirmwareInfoPtr->Firmware_info_1.last_pack_size = localbuf[Index]; Index += sizeof(FirmwareInfoPtr->Firmware_info_1.last_pack_size); // И ТАК ДАЛЕЕ } В таком виде функция заполнит экземпляр структуры не полностью: Спойлер Но если пройти пошагово в отладчике по этой функции или поставить точку останова сразу после строчки int32_t res = MT25QL512ABB_ReadSTR_DMA..., а потом продолжить выполнение или раскомментировать 3 строчки после /* ЗАКОММЕНТИРОВАНО!!! */, то заполняется правильно (видно инкремент во всех полях): Спойлер Не могу понять в чем дело, указатель на массив вроде передал правильно (смотрел примеры на этом форуме), читает данные из памяти в массив rx_data_QSPI всегда правильно. Не посоветуете в чем тут может быть дело? Буду признателен за любые советы и критику (за конструктивную так особенно). Изменено 25 июля пользователем Turgenev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 82 25 июля Опубликовано 25 июля · Жалоба Для чтения используете DMA? Ттгда он просто не успевает передать данные 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 25 июля Опубликовано 25 июля · Жалоба 25 minutes ago, EdgeAligned said: Для чтения используете DMA? Ттгда он просто не успевает передать данные Точно И не видно callback по завершению DMA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 25 июля Опубликовано 25 июля · Жалоба Зачем здесь вообще DMA, если все равно ждать окончания передачи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 25 июля Опубликовано 25 июля · Жалоба 5 minutes ago, Allregia said: Зачем здесь вообще DMA, если все равно ждать окончания передачи? Какая разница зачем. Захотел и сделал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 82 25 июля Опубликовано 25 июля (изменено) · Жалоба Самое смешное (удивительное и чудесное), что эту "информацию о прошивках" можно не перекопировать в SRAM, а читать прямо из флеша. Это ведь константные данные, так ведь? Ну так и пусть они остаются в неизменяемой части, во флеше. И сделать УКАЗАТЕЛЬ на структуру, который накладывается на заданную область памяти, как ящик-шаблон, и эта область делится на "отсеки", как прописано в структуре. Таким образом, хранится только указатель типа "структура", этому указателю присваиваем адрес начала блока с данными, и производим вычитывание данных по указателю на структуру через ptr->xxx. Это работает аналогично тому, как сделано с GPIOA->ODR. Пардон, забыл, что флеш-то - внешняя, через SPI! 🙂 Сорян, тогда коммент отменяется (считать недействительным) Изменено 25 июля пользователем EdgeAligned Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 25 июля Опубликовано 25 июля · Жалоба 6 часов назад, Turgenev сказал: Скрыть контент FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+0] << 24) & 0xFF000000; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+1] << 16) & 0xFF0000; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+2] << 8) & 0xFF00; FirmwareInfoPtr->Firmware_info_1.start_address |= (localbuf[Index+3] << 0) & 0xFF; Index += sizeof(FirmwareInfoPtr->Firmware_info_1.start_address); FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+0] << 24) & 0xFF000000; FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+1] << 16) & 0xFF0000; FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+2] << 8) & 0xFF00; FirmwareInfoPtr->Firmware_info_1.stop_address |= (localbuf[Index+3] << 0) & 0xFF; Index += sizeof(FirmwareInfoPtr->Firmware_info_1.stop_address); Ужас конечно. Кровь из глаз... Понимаю теперь почему современные программы имеют такие невменяемые размеры..... ТС, ваш CPU умеет команду REV! Советую наконец-то открыть и почитать мануал на ваш процессор. И на кой интересно rx_data_QSPI прибит гвоздями к абсолютному адресу?? 4 часа назад, EdgeAligned сказал: Для чтения используете DMA? Ттгда он просто не успевает передать данные Посещали курсы телепатов? Или вы телепат-любитель? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 25 июля Опубликовано 25 июля · Жалоба 3 часа назад, EdgeAligned сказал: Для чтения используете DMA? Ттгда он просто не успевает передать данные Да, вы правы, забыл его мониторить при выполнении функции, хотя колбек и флаги заведены. 10 минут назад, jcxz сказал: Ужас конечно. Кровь из глаз... Претензии только к размеру? Про REV обязательно почитаю. 11 минут назад, jcxz сказал: И на кой интересно rx_data_QSPI прибит гвоздями к абсолютному адресу?? В проекте есть еще SPI DMA, который не работает , если линковщик все разместит в DTCM и наоборот: MDMA не заработает, если все разместить в AXI SRAM. В примере моего кода есть функция DeserializeSystemData. Она раскладывает значения массива по полям экземпляра структуры шагая по адресам, где находится массив. Если выполнять обратную операцию, укладывая значения экземпляра структуры в массив, который создается в этой функции сериализации, размером, также переданным в функцию, то как компилятор понимает сколько памяти выделить массиву, если его размер не известен, пока не вызовется функция? Просто ошибок компилятор не выдает и позволяет так сделать, но результат не понятный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 82 25 июля Опубликовано 25 июля · Жалоба 58 минут назад, jcxz сказал: Понимаю теперь почему современные программы имеют такие невменяемые размеры..... Эт верно! 🙂 На смартфоне установлены только самые необходимые приложения, и они занимают нынче аж 28 ГБ! Чем больше памяти у смартфонов, тем больше места занимают ровно те же самые приложения, которые раньше весили гораздо меньше. 1 час назад, jcxz сказал: Посещали курсы телепатов? Или вы телепат-любитель? Неее, я просто вспоминаю свои косяки, всякое случалось. Но я подключал лог.анализатор, рылся в мануалах. 48 минут назад, Turgenev сказал: если линковщик все разместит в DTCM и наоборот: Верно. DTCM - data tightly coupled memomy, область памяти для наикратчайшего и быстрого доступа со стороны ядра. Обычно эту область используют для текущих быстрых вычислений, а не для хранения редкоиспользуемых данных. Но линковщику можно указывать не жесткий адрес, а секции памяти, которые были созданы в ld-скрипте. И при размещении переменной указывается секция через __attribute__((section("Xxxx"))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 42 26 июля Опубликовано 26 июля · Жалоба 15 hours ago, Turgenev said: В проекте есть еще SPI DMA, который не работает , если линковщик все разместит в DTCM и наоборот: MDMA не заработает, если все разместить в AXI SRAM. Опять то же самое, размещение данных в памяти по нужным адресам. Вроде, неделю назад обсуждали, и ссылки на доки Кейла был, где всё это описаны и показаны примеры. 14 hours ago, EdgeAligned said: секции памяти, которые были созданы в ld-скрипте. У ТС Кейл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 26 июля Опубликовано 26 июля · Жалоба 52 minutes ago, tonyk_av said: Вроде, неделю назад обсуждали, и ссылки на доки Кейла был, где всё это описаны и показаны примеры. Рыбки гуппи помнят 1 день только Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 26 июля Опубликовано 26 июля · Жалоба 16 часов назад, Turgenev сказал: Претензии только к размеру? Про REV обязательно почитаю. Почти к каждой строчке. Вы разве сами не замечаете, что там понаписали? Начиная от: memset(pArrayRX_dataQSPI, 0xFF, bufQSPI_size); /// - обнуление массива, в который читается информация по QSPI; Зачем вообще какое-то "обнуление"? Почему ложь в комменте? Также на кой задавать такие вопросы и не выкладывать описание ВСЕХ используемых типов данных и функций? И описание начальных значений переменных, с которыми что-то делаете в коде? Вы здесь телепатов ищете, которые должны всё это угадать? Смотрите на свой пост и на каждой строчке пробуйте включать мозг. 16 часов назад, Turgenev сказал: В проекте есть еще SPI DMA, который не работает , если линковщик все разместит в DTCM и наоборот: MDMA не заработает, если все разместить в AXI SRAM. И что? Вопросы про компоновку в заданные адреса тут обсасывались уже многократно. И в очередной раз - совсем недавно. Попробуйте быть не только "чукчей-писателем". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 26 июля Опубликовано 26 июля · Жалоба 11 minutes ago, jcxz said: Вы разве сами не замечаете, что там понаписали? Не волнуйтесь. Мало ли говнокода на планете Земля. Одним больше, одним меньше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 82 26 июля Опубликовано 26 июля · Жалоба Раньше это называлось "индусский код", который, согласно преданию, нужно было петь и танцевать, и чем больше строчек кода, тем длиннее индийский сериал 🙂 Лично я бы не делал отдельной фукнции под названием "ReadFirmwareInfo()", поскольку по смыслу она равносильна универсальной функции, выполняющей чтение из внешней флеши из указанного адреса в указанный адрес SRAM. Поэтому, здесь должна быть универсальная функция чтения ReadFromExtFlash(source_address, destination_address, size), как бы вот и всё. То есть, не делать индусского кода. (что такое индусский код, можно загуглить в википедии). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 82 26 июля Опубликовано 26 июля · Жалоба Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться