简单尝试Milk-V Duo的小核运行FreeRTOS

转载自:https://mp.weixin.qq.com/s/CAW3ME9ZpIW8HItXseLPHQ ,原作者是: 电气电子小倒腾

简单尝试Milk-V Duo的小核运行FreeRTOS

好久没有更新了,昨天看到官方放出了小核运行FreeRTOS的SDK,刚好今天周末,git pull最新代码,简单试了一下。
一.如何添加RTOS任务代码?
首先简单的看了一下代码,SDK中FreeRTOS下有了civtek这个文件,直接打开task文件。里面有2个文件,1个common,1个main。打开main.c,其他不用看,发现了main_cvirtos(),这个就是freertos的入口函数了。

int main(void)
{
  pre_system_init();
  printf("CVIRTOS Build Date:%s  (Time :%s) \n", __DATE__, __TIME__);
#ifndef __riscv
  mmu_enable();
  printf("enable I/D cache & MMU done\n");
#endif
  /* Configure the hardware ready to run the demo. */
  prvSetupHardware();
#if ( configUSE_TRACE_FACILITY == 1 )
  vTraceEnable(TRC_START);
#endif
  post_system_init();

#ifdef CVIRTOS
  {
    main_cvirtos(); //入口函数
  }
#else
#error "Not correct running definition"
#endif

  /* Don't expect to reach here. */
  return 0;
}

那么main_cvirots()在哪里呢?继续点开common文件,找到了!路径在:task/comm/src/riscv64中。源码很简单:

void main_cvirtos(void)
{
  printf("create cvi task\n");
  /* Start the tasks and timer running. */
   那么在这里!这里!这里添加源码即可!
  /* If all is well, the scheduler will now be running, and the following
    line will never be reached.  If the following line does execute, then
    there was either insufficient FreeRTOS heap memory available for the idle
    and/or timer tasks to be created, or vTaskStartScheduler() was called from
    User mode.  See the memory management section on the FreeRTOS web site for
    more details on the FreeRTOS heap http://www.freertos.org/a00111.html.  The
    mode from which main() is called is set in the C start up code and must be
    a privileged mode (not user mode). */
  printf("cvi task end\n");

  for (;;)
    ;
}

后面我们就按FreeRTOS的API来创建任务吧!
二.简单尝试,来个FreeRTOS版本的helloworld!
这里因为官方已经uart0的驱动弄好了,直接printf即可。我修改以后的common_main.c如下:

/* Standard includes. */
#include <stdio.h>

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "mmio.h"
#include "delay.h"

/* cvitek includes. */
#include "printf.h"
#include "rtos_cmdqu.h"
#include "cvi_mailbox.h"
#include "intr_conf.h"
#include "top_reg.h"
#include "memmap.h"
#include "comm.h"
#include "cvi_spinlock.h"

//#define __DEBUG__

#ifdef __DEBUG__
#define debug_printf printf
#else
#define debug_printf(...)
#endif

/****************************************************************************
 * Function prototypes
 ****************************************************************************/
void my_task_test();
/****************************************************************************
 * Global parameters
 ****************************************************************************/

/* mailbox parameters */
volatile struct mailbox_set_register *mbox_reg;
volatile struct mailbox_done_register *mbox_done_reg;
volatile unsigned long *mailbox_context; // mailbox buffer context is 64 Bytess

/****************************************************************************
 * Function definitions
 ****************************************************************************/

DEFINE_CVI_SPINLOCK(mailbox_lock, SPIN_MBOX);

void main_cvirtos(void)
{
  printf("create cvi task\n");

  xTaskCreate(my_task_test, "my_task", 1024 * 8, NULL, 1, NULL);
  
  vTaskStartScheduler();

  /* Start the tasks and timer running. */

  /* If all is well, the scheduler will now be running, and the following
    line will never be reached.  If the following line does execute, then
    there was either insufficient FreeRTOS heap memory available for the idle
    and/or timer tasks to be created, or vTaskStartScheduler() was called from
    User mode.  See the memory management section on the FreeRTOS web site for
    more details on the FreeRTOS heap http://www.freertos.org/a00111.html.  The
    mode from which main() is called is set in the C start up code and must be
    a privileged mode (not user mode). */
  printf("cvi task end\n");

  for (;;)
    ;
}

void my_task_test()
{
  int index = 0;
  for (;;) {
    printf("test the RTOS: %d\r\n", index);
    vTaskDelay(100);
    index++;
  }
}

然后重新编译,连接串口0,这里用了官方底板,之后上电,发现FreeRTOS已经正常运行了,由于串口与Linux公用,这里可以看到串口资源一直被抢占了。

可以看到,即使大核的Linux运行时,小核运行的FreeRTOS也一直在打印计数。等进入到Linux系统启动以后,RTOS一直这样:

最后,不管打印什么,我在linux命令行下输入了halt,结果两个核心都消停了。

三.遇到的问题及解决。

  1. 需要修改FreeRTOS的config配置文件,关configUSE_TICK_HOOK,不然会提示错误哦!
  2. 开始我以为和ESP32的idf开发一样,只要编写task程序,不用开启调度器,结果发现运行不了,必须在最后开启调度器哦!
    好了,分享完毕,感兴趣的朋友,可以尝试一下!