轻松玩转树莓派Pico之八、RP2040 双核应用


前文说过树莓派 Pico 开发板片上主芯片为 RP2040 单片机,双核 Arm Cortex-M0 + 处理器,工作主频为 133MHz,264K 片上 SRAM,和 2MByteFlash。之前相关的 Project 都只用到了其中 1 个核,这次来体验一下双核。

1、官方代码

pico-examples

官方 pico-examples 提供了相关双核的示例,位于 multicore 目录下,提供了 4 个示例:

  1. hello_multicore
  2. multicore_fifo_irqs
  3. multicore_runner
  4. multicore_runner_queue

pico-sdk

双核相关接口都在 pico-sdk/blob/master/src/rp2_common/pico_multicore/multicore.c 文件中。
接口:

void multicore_launch_core1(void (*entry)(void));
//fifo
uint32_t multicore_fifo_pop_blocking(void);
void multicore_fifo_push_blocking(uint32_t data);

//irq
inline void multicore_fifo_clear_irq(void);
void irq_set_exclusive_handler(uint num, irq_handler_t handler);
void irq_set_enabled(uint num, bool enabled);
inline bool multicore_fifo_rvalid(void);

2、FreeRTOS应用

FreeRTOS 也已经支持 SMP 功能。FreeRTOS SMP 相关的代码,目前是以分支形式在 FreeRTOS-Kernel 仓库里面的。仓库地址:https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp

FreeRTOS SMP 相关介绍可以在官网 https://www.freertos.org/symmetric-multiprocessing-introduction.html 页面下获取。

该页面上面就有 pico 在 FreeRTOS SMP 上应用的相关介绍 https://www.freertos.org/smp-demos-for-the-raspberry-pi-pico-board.html

FreeRTOS 提供了 SMP 的 demo,位于 https://github.com/FreeRTOS/FreeRTOS-SMP-Demos.

SMP.md 中有介绍 SMP 相关的特殊 API。

DEMO 运行

  1. 下载 FreeRTOS-SMP-Demos
    FreeRTOS-SMP-Demos 仓库里面通过 submodule 模式已经集成了 支持 SMP 的 FreeRTOS-Kernel
$ git clone --recursive https://github.com/FreeRTOS/FreeRTOS-SMP-Demos
  1. RP2040 的工程位于 FreeRTOS-SMP-Demos/FreeRTOS/Demo/CORTEX_M0+_RP2040,文件夹下集成了 PICO 编译需要的相关文件,可以直接编译。
$ tree -L 1
.
├── CMakeLists.txt
├── OnEitherCore
├── pico_sdk_import.cmake
├── README.md
└── Standard

该目录下有 2 个 demo

  • Standard
  • OnEitherCore

创建 build 目录并进入 build 目录,运行

$ mkdir build && cd build
$ cmake ..
$ make

编译完成后,会在 2 个 demo 下各自自动生成 2 个可执行文件。

Standard 项目

该项目编译后,会生成 main_blinky 和 main_full 两个可执行文件,分别对应 vLaunch() 下的宏 mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 控制的两个函数。

void vLaunch( void)
{
    /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
    {
        main_blinky();
    }
#else
    {
        main_full();
    }
#endif
}

main_blinky 比较简单,分别创建了 2 个任务 prvQueueReceiveTask 和 prvQueueSendTask。

默认源代码不会显示当前任务运行在哪个核,可以在各自的任务中添加 printf("task %s is runing in core %d\r\n", __FUNCTION__, portGET_CORE_ID()); 显示当前任务运行核。
运行如下:

task prvQueueSendTask is runing in core 1
task prvQueueReceiveTask is runing in core 0

也有可能 2 个 Task 都运行在 core0 或者 core1,每次上电可能会切换。

可以通过 FreeRTOS 提供的 SMP 专有的 API 设置在创建任务时候设置对应任务运行在哪个核。

void main_blinky( void )
{
    printf(" Starting main_blinky.\n");

    /* Create the queue. */
	xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );

	if( xQueue != NULL )
	{
		/* Start the two tasks as described in the comments at the top of this
		file. */
	
		
		TaskHandle_t task0_Handle = NULL;
		xTaskCreate( prvQueueReceiveTask,				/* The function that implements the task. */
					"Rx", 								/* The text name assigned to the task - for debug only as it is not used by the kernel. */
					configMINIMAL_STACK_SIZE, 			/* The size of the stack to allocate to the task. */
					NULL, 								/* The parameter passed to the task - not used in this case. */
					mainQUEUE_RECEIVE_TASK_PRIORITY, 	/* The priority assigned to the task. */
					&task0_Handle );								/* The task handle is not required, so NULL is passed. */

    	UBaseType_t task0_CoreAffinityMask = (1 << 1);
    	vTaskCoreAffinitySet(task0_Handle, task0_CoreAffinityMask); 

    	TaskHandle_t task1_Handle = NULL;
		xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, &task1_Handle );

    	UBaseType_t task1_CoreAffinityMask = (1 << 0);
    	vTaskCoreAffinitySet(task1_Handle, task1_CoreAffinityMask);

		/* Start the tasks and timer running. */
		vTaskStartScheduler();
	}

	/* 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 insufficient FreeRTOS heap memory available for the Idle and/or
	timer tasks to be created.  See the memory management section on the
	FreeRTOS web site for more details on the FreeRTOS heap
	http://www.freertos.org/a00111.html. */
	for( ;; );
}

运行如下:

task prvQueueSendTask is runing in core 0
task prvQueueReceiveTask is runing in core 1
  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值