From a289612c6e2c8073fd06fe9ad9f7feda1ccca564 Mon Sep 17 00:00:00 2001 From: Jon Durrant Date: Thu, 25 Aug 2022 14:10:55 +0000 Subject: [PATCH] Multicore Section Examples --- .gitmodules | 3 + 8-Multicore/FreeRTOSSMP/CMakeLists.txt | 39 ++++ .../FreeRTOSSMP/FreeRTOS_Kernel_import.cmake | 69 ++++++ 8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel | 1 + 8-Multicore/FreeRTOSSMP/pico_sdk_import.cmake | 62 ++++++ .../port/FreeRTOS-Kernel/FreeRTOSConfig.h | 145 +++++++++++++ 8-Multicore/FreeRTOSSMP/src/Agent.cpp | 105 ++++++++++ 8-Multicore/FreeRTOSSMP/src/Agent.h | 92 ++++++++ 8-Multicore/FreeRTOSSMP/src/BlinkAgent.cpp | 61 ++++++ 8-Multicore/FreeRTOSSMP/src/BlinkAgent.h | 54 +++++ 8-Multicore/FreeRTOSSMP/src/CMakeLists.txt | 29 +++ 8-Multicore/FreeRTOSSMP/src/CounterAgent.cpp | 198 ++++++++++++++++++ 8-Multicore/FreeRTOSSMP/src/CounterAgent.h | 92 ++++++++ 8-Multicore/FreeRTOSSMP/src/main.cpp | 168 +++++++++++++++ 8-Multicore/sdkMulticore/CMakeLists.txt | 31 +++ .../sdkMulticore/pico_sdk_import.cmake | 62 ++++++ 8-Multicore/sdkMulticore/src/CMakeLists.txt | 24 +++ 8-Multicore/sdkMulticore/src/main.cpp | 93 ++++++++ 18 files changed, 1328 insertions(+) create mode 100644 8-Multicore/FreeRTOSSMP/CMakeLists.txt create mode 100644 8-Multicore/FreeRTOSSMP/FreeRTOS_Kernel_import.cmake create mode 160000 8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel create mode 100644 8-Multicore/FreeRTOSSMP/pico_sdk_import.cmake create mode 100644 8-Multicore/FreeRTOSSMP/port/FreeRTOS-Kernel/FreeRTOSConfig.h create mode 100644 8-Multicore/FreeRTOSSMP/src/Agent.cpp create mode 100644 8-Multicore/FreeRTOSSMP/src/Agent.h create mode 100644 8-Multicore/FreeRTOSSMP/src/BlinkAgent.cpp create mode 100644 8-Multicore/FreeRTOSSMP/src/BlinkAgent.h create mode 100644 8-Multicore/FreeRTOSSMP/src/CMakeLists.txt create mode 100644 8-Multicore/FreeRTOSSMP/src/CounterAgent.cpp create mode 100644 8-Multicore/FreeRTOSSMP/src/CounterAgent.h create mode 100644 8-Multicore/FreeRTOSSMP/src/main.cpp create mode 100644 8-Multicore/sdkMulticore/CMakeLists.txt create mode 100644 8-Multicore/sdkMulticore/pico_sdk_import.cmake create mode 100644 8-Multicore/sdkMulticore/src/CMakeLists.txt create mode 100644 8-Multicore/sdkMulticore/src/main.cpp diff --git a/.gitmodules b/.gitmodules index 9c14d1f..0c6ea65 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/tiny-json"] path = lib/tiny-json url = https://github.com/rafagafe/tiny-json +[submodule "8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel"] + path = 8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel + url = https://github.com/FreeRTOS/FreeRTOS-Kernel diff --git a/8-Multicore/FreeRTOSSMP/CMakeLists.txt b/8-Multicore/FreeRTOSSMP/CMakeLists.txt new file mode 100644 index 0000000..8838456 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.12) + +# Change your executable name to something creative! +set(NAME BlinkLEDExt) # <-- Name your project/executable here! + +include(pico_sdk_import.cmake) + +# Gooey boilerplate +project(${NAME} C CXX ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +# Initialize the SDK +pico_sdk_init() + +#include Libraries +SET(FREERTOS_CONFIG_FILE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/port/FreeRTOS-Kernel" CACHE STRING "Local Config") +include_directories("${FREERTOS_CONFIG_FILE_DIRECTORY}") +include(FreeRTOS_Kernel_import.cmake) +add_compile_definitions( + FREE_RTOS_KERNEL_SMP=1 + portSUPPORT_SMP=1 +) + +#Add main source directory +add_subdirectory(src) + +#Set up files for the release packages +install(CODE "execute_process(COMMAND $ENV{HOME}/bin/picoDeploy.sh ${CMAKE_CURRENT_BINARY_DIR}/src/${NAME}.elf)") + +# Set up files for the release packages +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/src/${NAME}.uf2 + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} +) + +set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) +set(CPACK_GENERATOR "ZIP" "TGZ") +include(CPack) diff --git a/8-Multicore/FreeRTOSSMP/FreeRTOS_Kernel_import.cmake b/8-Multicore/FreeRTOSSMP/FreeRTOS_Kernel_import.cmake new file mode 100644 index 0000000..6ac35a1 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/FreeRTOS_Kernel_import.cmake @@ -0,0 +1,69 @@ +# This is a copy of /portable/ThirdParty/GCC/RP2040/FREERTOS_KERNEL_import.cmake + +# This can be dropped into an external project to help locate the FreeRTOS kernel +# It should be include()ed prior to project(). Alternatively this file may +# or the CMakeLists.txt in this directory may be included or added via add_subdirectory +# respectively. + +if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH)) + set(FREERTOS_KERNEL_PATH $ENV{FREERTOS_KERNEL_PATH}) + message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')") +else () + set(FREERTOS_KERNEL_PATH "${CMAKE_CURRENT_LIST_DIR}/lib/FreeRTOS-Kernel") + message("Using local FREERTOS_KERNEL_PATH '${FREERTOS_KERNEL_PATH}')") +endif () + +set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC/RP2040") +# undo the above +# set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") + + +if (NOT FREERTOS_KERNEL_PATH) + # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) + get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) + get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + endif() + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") + elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") + set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) + message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") + endif() +endif () + +if (NOT FREERTOS_KERNEL_PATH) + foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) + # check if FreeRTOS-Kernel exists under directory that included us + set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}}) + set(SEARCH_ROOT ../../../..) + get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) + if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) + get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") + break() + endif() + endforeach() +endif() + +if (NOT FREERTOS_KERNEL_PATH) + message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.") +endif() + +set(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" CACHE PATH "Path to the FreeRTOS Kernel") + +get_filename_component(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${FREERTOS_KERNEL_PATH}) + message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found") +endif() +if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) + message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain an RP2040 port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") +endif() +set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE) + +add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) + +#FORCE LIBRARY BUILD +include(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/library.cmake) diff --git a/8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel b/8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel new file mode 160000 index 0000000..2b0fdf2 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/lib/FreeRTOS-Kernel @@ -0,0 +1 @@ +Subproject commit 2b0fdf2a712d29cb3695e540042c89cadecc29dd diff --git a/8-Multicore/FreeRTOSSMP/pico_sdk_import.cmake b/8-Multicore/FreeRTOSSMP/pico_sdk_import.cmake new file mode 100644 index 0000000..e02a33e --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the PICO SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading PICO SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "PICO SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the PICO SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the PICO SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/8-Multicore/FreeRTOSSMP/port/FreeRTOS-Kernel/FreeRTOSConfig.h b/8-Multicore/FreeRTOSSMP/port/FreeRTOS-Kernel/FreeRTOSConfig.h new file mode 100644 index 0000000..fb84519 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/port/FreeRTOS-Kernel/FreeRTOSConfig.h @@ -0,0 +1,145 @@ +/* + * FreeRTOS V202111.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "rp2040_config.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +/* Scheduler Related */ +#define configUSE_PREEMPTION 1 +#define configUSE_TICKLESS_IDLE 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES 32 +#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 256 +#define configUSE_16_BIT_TICKS 0 + +#define configIDLE_SHOULD_YIELD 1 + +/* Synchronization Related */ +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_NEWLIB_REENTRANT 0 +// todo need this for lwip FreeRTOS sys_arch to compile +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* System */ +#define configSTACK_DEPTH_TYPE uint32_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE (128*1024) +#define configAPPLICATION_ALLOCATED_HEAP 0 + +/* Hook function related definitions. */ +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 1024 + +/* Interrupt nesting behaviour configuration. */ +/* +#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor] +#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application] +#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] +*/ + +#if FREE_RTOS_KERNEL_SMP // set by the RP2040 SMP port of FreeRTOS +/* SMP port only */ +#define configNUM_CORES 2 +#define configTICK_CORE 0 +#define configRUN_MULTIPLE_PRIORITIES 1 +#define configUSE_CORE_AFFINITY 1 +#endif + +/* RP2040 specific */ +#define configSUPPORT_PICO_SYNC_INTEROP 1 +#define configSUPPORT_PICO_TIME_INTEROP 1 + +#include +/* Define to trap errors during development. */ +#define configASSERT(x) assert(x) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* A header file that defines trace macro can be included here. */ + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/8-Multicore/FreeRTOSSMP/src/Agent.cpp b/8-Multicore/FreeRTOSSMP/src/Agent.cpp new file mode 100644 index 0000000..a88eb0d --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/Agent.cpp @@ -0,0 +1,105 @@ +/* + * Agent.cpp + * Abstract agent interface to an active agent object that runs as + * FreeRTOS task + * Created on: 15 Aug 2022 + * Author: jondurrant + */ + +#include "Agent.h" +#include +#include "hardware/structs/sio.h" + +/*** + * Constructor + */ +Agent::Agent() { + // NOP + +} + +/*** + * Destructor + */ +Agent::~Agent() { + stop(); +} + +/*** + * Stop task + * @return + */ +void Agent::stop(){ + if (xHandle != NULL){ + vTaskDelete( xHandle ); + xHandle = NULL; + } +} + + +/*** +* Get high water for stack +* @return close to zero means overflow risk +*/ +unsigned int Agent::getStakHighWater(){ + if (xHandle != NULL) + return uxTaskGetStackHighWaterMark(xHandle); + else + return 0; +} + + +/*** +* Get the FreeRTOS task being used +* @return +*/ +TaskHandle_t Agent::getTask(){ + return xHandle; +} + + +/*** + * Start the task + * @param priority - Priority to apply to process + * @return + */ +bool Agent::start(const char *name, UBaseType_t priority){ + BaseType_t res; + + if (strlen(name) >= MAX_NAME_LEN){ + memcpy(pName, name, MAX_NAME_LEN); + pName[MAX_NAME_LEN-1]=0; + } else { + strcpy(pName, name); + } + res = xTaskCreate( + Agent::vTask, /* Function that implements the task. */ + pName, /* Text name for the task. */ + getMaxStackSize(), /* Stack size in words, not bytes. */ + ( void * ) this, /* Parameter passed into the task. */ + priority,/* Priority at which the task is created. */ + &xHandle + ); + return (res == pdPASS); +} + + + +/*** + * Internal function used by FreeRTOS to run the task + * @param pvParameters + */ + void Agent::vTask( void * pvParameters ){ + Agent *task = (Agent *) pvParameters; + if (task != NULL){ + task->run(); + } + } + +/*** +* Return core that code is running on +* @return 0 or 1 +*/ +uint8_t Agent::getCore(){ + return (uint8_t)sio_hw->cpuid; +} diff --git a/8-Multicore/FreeRTOSSMP/src/Agent.h b/8-Multicore/FreeRTOSSMP/src/Agent.h new file mode 100644 index 0000000..daf164a --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/Agent.h @@ -0,0 +1,92 @@ +/* + * Agent.h + * + * Abstract agent interface to an active agent object that runs as + * FreeRTOS task + * + * Created on: 15 Aug 2022 + * Author: jondurrant + */ + +#ifndef SRC_AGENT_H_ +#define SRC_AGENT_H_ + +#define MAX_NAME_LEN 20 + +#include "FreeRTOS.h" +#include "task.h" + + +class Agent { +public: + /*** + * Constructor + */ + Agent(); + + /*** + * Destructor + */ + virtual ~Agent(); + + /*** + * Start the task + * @param name - Give the task a name (<20 characters) + * @param priority - priority - 0 is idle + * @return + */ + virtual bool start(const char *name, UBaseType_t priority = tskIDLE_PRIORITY); + + /*** + * Stop task + * @return + */ + virtual void stop(); + + + /*** + * Get high water for stack + * @return close to zero means overflow risk + */ + virtual unsigned int getStakHighWater(); + + /*** + * Get the FreeRTOS task being used + * @return + */ + virtual TaskHandle_t getTask(); + + /*** + * Return core that code is running on + * @return 0 or 1 + */ + virtual uint8_t getCore(); + +protected: + /*** + * Start the task via static function + * @param pvParameters - will be the Agent object + */ + static void vTask( void * pvParameters ); + + /*** + * Task main run loop + */ + virtual void run()=0; + + /*** + * Get the static depth required in words + * @return - words + */ + virtual configSTACK_DEPTH_TYPE getMaxStackSize()=0; + + //The task + TaskHandle_t xHandle = NULL; + + char pName[MAX_NAME_LEN]; + + +}; + + +#endif /* SRC_AGENT_H_ */ diff --git a/8-Multicore/FreeRTOSSMP/src/BlinkAgent.cpp b/8-Multicore/FreeRTOSSMP/src/BlinkAgent.cpp new file mode 100644 index 0000000..c5ae4c6 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/BlinkAgent.cpp @@ -0,0 +1,61 @@ +/* + * BlinkAgent.cpp + * + * Created on: 15 Aug 2022 + * Author: jondurrant + */ + +#include "BlinkAgent.h" + +#include "stdio.h" + + +//Blink Delay +#define DELAY 500 + +/*** + * Constructor + * @param gp - GPIO Pad number for LED + */ +BlinkAgent::BlinkAgent(uint8_t gp) { + xLedPad = gp; + +} + +/*** + * Destructor + */ +BlinkAgent::~BlinkAgent() { + stop(); +} + + + /*** + * Main Run Task for agent + */ + void BlinkAgent::run(){ + + printf("Blink Started\n"); + + gpio_init(xLedPad); + + gpio_set_dir(xLedPad, GPIO_OUT); + + while (true) { // Loop forever + gpio_put(xLedPad, 1); + vTaskDelay(DELAY); + gpio_put(xLedPad, 0); + vTaskDelay(DELAY); + + printf("%s on Core %d\n", pName, getCore()); + } + + } + +/*** + * Get the static depth required in words + * @return - words + */ +configSTACK_DEPTH_TYPE BlinkAgent::getMaxStackSize(){ + return 150; +} diff --git a/8-Multicore/FreeRTOSSMP/src/BlinkAgent.h b/8-Multicore/FreeRTOSSMP/src/BlinkAgent.h new file mode 100644 index 0000000..7191dd5 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/BlinkAgent.h @@ -0,0 +1,54 @@ +/* + * BlinkAgent.h + * + * Active agent to run as task and blink and LED on the given GPIO pad + * + * Created on: 15 Aug 2022 + * Author: jondurrant + */ + +#ifndef BLINKAGENT_H_ +#define BLINKAGENT_H_ + +#include "pico/stdlib.h" +#include "FreeRTOS.h" +#include "task.h" + +#include "Agent.h" + + +class BlinkAgent: public Agent { +public: + /*** + * Constructor + * @param gp - GPIO Pad number for LED + */ + BlinkAgent(uint8_t gp=0); + + /*** + * Destructor + */ + virtual ~BlinkAgent(); + + +protected: + + /*** + * Run loop for the agent. + */ + virtual void run(); + + + /*** + * Get the static depth required in words + * @return - words + */ + virtual configSTACK_DEPTH_TYPE getMaxStackSize(); + + //GPIO PAD for LED + uint8_t xLedPad = 0; + +}; + + +#endif /* BLINKAGENT_H_ */ diff --git a/8-Multicore/FreeRTOSSMP/src/CMakeLists.txt b/8-Multicore/FreeRTOSSMP/src/CMakeLists.txt new file mode 100644 index 0000000..b9abd74 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/CMakeLists.txt @@ -0,0 +1,29 @@ +add_executable(${NAME} + main.cpp + Agent.cpp + BlinkAgent.cpp + CounterAgent.cpp + ) + +# Pull in our pico_stdlib which pulls in commonly used features +target_link_libraries(${NAME} + pico_stdlib + FreeRTOS-Kernel-Heap4 + ) + +target_include_directories(${NAME} PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/../lib/FreeRTOS-Kernel/include + ) + +target_compile_definitions(${NAME} PRIVATE + FREE_RTOS_KERNEL_SMP=1 + portSUPPORT_SMP=1 +) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${NAME}) + +# enable usb output, disable uart output +pico_enable_stdio_usb(${NAME} 1) +pico_enable_stdio_uart(${NAME} 0) \ No newline at end of file diff --git a/8-Multicore/FreeRTOSSMP/src/CounterAgent.cpp b/8-Multicore/FreeRTOSSMP/src/CounterAgent.cpp new file mode 100644 index 0000000..dc62d43 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/CounterAgent.cpp @@ -0,0 +1,198 @@ +/* + * CounterAgent.cpp + * + * Created on: 22 Aug 2022 + * Author: jondurrant + */ + +#include "CounterAgent.h" +#include "stdio.h" + +//Local enumerator of the actions to be queued +enum CounterAction {CounterOff, CounterOn, CounterBlink}; + +//Queue cmd structure +struct CounterCmd { + CounterAction action; + uint8_t count; +}; + +//Type def for the queue command +typedef struct CounterCmd CounterCmdT; + +/*** + * Contructor + * @param gp1 GPIO PAD for 1st LED - units + * @param gp2 GPIO PAD for 1st LED - 2 + * @param gp3 GPIO PAD for 1st LED - 4 + * @param gp4 GPIO PAD for 1st LED - 8 + */ +CounterAgent::CounterAgent(uint8_t gp1, uint8_t gp2, uint8_t gp3, uint8_t gp4) { + + pLedPads[0] = gp1; + pLedPads[1] = gp2; + pLedPads[2] = gp3; + pLedPads[3] = gp4; + + xCmdQ = xQueueCreate( COUNT_QUEUE_LEN, sizeof(CounterCmd)); + if (xCmdQ == NULL){ + printf("ERROR: Unable to create Queue\n"); + } +} + + +/*** + * Destructor + */ +CounterAgent::~CounterAgent() { + if (xCmdQ != NULL){ + vQueueDelete(xCmdQ); + } +} + +/*** + * Initialise the LEDs + */ +void CounterAgent::init(){ + for (int i = 0 ; i < COUNT_LEDS; i++){ + gpio_init(pLedPads[i]); + gpio_set_dir(pLedPads[i], GPIO_OUT); + gpio_put(pLedPads[i], 0); + } +} + + +/*** + * Main Run Task for agent + */ + void CounterAgent::run(){ + BaseType_t res; + printf("Count Started\n"); + init(); + + CounterAction action = CounterOff; + uint8_t count = 0; + bool blinkOn = false; + CounterCmdT cmd; + bool change; + + if (xCmdQ == NULL){ + return; + } + + while (true) { // Loop forever + printf("%s on Core %d\n",pName, getCore()); + res = xQueueReceive(xCmdQ, (void *)&cmd, COUNT_BLINK_DELAY); + if (res == pdTRUE){ + action = cmd.action; + count = cmd.count; + change = true; + } else { + change = false; + } + + switch(action){ + case CounterOff: + if (change){ + setLeds(0); + } + break; + case CounterOn: + if (change){ + setLeds(count); + } + break; + case CounterBlink: + blinkOn = ! blinkOn; + if (blinkOn){ + setLeds(count); + } else { + setLeds(0); + } + } + } + +} + +/*** + * Get the static depth required in words + * @return - words + */ +configSTACK_DEPTH_TYPE CounterAgent::getMaxStackSize(){ + return 150; +} + + +/*** + * Set the LEDs to the mask in count + * @param count + */ +void CounterAgent::setLeds(uint8_t count){ + for (int i = 0; i < COUNT_LEDS; i ++){ + uint8_t m = 1 << i; + if ( (count & m) > 0){ + gpio_put(pLedPads[i], 1); + } else { + gpio_put(pLedPads[i], 0); + } + } +} + +/*** + * Turn LEDs on and display count + * @param count - between 0 and 0xF + */ +void CounterAgent::on(uint8_t count){ + BaseType_t res; + + CounterCmdT cmd; + cmd.action = CounterOn; + cmd.count = count; + + if (xCmdQ != NULL){ + res = xQueueSendToBack(xCmdQ, (void *)&cmd, 0); + if (res != pdTRUE){ + printf("WARNING: Queue is full\n"); + } + } +} + +/*** + * Turn LEDs off + */ +void CounterAgent::off(){ + BaseType_t res; + + CounterCmdT cmd; + cmd.action = CounterOff; + cmd.count = 0; + + if (xCmdQ != NULL){ + res = xQueueSendToBack(xCmdQ, (void *)&cmd, 0); + if (res != pdTRUE){ + printf("WARNING: Queue is full\n"); + } + } + +} + +/*** + * Blink LEDs with displayed count + * @param count - between 0 and 0x0F + */ +void CounterAgent::blink(uint8_t count){ + BaseType_t res; + + CounterCmdT cmd; + cmd.action = CounterBlink; + cmd.count = count; + + if (xCmdQ != NULL){ + res = xQueueSendToBack(xCmdQ, (void *)&cmd, 0); + if (res != pdTRUE){ + printf("WARNING: Queue is full\n"); + } + } +} + + diff --git a/8-Multicore/FreeRTOSSMP/src/CounterAgent.h b/8-Multicore/FreeRTOSSMP/src/CounterAgent.h new file mode 100644 index 0000000..c8a99b4 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/CounterAgent.h @@ -0,0 +1,92 @@ +/* + * CounterAgent.h + * + * Show binary view of count on LEDs + * + * Created on: 22 Aug 2022 + * Author: jondurrant + */ + +#ifndef COUNTERAGENT_H_ +#define COUNTERAGENT_H_ + +#include "pico/stdlib.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#include "Agent.h" + +#define COUNT_LEDS 4 +#define COUNT_QUEUE_LEN 10 +#define COUNT_BLINK_DELAY 500 + +class CounterAgent : public Agent { +public: + + /*** + * Contructor + * @param gp1 GPIO PAD for 1st LED - units + * @param gp2 GPIO PAD for 1st LED - 2 + * @param gp3 GPIO PAD for 1st LED - 4 + * @param gp4 GPIO PAD for 1st LED - 8 + */ + CounterAgent(uint8_t gp1=0, uint8_t gp2=0, uint8_t gp3=0, uint8_t gp4=0); + + /*** + * Destructor + */ + virtual ~CounterAgent(); + + /*** + * Turn LEDs on and display count + * @param count - between 0 and 0xF + */ + virtual void on(uint8_t count); + + /*** + * Turn LEDs off + */ + virtual void off(); + + /*** + * Blink LEDs with displayed count + * @param count - between 0 and 0x0F + */ + virtual void blink(uint8_t count); + +protected: + + /*** + * Run loop for the agent. + */ + virtual void run(); + + + /*** + * Get the static depth required in words + * @return - words + */ + virtual configSTACK_DEPTH_TYPE getMaxStackSize(); + + /*** + * Initialise the LEDs + */ + virtual void init(); + + + /*** + * Set the LEDs to the mask in count + * @param count + */ + virtual void setLeds(uint8_t count); + + //GPIO PAD for LED + uint8_t pLedPads[COUNT_LEDS]; + + //Queue of commands + QueueHandle_t xCmdQ; + +}; + +#endif /* COUNTERAGENT_H_ */ diff --git a/8-Multicore/FreeRTOSSMP/src/main.cpp b/8-Multicore/FreeRTOSSMP/src/main.cpp new file mode 100644 index 0000000..51bc7e1 --- /dev/null +++ b/8-Multicore/FreeRTOSSMP/src/main.cpp @@ -0,0 +1,168 @@ +/*** + * Demo program to use FreeRTOS SMP on Both Cores + * Blink on Core 0 to GPIO 0 + * Blink on Core 1 to GPIO 15 + * Counter showing on GPIO 2 to 5, using Core 1 + * Instructions sent to Counter from Main Task on Core 0 + * Jon Durrant + * 15-Aug-2022 + */ + + +#include "pico/stdlib.h" + +#include "FreeRTOS.h" +#include "task.h" +#include +#include +#include "hardware/structs/sio.h" + +#include "BlinkAgent.h" +#include "CounterAgent.h" + + +//Standard Task priority +#define TASK_PRIORITY ( tskIDLE_PRIORITY + 1UL ) + +//LED PAD to use +#define LED_PAD 0 +#define LED1_PAD 2 +#define LED2_PAD 3 +#define LED3_PAD 4 +#define LED4_PAD 5 +#define LED5_PAD 15 + + +void runTimeStats( ){ + TaskStatus_t *pxTaskStatusArray; + volatile UBaseType_t uxArraySize, x; + unsigned long ulTotalRunTime; + + + // Get number of takss + uxArraySize = uxTaskGetNumberOfTasks(); + printf("Number of tasks %d\n", uxArraySize); + + //Allocate a TaskStatus_t structure for each task. + pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) ); + + if( pxTaskStatusArray != NULL ){ + // Generate raw status information about each task. + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, + uxArraySize, + &ulTotalRunTime ); + + // Print stats + for( x = 0; x < uxArraySize; x++ ) + { + printf("Task: %d \t cPri:%d \t bPri:%d \t hw:%d \t%s\n", + pxTaskStatusArray[ x ].xTaskNumber , + pxTaskStatusArray[ x ].uxCurrentPriority , + pxTaskStatusArray[ x ].uxBasePriority , + pxTaskStatusArray[ x ].usStackHighWaterMark , + pxTaskStatusArray[ x ].pcTaskName + ); + } + + + // Free array + vPortFree( pxTaskStatusArray ); + } else { + printf("Failed to allocate space for stats\n"); + } + + //Get heap allocation information + HeapStats_t heapStats; + vPortGetHeapStats(&heapStats); + printf("HEAP avl: %d, blocks %d, alloc: %d, free: %d\n", + heapStats.xAvailableHeapSpaceInBytes, + heapStats.xNumberOfFreeBlocks, + heapStats.xNumberOfSuccessfulAllocations, + heapStats.xNumberOfSuccessfulFrees + ); +} + + +/*** + * Main task to blink external LED + * @param params - unused + */ +void mainTask(void *params){ + BlinkAgent blink(LED_PAD); + BlinkAgent blink1(LED5_PAD); + CounterAgent counter(LED1_PAD, LED2_PAD, LED3_PAD, LED4_PAD); + + + printf("Main task started\n"); + + blink.start("Blink 0", TASK_PRIORITY); + blink1.start("Blink 1", TASK_PRIORITY); + counter.start("Counter", TASK_PRIORITY); + + //Bind to CORE 1 + UBaseType_t coreMask = 0x2; + vTaskCoreAffinitySet( blink1.getTask(), coreMask ); + vTaskCoreAffinitySet( counter.getTask(), coreMask ); + + //Bind to CORE 0 + coreMask = 0x1; + vTaskCoreAffinitySet( blink.getTask(), coreMask ); + + + while (true) { // Loop forever + runTimeStats(); + printf("Main on Core %ld\n",sio_hw->cpuid); + + uint8_t r = rand()&0xF; + counter.on(r); + vTaskDelay(3000); + } +} + + + + +/*** + * Launch the tasks and scheduler + */ +void vLaunch( void) { + + //Start blink task + TaskHandle_t task; + xTaskCreate(mainTask, "MainThread", 500, NULL, TASK_PRIORITY, &task); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); +} + +/*** + * Main + * @return + */ +int main( void ) +{ + //Setup serial over USB and give a few seconds to settle before we start + stdio_init_all(); + sleep_ms(2000); + printf("GO\n"); + + //Start tasks and scheduler + + const char *rtos_name; +#if ( portSUPPORT_SMP == 1 ) + rtos_name = "FreeRTOS SMP"; +#else + rtos_name = "FreeRTOS"; +#endif + +#if ( portSUPPORT_SMP == 1 ) && ( configNUM_CORES == 2 ) + printf("%s on both cores:\n", rtos_name); +#else + printf("Starting %s on core 0:\n", rtos_name); +#endif + + vLaunch(); + + + return 0; +} diff --git a/8-Multicore/sdkMulticore/CMakeLists.txt b/8-Multicore/sdkMulticore/CMakeLists.txt new file mode 100644 index 0000000..ecf39fa --- /dev/null +++ b/8-Multicore/sdkMulticore/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.12) + +# Change your executable name to something creative! +set(NAME sdkMC) # <-- Name your project/executable here! + +include(pico_sdk_import.cmake) + +# Gooey boilerplate +project(${NAME} C CXX ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +# Initialize the SDK +pico_sdk_init() + + +#Add main source directory +add_subdirectory(src) + +#Set up files for the release packages +install(CODE "execute_process(COMMAND $ENV{HOME}/bin/picoDeploy.sh ${CMAKE_CURRENT_BINARY_DIR}/src/${NAME}.elf)") + +# Set up files for the release packages +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/src/${NAME}.uf2 + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} +) + +set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) +set(CPACK_GENERATOR "ZIP" "TGZ") +include(CPack) diff --git a/8-Multicore/sdkMulticore/pico_sdk_import.cmake b/8-Multicore/sdkMulticore/pico_sdk_import.cmake new file mode 100644 index 0000000..e02a33e --- /dev/null +++ b/8-Multicore/sdkMulticore/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the PICO SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading PICO SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "PICO SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the PICO SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the PICO SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/8-Multicore/sdkMulticore/src/CMakeLists.txt b/8-Multicore/sdkMulticore/src/CMakeLists.txt new file mode 100644 index 0000000..04abe50 --- /dev/null +++ b/8-Multicore/sdkMulticore/src/CMakeLists.txt @@ -0,0 +1,24 @@ +add_executable(${NAME} + main.cpp + ) + +# Pull in our pico_stdlib which pulls in commonly used features +target_link_libraries(${NAME} + pico_stdlib + pico_multicore + ) + +target_include_directories(${NAME} PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ) + +target_compile_definitions(${NAME} PRIVATE + configNUM_CORES=2 +) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${NAME}) + +# enable usb output, disable uart output +pico_enable_stdio_usb(${NAME} 1) +pico_enable_stdio_uart(${NAME} 0) \ No newline at end of file diff --git a/8-Multicore/sdkMulticore/src/main.cpp b/8-Multicore/sdkMulticore/src/main.cpp new file mode 100644 index 0000000..47fceea --- /dev/null +++ b/8-Multicore/sdkMulticore/src/main.cpp @@ -0,0 +1,93 @@ +/*** + * Demo program to + * + * Jon Durrant + * 15-Aug-2022 + */ + + +#include "pico/stdlib.h" +#include +#include "pico/multicore.h" +#include "hardware/structs/sio.h" +#include + +#define TASK_PRIORITY ( tskIDLE_PRIORITY + 1UL ) + +//LED PAD to use +#define LED_PAD 0 +#define LED5_PAD 15 + +//Blink Delay +#define DELAY 500 + + +/*** + * Function to run on Core1 + */ +void core1Main(void){ + + printf("Main Core 1 task started %ld\n", sio_hw->cpuid); + + const uint ledPad = LED5_PAD; + gpio_init(ledPad); + + gpio_set_dir(ledPad, GPIO_OUT); + + while (true) { // Loop forever + gpio_put(ledPad, 1); + sleep_ms(DELAY); + gpio_put(ledPad, 0); + sleep_ms(DELAY); + + uint32_t r; + if (multicore_fifo_pop_timeout_us(0, &r)){ + printf("Received %ld\n", r); + } + } +} + +/*** + * Function to run on Core 0 + */ +void core0Main(void){ + + printf("Main Core 0 task started %ld\n", sio_hw->cpuid); + + const uint ledPad = LED_PAD; + gpio_init(ledPad); + + gpio_set_dir(ledPad, GPIO_OUT); + + while (true) { // Loop forever + gpio_put(ledPad, 1); + sleep_ms(DELAY); + gpio_put(ledPad, 0); + sleep_ms(DELAY); + + uint32_t r = rand(); + if (multicore_fifo_push_timeout_us (r, 0)){ + printf("Sent %ld\n", r); + } + } +} + + +/*** + * Main + * @return + */ +int main( void ) +{ + stdio_init_all(); + sleep_ms(2000); + printf("GO\n"); + + multicore_launch_core1(core1Main); + + core0Main(); + + + + return 0; +}