PolarFire® SoC FreeRTOS demo 分析

PolarFire-SoC 

https://github.com/polarfire-soc/polarfire-soc-bare-metal-examples

 

demo 说明文档:polarfire-soc-bare-metal-examples/driver-examples/mss/mss-ethernet-mac/mpfs-uart-mac-freertos_lwip at main · 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.)

  

image

 

 

二、头文件包含路径:确认 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 );
}

 

posted on 2025-09-08 11:51  所长  阅读(11)  评论(0)    收藏  举报

导航