VHEMaster 0 24 декабря, 2015 Опубликовано 24 декабря, 2015 (изменено) · Жалоба Доброго времени суток! Захотел сделать что-то в роде своего компьютера на STM32 со своей ОС, но не суть. Нужно написать загрузчик внешних программ (приложений) из внешнего накопителя, будь то SD карта или USB флешка. Проблема в том, что если грузить эти программы во внешнюю SDRAM, то внешнее приложение нифига не запускается, а если во внутреннюю ОЗУ (благо её у 429-го камня 192КБ) то всё работает отлично! Вот вывод терминала , когда всё работает с внутренней ОЗУ Hello from main! 0x0800E321 Insert Flash Flash detected A:/ File opened! size: 288 Loading...Done! 288/288 80 B5 82 B0 00 AF 78 60 39 60 7B 68 20 4A 13 60 1F 4B 1B 68 1F 48 00 21 98 47 00 F0 41 F8 00 F0 4B F8 1B 4B 1B 68 1C 4A 12 78 1C 48 01 21 98 47 19 4B 1B 78 01 33 DA B2 17 4B 1A 70 14 4B 1B 68 15 4A 12 78 15 48 01 21 98 47 13 4B 1B 78 01 33 DA B2 11 4B 1A 70 0E 4B 1B 68 0F 4A 12 78 0F 48 01 21 98 47 0C 4B 1B 78 01 33 DA B2 0A 4B 1A 70 07 4B 1B 68 08 4A 12 78 08 48 01 21 98 47 00 F0 0F F8 00 F0 19 F8 3B 68 18 46 08 37 BD 46 80 BD 00 00 02 20 D0 00 01 20 04 00 02 20 EC 00 01 20 80 B5 00 AF 02 4B 1B 68 02 48 00 21 98 47 80 BD 00 00 02 20 FC 00 01 20 80 B5 00 AF 02 4B 1B 68 02 48 00 21 98 47 80 BD 00 00 02 20 10 01 01 20 0A 0D 48 65 6C 6C 6F 20 66 72 6F 6D 20 74 65 73 74 20 70 72 6F 67 21 0A 0D 00 00 00 56 61 72 69 61 62 6C 65 20 3D 20 25 64 0A 0D 00 43 61 6C 6C 65 64 20 73 65 63 66 75 6E 63 0A 0D 00 00 00 00 43 61 6C 6C 65 64 20 74 68 66 75 6E 63 0A 0D 00 Executing ext. soft.. Hello from test prog! Called secfunc Called thfunc Variable = 54 Variable = 55 Variable = 56 Variable = 57 Called secfunc Called thfunc Done! Retvalue = 0x12345678 Вот код загрузчика #include "stm32f4xx_hal.h" #include "usb_host.h" #include "delay.h" #include "sdram.h" #include "uart.h" #include "fatfs_driver.h" FS_DriveInfoHand Drive; FS_PartInfoHand Part; FS_DirInfoHand Dir; FS_FileInfoHand File; uint32_t i; void SystemClock_Config(void); static void MX_GPIO_Init(void); void MX_USB_HOST_Process(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); DelayInit(); print_init(115200); print("Hello from main! 0x%08X ",1,(uint32_t)&main); MX_USB_HOST_Init(); SDRAM_Msp(); SDRAM_Init(); print("Insert Flash ",0); //ВОТ ТУТ МЕНЯЕМ АДРЕС, КУДА ПИСАТЬ ПРОГРАММУ!!! //0xC0000000 - это SDRAM //Нужно не забывать прописать соответствующие адреса в линкере внешней программы при компиляции volatile uint8_t * PROGRAMDATA = (volatile uint8_t *)(uint32_t)0x20010000; while (1) { MX_USB_HOST_Process(); while(MX_USB_HOST_State() == APPLICATION_READY) { print("Flash detected\n\r",0); if(f_driveinfo(&Drive, DEV_USB)) { print("DriveInfo error!",0); goto error; } if(f_mount(&Drive,&Part, 0)) { print("Mount error!",0); goto error; } if(f_dir(&Dir, "/")) { print("Disk List Error!",0); goto error; } for(i=0;i<Dir.Files;i++) print("%s\n\r",1,Dir.Name); if(f_open(&File,"A:/ExtSoft_CoIDE.bin",FS_READ)) { print("File Open Error!!",0); goto error; } print("File opened!\n\rsize: %d\n\rLoading...",1,File.Size); uint8_t Buffer[4096]; uint32_t BLOCK = 4096; uint32_t wrote = 0; while(f_eof(&File)) { if(File.Size-File.CurrentByte < BLOCK) BLOCK = File.Size-File.CurrentByte; if(f_read(&File, (uint8_t*)Buffer, BLOCK)) goto error; for(i=0;i<BLOCK;i++,wrote++) { PROGRAMDATA[wrote] = Buffer[i]; } } print("Done! %d/%d\n\r",2,File.CurrentByte,File.Size); for(i=0;i<File.Size;i++) { if(i%8 == 0) print(" ",0); if(i%16 == 0) print("\n\r",0); print("%02X ",1,PROGRAMDATA[i]); } uint32_t (*extprog)(uint32_t,uint32_t); uint32_t retvalue; extprog = (uint32_t(*)(uint32_t,uint32_t))(PROGRAMDATA+1); print("\n\rExecuting ext. soft.. \n\r",0); retvalue = (*extprog)((uint32_t)&print,0x12345678); print("\n\rDone! Retvalue = 0x%08X\n\r",1,retvalue); while(1); } } error: while(1); } /** System Clock Configuration */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; __PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 7; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 10; HAL_RCC_OscConfig(&RCC_OscInitStruct); HAL_PWREx_ActivateOverDrive(); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1 |RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); } void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ __GPIOH_CLK_ENABLE(); __GPIOA_CLK_ENABLE(); } Вот код внешней программы: #include "stm32f429xx.h" void secfunc(void); void thfunc(void); void (*print)(char*,uint32_t,...); uint8_t somevar2; uint32_t entry(uint32_t func, uint32_t var) { print = *((void(*)(char*,uint32_t,...))func); print("\n\rHello from test prog!\n\r",0); secfunc(); thfunc(); print("Variable = %d\n\r",1,somevar2); somevar2++; print("Variable = %d\n\r",1,somevar2); somevar2++; print("Variable = %d\n\r",1,somevar2); somevar2++; print("Variable = %d\n\r",1,somevar2); secfunc(); thfunc(); return var; } void secfunc(void) { print("Called secfunc\n\r",0); } void thfunc(void) { print("Called thfunc\n\r",0); } Сама SDRAM работает прекрасно, но если с неё грузить софт то на строчке "Executing ext. soft.. " всё прекращается. В чём может быть проблема?... Делал по этой статье http://we.easyelectronics.ru/STM32/stm32-i...h-programm.html Изменено 24 декабря, 2015 пользователем VHEMaster Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 декабря, 2015 Опубликовано 24 декабря, 2015 · Жалоба Подключите внутрисхемный отладчик и посмотрите, что там происходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VHEMaster 0 24 декабря, 2015 Опубликовано 24 декабря, 2015 (изменено) · Жалоба Подключите внутрисхемный отладчик и посмотрите, что там происходит. Что-то в роде STLINK? Я посмотрел, там вылетает Default_Handler. Комментарий к нему: * @brief This is the code that gets called when the processor receives an * unexpected interrupt. This simply enters an infinite loop, preserving * the system state for examination by a debugger. Что это может означать? UPD: почему-то нельзя просмотреть содержимое SDRAM через отладчик... Изменено 24 декабря, 2015 пользователем VHEMaster Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 24 декабря, 2015 Опубликовано 24 декабря, 2015 · Жалоба почему-то нельзя просмотреть содержимое SDRAM через отладчик... Это и есть ответ, сбой инициализации sdram. В нормальном состоянии вся область sdram прекрасно читается отладчиком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VHEMaster 0 25 декабря, 2015 Опубликовано 25 декабря, 2015 · Жалоба Это и есть ответ, сбой инициализации sdram. В нормальном состоянии вся область sdram прекрасно читается отладчиком. Перечитай, пожалуйста, моё первое сообщение. Написано, что SDRAM прекрасно работает! Я даже буфер для VGA монитора (LTDC) туда бросал. Всё отлично работало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 25 декабря, 2015 Опубликовано 25 декабря, 2015 · Жалоба Кстати, вы не забыли свериться с ерратой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VHEMaster 0 25 декабря, 2015 Опубликовано 25 декабря, 2015 · Жалоба Кстати, вы не забыли свериться с ерратой? Там ничего об этом нет. На самом деле решение оказалось смешным. Оказалось, что для банка SDRAM не поддерживается кэширование инструкций, если я правильно понял. По-этому нужно сделать ремап строчкой SYSCFG->MEMRMP |= 0x400; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 32 25 декабря, 2015 Опубликовано 25 декабря, 2015 (изменено) · Жалоба Оказалось, что для банка SDRAM не поддерживается кэширование инструкций В камне есть кэш?? Интересно, насколько тогда упало быстродействие? Изменено 25 декабря, 2015 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VHEMaster 0 25 декабря, 2015 Опубликовано 25 декабря, 2015 (изменено) · Жалоба В камне есть кэш?? Интересно, насколько тогда упало быстродействие? Возможно, я ошибся в плане кэша, ну да ладно. Об этом вычитал тут https://my.st.com/public/STe2ecommunities/m...urrentviews=881 Замеры ещё не делал. Сделаю - постараюсь сообщить) UPD: скорость исполнения кода из под SDRAM ниже чуть более чем в 6 раз, относительно скорости исполнения из внутренней флешки. В принципе, это не удивительно. И заодно сделал тест скорости исполнения кода из внутренней RAM контроллера. Она выше на 40% относительно флешки. UPD 2: В принципе, если нужна высокая производительность конкретного участка кода, то его как раз можно загрузить во внутреннюю ОЗУ, которая будет играть роль "кэша". Но для этого нужно написать свою ОС)) Изменено 25 декабря, 2015 пользователем VHEMaster Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться