Jump to content

    

UniSoft

Свой
  • Content Count

    95
  • Joined

  • Last visited

Community Reputation

0 Обычный

About UniSoft

  • Rank
    Частый гость
  • Birthday 08/02/1979

Контакты

  • Сайт
    http://
  • ICQ
    345012614
  • Yahoo
    uniskz

Информация

  • Город
    China, Shenzhen

Recent Profile Visitors

12722 profile views
  1. Мой выбор остановился на: Visual Studio 2015 + Visual Assist X + VisualGDB + TabsStudio VS конечно очень тяжелая, но если комп тянет, то можно пользоваться... VisualGDB позволяет создавать проекты и (с недавнего времени) поддерживает компилятор Keil, можно в нем же собирать и отлаживать (использую JLink), в плагине также есть опция RAW Terminal, которую можно заюзать для приема ITM сообщений. Лучшего пока что ничего не видел :(
  2. Tracealyzer для FreeRTOS

    Версия 4.2.12... поддерживает следующие RTOS: FreeRTOS SafeRTOS Keil RTX5 Micrium µC/OS-III On Time RTOS-32 OpenVX/Synopsys VxWorks ThreadX Взять можно пройдя по той-же ссылке (на rgho.st), в описании ссылка на 4.2.12 (ну или в ПМ, либо на email)
  3. STM32F722 и Cache Coherency

    Интересное объяснение. И что-то в этом есть... но ведь стартап и инициализация памяти выполняется до входа в main, а D-кэш включается именно в начале main.
  4. STM32F722 и Cache Coherency

    Всем спасибо, проблему решил. Избавился полностью от HAL, надергал функции в свой файл, что-то убрал, что-то оптимизировал, в общем весь драйвер получился в одном файле. Сначала правда тоже не работало, но как только раскомментировал очистку кэша до чтения (которую ранее пробовал и закомментировал, так как не помогало), так сразу все и заработало. Так что @GenaSPB был прав, нужна очистка кэша до вызова процедуры чтения, хоть и выглядит это совершенно нелогично. Как только ее убираю, перестает работать. И почему об этот нет никакого упоминания в примерах, а код частично брался как раз из них (с самого последнего - STM32Cube_FW_F7_V1.15.0), и там еще есть косяки ну например, найдите ошибку timer = osKernelSysTick() + SD_TIMEOUT; /* block until SDIO IP is ready or a timeout occur */ while(timer > osKernelSysTick()) { if (BSP_SD_GetCardState() == SD_TRANSFER_OK) { res = RES_OK; break; } } Ну во первых так писать категорически нельзя (хотя и довольно часто такое видел, и в HAL такое тоже есть) ведь при "osKernelSysTick() + SD_TIMEOUT" возможно переполнение.. ну да ладно, косяк не в этом, а в osKernelSysTick(), в дебрях RTX5 это: #define osKernelSysTick osKernelGetSysTimerCount И функция osKernelGetSysTimerCount() возвращает далеко не SysTick и не время в миллисекундах, а как видно по имени скорее время в тактах SysTick таймера, а вот SD_TIMEOUT время в миллисекундах, таким образом этот цикл в моем случае крутился менее 1/20 ms.
  5. STM32F722 и Cache Coherency

    Посмотрел, к сожалению, ничего нового не увидел. Единственное, что очистка кэша до чтения... хотя я это и не понимаю, но как уже сказал, такой вариант пробовал... не помогло. А на счет идеально работающий, это еще не факт... ради интереса, разместите буфер куда-нибудь за пределы DTCM... ну, например вот так: #define __AT(__ADDR) __attribute__((section(".ARM.__at_" #__ADDR))) #define AT_ADDR(__ADDR) __AT(__ADDR) AT_ADDR(0x20010200) static RAMNOINIT_D1 FATFS wave_Fatfs;
  6. STM32F722 и Cache Coherency

    Да это как-то странно, распределять буферы... А если это локальные буферы? ну там прочитать заголовок файла... можно конечно двойную буферизацию, но пока ищу нормальное решение. А атрибуты памяти выкурил все в корень, все перепробовал и CACHEABLE и NOT_CACHEABLE, SHAREABLE и NOT_SHAREABLE, LL_MPU_REGION_NUMBER0 и LL_MPU_REGION_NUMBER1 (в разных примерах по разному) при некоторых валится в HardFault, при других ничего не меняется. Прежде чем сюда написать, перепробовал все, что только мог. Перерыл множество примеров.
  7. STM32F722 и Cache Coherency

    Да смотрел, а что толку... Я честно говоря, не понимаю зачем нужно делать CleanInvalidate до чтения, но (читал обсуждение) и видел в исходниках https://github.com/micropython/micropython/blob/86f06d6a874d4eb3d6c50deec0240942344c01ea/ports/stm32/sdcard.c И тоже пробовал ставить очистку еще и до чтения, но результата это не дало...
  8. STM32F722 и Cache Coherency

    не сразу уловил, про какое значение говорите... Определен верно, в коде все присутствует (смотрел в дизассемблере).
  9. STM32F722 и Cache Coherency

    Оно установлено верно. Я уже тоже засомневался, и не только по этому дефайну, а еще и по __DCACHE_PRESENT (что используется в SCB_CleanDCache_by_Addr()) Посмотрел в дизассемблере, все с этим ок
  10. STM32F722 и Cache Coherency

    Этот контроллер мне уже весь мозг вынес... Что ему блин нужно? Может кто подскажет что-то дельное... Итак, контроллер STM32F722... + FatFs... проблема в чтении SD, а точнее в DMA и кэше, не хотят они никак дружить. Все работало... проект рос... и хрясь с того ни с сего и больше не работает... Со временем выяснилось, что перестало работать как только буферы оказались в SRAM1 (ну т.е. выше 0x20010000)... Данные просто повреждены и все. И это реально взрыв мозга, вроде все правильно но не работает, и в то же время работает при определенных условиях, откуда же я мог догадаться, что проблема именно в кэше, в коде ведь есть очистка но она видимо не работает, из-за этого перебрал весь код. Итак, что помогает: 1. выключение (а точнее не включение) DCache... (Но это как-то не правильно) 2. Размещение буферов в области DTCM... (Не распределять же мне теперь вручную все буферы, (от)куда идут данные) 3. Возможно поможет переход на IT вместо DMA (пока не пробовал) Так вот кто-нибудь может что-то порекомендовать? Может уже решали подобную задачу? Вот функции чтения и записи //---------------------------------------------------------------------------- //! @brief Reads block(s) from a specified address in a card. The Data transfer //! is managed by DMA mode. //! @param pData : Pointer to the buffer that will contain the received data //! @param BlockAdd : Block Address from where data is to be read //! @param NumOfBlocks : Number of blocks to read. //! @retval DRESULT: Operation result //---------------------------------------------------------------------------- static DRESULT sd_read(void *pData, uint32_t BlockAdd, uint32_t NumOfBlocks) { // Read block(s) in DMA transfer mode if (SD_ReadBlocks_DMA((uint32_t *)pData, BlockAdd, NumOfBlocks) == MSD_OK) { // Wait that the reading process is completed or a timeout occurs uint32_t flags = osEventFlagsWait(SDEventID, SD_READ_CPLT_MSG | SD_ERROR_MSG | SD_ABORT_MSG, osFlagsWaitAny, SD_TIMEOUT); if ((flags & (osFlagsError | SD_READ_CPLT_MSG)) == SD_READ_CPLT_MSG) { // block until SDIO IP is ready or a timeout occur uint32_t tc = osKernelSysTick(); do { if (SD_GetCardState() == SD_CARD_TRANSFER) { #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) // the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address, // adjust the address and the D-Cache size to invalidate accordingly. uint32_t alignedAddr = (uint32_t)pData & ~0x1FUL; SCB_InvalidateDCache_by_Addr((uint32_t *)alignedAddr, NumOfBlocks * SD_BLOCKSIZE + ((uint32_t)pData - alignedAddr)); #endif return RES_OK; } } while ((osKernelSysTick() - tc) < SD_TIMEOUT); } } return RES_ERROR; } //---------------------------------------------------------------------------- //! @brief Writes block(s) to a specified address in a card. The Data transfer //! is managed by DMA mode. //! @param pData : Pointer to the buffer that will contain the data to transmit //! @param BlockAdd : Block Address where data will be written //! @param NumOfBlocks : Number of blocks to write //! @retval DRESULT: Operation status //---------------------------------------------------------------------------- static DRESULT sd_write(const void *pData, uint32_t BlockAdd, uint32_t NumOfBlocks) { #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) // Invalidate the chache before writting into the buffer. // This is not needed if the memory region is configured as W/T. uint32_t alignedAddr = (uint32_t)pData & ~0x1FUL; //SCB_InvalidateDCache_by_Addr((uint32_t *)alignedAddr, NumOfBlocks * SD_BLOCKSIZE + ((uint32_t)pData - alignedAddr)); SCB_CleanDCache_by_Addr((uint32_t *)alignedAddr, NumOfBlocks * SD_BLOCKSIZE + ((uint32_t)pData - alignedAddr)); #endif // Write block(s) in DMA transfer mode if (SD_WriteBlocks_DMA((uint32_t *)pData, BlockAdd, NumOfBlocks) == MSD_OK) { // wait until the read operation is finished uint32_t flags = osEventFlagsWait(SDEventID, SD_WRITE_CPLT_MSG | SD_ERROR_MSG | SD_ABORT_MSG, osFlagsWaitAny, SD_TIMEOUT); if ((flags & (osFlagsError | SD_WRITE_CPLT_MSG)) == SD_WRITE_CPLT_MSG) { // block until SDIO IP is ready or a timeout occur uint32_t tc = osKernelSysTick(); do { if (SD_GetCardState() == SD_CARD_TRANSFER) { return RES_OK; } } while ((osKernelSysTick() - tc) < SD_TIMEOUT); } } return RES_ERROR; } Пробовал Configure the MPU attributes as WT for SRAM но это не помогает //---------------------------------------------------------------------------- //! @brief Configure the MPU attributes as Write Through for SRAM1/2. //! @note The Base Address is 0x20010000 since this memory interface is the AXI. //! The Region Size is 256KB, it is related to SRAM1 and SRAM2 memory size. //! @param None //! @retval None //---------------------------------------------------------------------------- static void MPU_Config(void) { // Disable MPU LL_MPU_Disable(); // Configure the MPU attributes as WT for SRAM LL_MPU_ConfigRegion(LL_MPU_REGION_NUMBER1, 0x00, 0x20010000UL, LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | LL_MPU_ACCESS_NOT_BUFFERABLE | MPU_ACCESS_CACHEABLE | MPU_ACCESS_NOT_SHAREABLE | LL_MPU_TEX_LEVEL1 | LL_MPU_INSTRUCTION_ACCESS_ENABLE); // Enable MPU (any access not covered by any enabled region will cause a fault) LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT); }
  11. нужен свежий Keil

    самый крайний тут http://www2.keil.com/mdk5/527pre
  12. был весь, но возможно с того времени еще что-то добавили. Это не все условия. Там есть еще проверка некой константы, которая генерируется из серийного номера (следующий DWORD сразу за серийником), он должен быть либо соответствующим серийному номеру, либо просто 0xFFFFFFFF. В некоторых клонах (и у меня так было в v9.3) там было неверное значение. Насчет GDBFull найдите ее поиском и просто забейте 0xFF, (если она не последняя, просто остальные лицензии сместите).
  13. ну это вы сами решайте стоит или нет... тот же EDU стоит в два раза дороже, зато оригинал (ну и есть ограничения, которые можно обойти только перепрошивкой). 632i угрохает клон (по крайней мере те, которые я видел, только сегодня очередной загубил, сейчас буду восстанавливать), наверняка уже есть и другие клоны, где это исправили. у меня свой собственный патч прошивки. Но опять же нет никакой гарантии, что в дальнейшем и он не накроется... к счастью, всегда можно перепрошить. либо просто можно накатить прошивку с задранной датой (тут выше уже выкладывал комплект), тогда он просто больше никогда не попросит обновления по крайней мере до 2028 года :) Лично у меня есть и оригинал и клон, использую только клон (оригинал лежит на всякий случай, если вдруг после очередного обновления клон снова помрет, а времени пилить новый патч не будет)
  14. Tracealyzer для FreeRTOS

    RTT как раз у всех есть (SEGGER_RTT_printf()) это по сути обычный кольцевой буфер, который с некоторой периодичностью вычищается отладчиком. Я то думал там ITM используется, а нет (не пользуюсь FreeRTOS, я на RTX5). Заглянул в исходники (SEGGER_RTT_Conf.h), ну и как и предполагал #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) стоит не блокирующий режим. В этом режиме, если не достаточно места в буфере под сообщение целиком, то оно просто игнорируется. есть еще такие режимы SEGGER_RTT_MODE_NO_BLOCK_TRIM - просто обрезается все что не влазит. SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL - ждем освобождение буфера. попробуйте, может поможет. #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
  15. Tracealyzer для FreeRTOS

    может у вас проблема совсем в другом, может просто как-то не так данные в ITM отсылаете? ну скажем нет проверки на завершение предыдущей передачи... должно быть как-то так: /* ITM registers */ #define ITM_PORT0_U8 (*((volatile uint8_t *)0xE0000000)) #define ITM_PORT0_U32 (*((volatile uint32_t *)0xE0000000)) #define ITM_TER (*((volatile uint32_t *)0xE0000E00)) #define ITM_TCR (*((volatile uint32_t *)0xE0000E80)) #define ITM_TCR_ITMENA_Msk (1UL << 0) int32_t ITM_SendChar (int32_t ch) { if ((ITM_TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ (ITM_TER & (1UL << 0) )) { /* ITM Port #0 enabled */ while (ITM_PORT0_U32 == 0); /* wait for end of transmit previous character */ ITM_PORT0_U8 = (uint8_t)ch; } return (ch); }