PolarFire® SoC FreeRTOS demo 分析
https://github.com/polarfire-soc/polarfire-soc-bare-metal-examples
软件环境: Microchip SoftConsole v2022.2-RISC-V-747
硬件环境:microchip.com/en-us/development-tool/mpfs-icicle-kit
一、工程激活选项卡:DDR-Release-lcicle-Kit (Runs in DDR, loaded by a previous stage program.)

二、头文件包含路径:确认 mss_sw_config.h 文件位置
"${workspace_loc:/${ProjName}/src/middleware/support}" "${workspace_loc:/${ProjName}/src/boards/icicle-kit-es/platform_config_ddr}" "${workspace_loc:/${ProjName}/src/boards/icicle-kit-es}" "${workspace_loc:/${ProjName}/src/middleware/lwip-2.0.0-wip}" "${workspace_loc:/${ProjName}/src/middleware/lwip-2.0.0-wip/include}" "${workspace_loc:/${ProjName}/src/middleware/lwip-2.0.0-wip/port/FreeRTOS/M2SXXX}" "${workspace_loc:/${ProjName}/src/middleware/FreeRTOS/include}" "${workspace_loc:/${ProjName}/src/middleware/FreeRTOS/portable/GCC/RISCV}" "${workspace_loc:/${ProjName}/src/middleware/vtss_api_lite_v1_02/include}" "${workspace_loc:/${ProjName}/src/application}" "${workspace_loc:/${ProjName}/src/middleware/config}" "${workspace_loc:/${ProjName}/src/middleware}" "${workspace_loc:/${ProjName}/src/platform}" "${workspace_loc:/${ProjName}/src/middleware/vtss_api_lite_v1_02/phy_1g/common}"
根据 #include "mpfs_hal_config/mss_sw_config.h" 以及 上面头文件路径
mss_sw_config.h 的位置在 /src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h ;
三、/src/platform/mpfs_hal/startup_gcc/system_startup.c 启动文件 分析
由于 mss_sw_config.h 定义, IMAGE_LOADED_BY_BOOTLOADER = 1, main_first_hart_app 函数 214行
也就是说 , DDR 没有初始化,该工程不能直接 从 softconsole JTAG 仿真调试, demo 文档 说明如下:
Debug the application in DDR Load MPFS HAL ddr demo project to eNVM as above.
// 先 将 MPFS HAL ddr demo project 下的可执行文件,烧录到 eNVM ,
Load binary file using oprion 6 as above.
// 然后使用 "mpfs-uart-mac-freertos-lwip-DDR-Release" debug 即可
Connect using "mpfs-uart-mac-freertos-lwip-DDR-Release" debug configuration Add any break-point you desire.
e.g. Add one here "U54_1" Press resume button on the debugger Press option 7 on UART0.
The program should halt at your added break-point.
四、main_first_hart_app() 跳转 main_other_hart() 然后跳转到 e51() 运行 , 跳转到 free_rtos 函数
/** * free_rtos(void) * start freeRTOS * will never return */ void free_rtos(void) { BaseType_t rtos_result; volatile int ix; rtos_result = xTaskCreate(e51_task, "e51", 4000, NULL, uartPRIMARY_PRIORITY, NULL); if (1 != rtos_result) { int ix; for (;;) ix++; } rtos_result = xTaskCreate(blinky_task, "e51-2nd", 4000, NULL, uartPRIMARY_PRIORITY + 2, &thandle_blinky); if (1 != rtos_result) { int ix; for (;;) ix++; } rtos_result = xTaskCreate(http_server_netconn_thread, (char *)"http_server", 4000, NULL, uartPRIMARY_PRIORITY + 3, &thandle_web); if (1 != rtos_result) { int ix; for (;;) ix++; } /* Create the task the Ethernet link status. */ rtos_result = xTaskCreate(prvLinkStatusTask, (char *)"EthLinkStatus", 4000, NULL, uartPRIMARY_PRIORITY + 1, &thandle_link);
if (1 != rtos_result) { int ix; for (;;) ix++; } vTaskSuspend(thandle_blinky); vTaskSuspend(thandle_link); vTaskSuspend(thandle_web); /* Start the kernel. From here on, only tasks and interrupts will run. */ vTaskStartScheduler(); }
五、vTaskStartScheduler → xPortStartScheduler
/*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0;
/* Start the first task. */
vPortStartFirstTask();
/* Should not get here! */
return 0;
}
六、prvSetupTimerInterrupt 定时器初始化
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency.
*/
void prvSetupTimerInterrupt( void )
{
/* Try to register the interrupt handler. */
// 注册 定时器中断回调函数
if ( -EINVAL == alt_irq_register( SYS_CLK_IRQ, 0x0, vPortSysTickHandler ) )
{
/* Failed to install the Interrupt Handler. */
asm( "break" );
}
else
{
/* Configure SysTick to interrupt at the requested rate. */
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK );
IOWR_ALTERA_AVALON_TIMER_PERIODL( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) & 0xFFFF );
IOWR_ALTERA_AVALON_TIMER_PERIODH( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) >> 16 );
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_CONT_MSK | ALTERA_AVALON_TIMER_CONTROL_START_MSK | ALTERA_AVALON_TIMER_CONTROL_ITO_MSK );
}
/* Clear any already pending interrupts generated by the Timer. */
IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );
}
浙公网安备 33010602011771号