From 86cd14a1f6ede4514affb70127bf9d09b2c48127 Mon Sep 17 00:00:00 2001 From: IOsetting Date: Wed, 25 Jan 2023 15:39:31 +0800 Subject: [PATCH] feat: ll freertos semaphore examples --- .../LL_Binary_Semaphore/FreeRTOSConfig.h | 98 +++++++++++ .../Semaphore/LL_Binary_Semaphore/main.c | 160 ++++++++++++++++++ .../Semaphore/LL_Binary_Semaphore/main.h | 25 +++ .../LL_Binary_Semaphore/py32f0xx_it.c | 17 ++ .../LL_Binary_Semaphore/py32f0xx_it.h | 16 ++ .../LL_Counting_Semaphore/FreeRTOSConfig.h | 96 +++++++++++ .../Semaphore/LL_Counting_Semaphore/main.c | 143 ++++++++++++++++ .../Semaphore/LL_Counting_Semaphore/main.h | 25 +++ .../LL_Counting_Semaphore/py32f0xx_it.c | 17 ++ .../LL_Counting_Semaphore/py32f0xx_it.h | 16 ++ .../Semaphore/LL_Mutex/FreeRTOSConfig.h | 94 ++++++++++ Examples/FreeRTOS/Semaphore/LL_Mutex/main.c | 101 +++++++++++ Examples/FreeRTOS/Semaphore/LL_Mutex/main.h | 24 +++ .../FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.c | 17 ++ .../FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.h | 16 ++ Libraries/BSP_LL/Inc/py32f0xx_bsp_printf.h | 7 +- Libraries/BSP_LL/Src/py32f0xx_bsp_printf.c | 82 ++++++--- 17 files changed, 932 insertions(+), 22 deletions(-) create mode 100644 Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/FreeRTOSConfig.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.c create mode 100644 Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.c create mode 100644 Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/FreeRTOSConfig.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.c create mode 100644 Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.c create mode 100644 Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Mutex/FreeRTOSConfig.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Mutex/main.c create mode 100644 Examples/FreeRTOS/Semaphore/LL_Mutex/main.h create mode 100644 Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.c create mode 100644 Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.h diff --git a/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/FreeRTOSConfig.h b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/FreeRTOSConfig.h new file mode 100644 index 0000000..5769d36 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/FreeRTOSConfig.h @@ -0,0 +1,98 @@ +/* + * FreeRTOS V202112.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 + +/*----------------------------------------------------------- + * 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 + *----------------------------------------------------------*/ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + #include + #include + extern uint32_t SystemCoreClock; +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 2 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 3 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0 + +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* 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_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskGetStackHighWaterMark2 1 +#define INCLUDE_xTaskGetHandle 1 + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 +(lowest) to 0 (1?) (highest). */ +#define configKERNEL_INTERRUPT_PRIORITY 255 +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 10-111111, or priority 2. */ + +/* Use MACRO to replace the handlers without changing startup file */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + + +#endif /* FREERTOS_CONFIG_H */ \ No newline at end of file diff --git a/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.c b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.c new file mode 100644 index 0000000..25bc5a4 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.c @@ -0,0 +1,160 @@ +/** + * Example of Binary Semaphore + * + * Note: Require RAM > 6K Byte + */ +#include "main.h" +#include "py32f0xx_bsp_printf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +TaskStatus_t xTaskDetails; +char buff[512]; + +SemaphoreHandle_t xBinarySemaphore; +volatile uint32_t val; + +static void APP_SystemClockConfig(void); +static void APP_GPIOConfig(void); +static void APP_TIM1Config(void); + +void taskUART(void *pvParameters) +{ + (void)(pvParameters); + + while (1) + { + // Block till being notified by TIM1 Interrupt + xSemaphoreTake(xBinarySemaphore, portMAX_DELAY); + /** + * Use printf() will take more stack size + * printf("%lu Name State Priority Stack Num\r\n%s", val, buff); + */ + BSP_UART_TxHex32(val); + BSP_UART_TxString(" Name State Priority Stack Num\r\n"); + BSP_UART_TxString(buff); + } +} + +void taskInfo(void *pvParameters) +{ + (void)(pvParameters); + + while (1) + { + vTaskList(buff); + vTaskDelay(300); + } +} + +int main(void) +{ + BaseType_t xReturned; + + APP_SystemClockConfig(); + APP_GPIOConfig(); + + BSP_USART_Config(115200); + printf("SystemClk:%ld\r\n", SystemCoreClock); + + xBinarySemaphore = xSemaphoreCreateBinary(); + if (xBinarySemaphore == NULL) + { + APP_ErrorHandler(); + } + + xReturned = xTaskCreate(taskUART, "taskUART", 160, NULL, 2, NULL); + if (xReturned != pdPASS) + { + APP_ErrorHandler(); + } + + xReturned = xTaskCreate(taskInfo, "taskInfo", 160, NULL, 2, NULL); + if (xReturned != pdPASS) + { + APP_ErrorHandler(); + } + + APP_TIM1Config(); + + printf("FreeRTOS Scheduler starting...\r\n"); + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* Will only get here if there was not enough heap space to create the idle task. */ + return 0; +} + +static void APP_TIM1Config(void) +{ + LL_TIM_InitTypeDef TIM1CountInit = {0}; + + LL_APB1_GRP2_EnableClock(RCC_APBENR2_TIM1EN); + + TIM1CountInit.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM1CountInit.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM1CountInit.Prescaler = 8000-1; + TIM1CountInit.Autoreload = 6000-1; + TIM1CountInit.RepetitionCounter = 0; + LL_TIM_Init(TIM1,&TIM1CountInit); + + LL_TIM_EnableIT_UPDATE(TIM1); + LL_TIM_EnableCounter(TIM1); + + NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); + NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 2); +} + +/** + * Set system clock to 48MHz +*/ +static void APP_SystemClockConfig(void) +{ + LL_UTILS_ClkInitTypeDef UTILS_ClkInitStruct; + + LL_RCC_HSI_Enable(); + /* Change this value to adjust frequency */ + LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz); + while(LL_RCC_HSI_IsReady() != 1); + + UTILS_ClkInitStruct.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; + UTILS_ClkInitStruct.APB1CLKDivider = LL_RCC_APB1_DIV_1; + LL_PLL_ConfigSystemClock_HSI(&UTILS_ClkInitStruct); + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL); + + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_SetSystemCoreClock(48000000); +} + +static void APP_GPIOConfig(void) +{ + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); + LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT); +} + +void TIM1_BRK_UP_TRG_COM_IRQHandler(void) +{ + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + if(LL_TIM_IsActiveFlag_UPDATE(TIM1) && LL_TIM_IsEnabledIT_UPDATE(TIM1)) + { + // Clear interrupt flag + LL_TIM_ClearFlag_UPDATE(TIM1); + // Increase the value + val++; + // Give the semaphore so that taskUART can proceed + xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken ); + } + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void APP_ErrorHandler(void) +{ + while (1); +} \ No newline at end of file diff --git a/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.h b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.h new file mode 100644 index 0000000..e35a246 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/main.h @@ -0,0 +1,25 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "py32f0xx_ll_bus.h" +#include "py32f0xx_ll_cortex.h" +#include "py32f0xx_ll_exti.h" +#include "py32f0xx_ll_gpio.h" +#include "py32f0xx_ll_pwr.h" +#include "py32f0xx_ll_rcc.h" +#include "py32f0xx_ll_system.h" +#include "py32f0xx_ll_tim.h" +#include "py32f0xx_ll_utils.h" + + +void APP_ErrorHandler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.c b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.c new file mode 100644 index 0000000..b5abf84 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.c @@ -0,0 +1,17 @@ +#include "main.h" +#include "py32f0xx_it.h" + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + while (1); +} diff --git a/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.h b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.h new file mode 100644 index 0000000..160f858 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Binary_Semaphore/py32f0xx_it.h @@ -0,0 +1,16 @@ +#ifndef __PY32F0XX_IT_H +#define __PY32F0XX_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +void NMI_Handler(void); +void HardFault_Handler(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PY32F0XX_IT_H */ diff --git a/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/FreeRTOSConfig.h b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/FreeRTOSConfig.h new file mode 100644 index 0000000..8f7be9e --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/FreeRTOSConfig.h @@ -0,0 +1,96 @@ +/* + * FreeRTOS V202112.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 + +/*----------------------------------------------------------- + * 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 + *----------------------------------------------------------*/ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + #include + #include + extern uint32_t SystemCoreClock; +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 2 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 4 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0 + +#define configUSE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* 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 0 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 +(lowest) to 0 (1?) (highest). */ +#define configKERNEL_INTERRUPT_PRIORITY 255 +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 10-111111, or priority 2. */ + +/* Use MACRO to replace the handlers without changing startup file */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + + +#endif /* FREERTOS_CONFIG_H */ \ No newline at end of file diff --git a/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.c b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.c new file mode 100644 index 0000000..39c8b5a --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.c @@ -0,0 +1,143 @@ +/** + * Example of Counting Semaphore + * - 3 producers, each generate 255 numbers + * - 2 consumers, print the produced numbers + * + * Note: Require RAM > 6.5K Byte + */ +#include +#include "main.h" +#include "py32f0xx_bsp_printf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define QUEUE_SIZE 5 +#define PRODUCERS 3 +#define CONSUMERS 2 +#define LIMIT 0x100 + +SemaphoreHandle_t mutex; +SemaphoreHandle_t binary_sema; +SemaphoreHandle_t empty_sema; +SemaphoreHandle_t filled_sema; + +const uint16_t ids[] = {1,2,3,4,5}; +uint16_t buf[QUEUE_SIZE], from = 0, to = 0; + +static void APP_SystemClockConfig(void); +static void APP_GPIOConfig(void); + +void taskProducer(void *pvParameters) +{ + uint16_t count, id = *(uint16_t *)pvParameters; + + for (count = 0; count < LIMIT; count++) + { + xSemaphoreTake(empty_sema, portMAX_DELAY); + xSemaphoreTake(mutex, portMAX_DELAY); + buf[to] = ((id & 0xFF) << 8) + count; + to = (to + 1) % QUEUE_SIZE; + xSemaphoreGive(mutex); + xSemaphoreGive(filled_sema); + } + vTaskDelete(NULL); +} + +void taskConsumer(void *pvParameters) +{ + uint16_t id = *(uint16_t *)pvParameters; + + while (1) + { + xSemaphoreTake(filled_sema, portMAX_DELAY); + xSemaphoreTake(mutex, portMAX_DELAY); + BSP_UART_TxHex16(id); + BSP_UART_TxChar(':'); + BSP_UART_TxHex16(buf[from]); + BSP_UART_TxString("\r\n"); + from = (from + 1) % QUEUE_SIZE; + xSemaphoreGive(mutex); + xSemaphoreGive(empty_sema); + } +} + +int main(void) +{ + uint8_t i; + + APP_SystemClockConfig(); + APP_GPIOConfig(); + + BSP_USART_Config(115200); + printf("SystemClk:%ld\r\n", SystemCoreClock); + + mutex = xSemaphoreCreateMutex(); + binary_sema = xSemaphoreCreateBinary(); + empty_sema = xSemaphoreCreateCounting(QUEUE_SIZE, QUEUE_SIZE); + filled_sema = xSemaphoreCreateCounting(QUEUE_SIZE, 0); + + memset(buf, 0, QUEUE_SIZE * sizeof(uint16_t)); + + for (i = 0; i < PRODUCERS; i++) + { + printf("Producer %d\n", i); + if (xTaskCreate(taskProducer, "taskProducer", 128, (void *)&ids[i], 2, NULL) != pdPASS) + { + APP_ErrorHandler(); + } + } + + for (i = 0; i < CONSUMERS; i++) + { + printf("Consumer %d\n", i); + if (xTaskCreate(taskConsumer, "taskConsumer", 128, (void *)&ids[i], 2, NULL) != pdPASS) + { + APP_ErrorHandler(); + } + } + + printf("FreeRTOS Scheduler starting...\r\n"); + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* Will only get here if there was not enough heap space to create the idle task. */ + return 0; +} + +/** + * Set system clock to 48MHz +*/ +static void APP_SystemClockConfig(void) +{ + LL_UTILS_ClkInitTypeDef UTILS_ClkInitStruct; + + LL_RCC_HSI_Enable(); + /* Change this value to adjust frequency */ + LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz); + while(LL_RCC_HSI_IsReady() != 1); + + UTILS_ClkInitStruct.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; + UTILS_ClkInitStruct.APB1CLKDivider = LL_RCC_APB1_DIV_1; + LL_PLL_ConfigSystemClock_HSI(&UTILS_ClkInitStruct); + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL); + + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_SetSystemCoreClock(48000000); +} + +static void APP_GPIOConfig(void) +{ + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); + LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT); +} + +void APP_ErrorHandler(void) +{ + while (1); +} \ No newline at end of file diff --git a/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.h b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.h new file mode 100644 index 0000000..e35a246 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/main.h @@ -0,0 +1,25 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "py32f0xx_ll_bus.h" +#include "py32f0xx_ll_cortex.h" +#include "py32f0xx_ll_exti.h" +#include "py32f0xx_ll_gpio.h" +#include "py32f0xx_ll_pwr.h" +#include "py32f0xx_ll_rcc.h" +#include "py32f0xx_ll_system.h" +#include "py32f0xx_ll_tim.h" +#include "py32f0xx_ll_utils.h" + + +void APP_ErrorHandler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.c b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.c new file mode 100644 index 0000000..b5abf84 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.c @@ -0,0 +1,17 @@ +#include "main.h" +#include "py32f0xx_it.h" + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + while (1); +} diff --git a/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.h b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.h new file mode 100644 index 0000000..160f858 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Counting_Semaphore/py32f0xx_it.h @@ -0,0 +1,16 @@ +#ifndef __PY32F0XX_IT_H +#define __PY32F0XX_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +void NMI_Handler(void); +void HardFault_Handler(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PY32F0XX_IT_H */ diff --git a/Examples/FreeRTOS/Semaphore/LL_Mutex/FreeRTOSConfig.h b/Examples/FreeRTOS/Semaphore/LL_Mutex/FreeRTOSConfig.h new file mode 100644 index 0000000..bbd20f1 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Mutex/FreeRTOSConfig.h @@ -0,0 +1,94 @@ +/* + * FreeRTOS V202112.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 + +/*----------------------------------------------------------- + * 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 + *----------------------------------------------------------*/ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + #include + #include + extern uint32_t SystemCoreClock; +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0 + +#define configUSE_MUTEXES 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* 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_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 +(lowest) to 0 (1?) (highest). */ +#define configKERNEL_INTERRUPT_PRIORITY 255 +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 10-111111, or priority 2. */ + +/* Use MACRO to replace the handlers without changing startup file */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + + +#endif /* FREERTOS_CONFIG_H */ \ No newline at end of file diff --git a/Examples/FreeRTOS/Semaphore/LL_Mutex/main.c b/Examples/FreeRTOS/Semaphore/LL_Mutex/main.c new file mode 100644 index 0000000..81726ee --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Mutex/main.c @@ -0,0 +1,101 @@ +/** + * Example of Mutex + * + * Note: Require RAM > 4.5K Byte + */ +#include "main.h" +#include "py32f0xx_bsp_printf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +const uint8_t ids[] = {1,2,3}; +SemaphoreHandle_t mutex; +volatile uint16_t counter; + +static void APP_SystemClockConfig(void); +static void APP_GPIOConfig(void); + +void taskCount(void *pvParameters) +{ + uint8_t id = *(uint8_t *)pvParameters; + + while (1) + { + xSemaphoreTake(mutex, portMAX_DELAY); + counter++; + BSP_UART_TxHex8(id); + BSP_UART_TxChar(':'); + BSP_UART_TxHex16(counter); + BSP_UART_TxString("\r\n"); + xSemaphoreGive(mutex); + vTaskDelay(0); + } +} + +int main(void) +{ + uint8_t i; + + APP_SystemClockConfig(); + APP_GPIOConfig(); + + BSP_USART_Config(115200); + printf("SystemClk:%ld\r\n", SystemCoreClock); + + // Create mutex + mutex = xSemaphoreCreateMutex(); + // Create tasks + for (i = 0; i < 3; i++) + { + printf("Task %d\n", ids[i]); + if (xTaskCreate(taskCount, "taskProducer", configMINIMAL_STACK_SIZE, (void *)&ids[i], 2, NULL) != pdPASS) + { + APP_ErrorHandler(); + } + } + + printf("FreeRTOS Scheduler starting...\r\n"); + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* Will only get here if there was not enough heap space to create the idle task. */ + return 0; +} + +static void APP_SystemClockConfig(void) +{ + LL_UTILS_ClkInitTypeDef UTILS_ClkInitStruct; + + LL_RCC_HSI_Enable(); + /* Change this value to adjust frequency */ + LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz); + while(LL_RCC_HSI_IsReady() != 1); + + UTILS_ClkInitStruct.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; + UTILS_ClkInitStruct.APB1CLKDivider = LL_RCC_APB1_DIV_1; + LL_PLL_ConfigSystemClock_HSI(&UTILS_ClkInitStruct); + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL); + + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + /* Don't invoke this in FreeRTOS */ + // LL_InitTick(48000000, 1000U); + /* Update global SystemCoreClock(or through SystemCoreClockUpdate function) */ + LL_SetSystemCoreClock(48000000); +} + +static void APP_GPIOConfig(void) +{ + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); + LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT); +} + +void APP_ErrorHandler(void) +{ + while (1); +} diff --git a/Examples/FreeRTOS/Semaphore/LL_Mutex/main.h b/Examples/FreeRTOS/Semaphore/LL_Mutex/main.h new file mode 100644 index 0000000..5f41582 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Mutex/main.h @@ -0,0 +1,24 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "py32f0xx_ll_rcc.h" +#include "py32f0xx_ll_bus.h" +#include "py32f0xx_ll_system.h" +#include "py32f0xx_ll_exti.h" +#include "py32f0xx_ll_cortex.h" +#include "py32f0xx_ll_utils.h" +#include "py32f0xx_ll_pwr.h" +#include "py32f0xx_ll_dma.h" +#include "py32f0xx_ll_gpio.h" + +void APP_ErrorHandler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.c b/Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.c new file mode 100644 index 0000000..b5abf84 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.c @@ -0,0 +1,17 @@ +#include "main.h" +#include "py32f0xx_it.h" + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + while (1); +} diff --git a/Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.h b/Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.h new file mode 100644 index 0000000..160f858 --- /dev/null +++ b/Examples/FreeRTOS/Semaphore/LL_Mutex/py32f0xx_it.h @@ -0,0 +1,16 @@ +#ifndef __PY32F0XX_IT_H +#define __PY32F0XX_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +void NMI_Handler(void); +void HardFault_Handler(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PY32F0XX_IT_H */ diff --git a/Libraries/BSP_LL/Inc/py32f0xx_bsp_printf.h b/Libraries/BSP_LL/Inc/py32f0xx_bsp_printf.h index 4e8d6e4..ea0dc68 100644 --- a/Libraries/BSP_LL/Inc/py32f0xx_bsp_printf.h +++ b/Libraries/BSP_LL/Inc/py32f0xx_bsp_printf.h @@ -57,8 +57,13 @@ extern "C" { /************************************************************/ -void BSP_USART_Config(uint32_t baudRate); +void BSP_USART_Config(uint32_t baudRate); +void BSP_UART_TxChar(char ch); +void BSP_UART_TxHex8(uint8_t hex); +void BSP_UART_TxHex16(uint16_t hex); +void BSP_UART_TxHex32(uint32_t hex); +void BSP_UART_TxString(char *str); #ifdef __cplusplus } diff --git a/Libraries/BSP_LL/Src/py32f0xx_bsp_printf.c b/Libraries/BSP_LL/Src/py32f0xx_bsp_printf.c index 7d818db..6fae7fe 100644 --- a/Libraries/BSP_LL/Src/py32f0xx_bsp_printf.c +++ b/Libraries/BSP_LL/Src/py32f0xx_bsp_printf.c @@ -3,6 +3,46 @@ #include #include "py32f0xx_bsp_printf.h" +const char HEX_TABLE[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + +void BSP_UART_TxChar(char ch) +{ + LL_USART_TransmitData8(DEBUG_USART, ch); + while (!LL_USART_IsActiveFlag_TC(DEBUG_USART)); + LL_USART_ClearFlag_TC(DEBUG_USART); +} + +void BSP_UART_TxHex8(uint8_t hex) +{ + BSP_UART_TxChar(HEX_TABLE[(hex >> 4) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[hex & 0x0F]); +} + +void BSP_UART_TxHex16(uint16_t hex) +{ + BSP_UART_TxChar(HEX_TABLE[(hex >> 12) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 8) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 4) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[hex & 0xF]); +} + +void BSP_UART_TxHex32(uint32_t hex) +{ + BSP_UART_TxChar(HEX_TABLE[(hex >> 28) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 24) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 20) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 16) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 12) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 8) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[(hex >> 4) & 0x0F]); + BSP_UART_TxChar(HEX_TABLE[hex & 0xF]); +} + +void BSP_UART_TxString(char *str) +{ + while (*str) BSP_UART_TxChar(*str++); +} + /** * @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1 * @param None @@ -10,34 +50,34 @@ */ void BSP_USART_Config(uint32_t baudRate) { - DEBUG_USART_CLK_ENABLE(); + DEBUG_USART_CLK_ENABLE(); - /* USART Init */ - LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, baudRate); - LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B); - LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1); - LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE); - LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE); - LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX); - LL_USART_Enable(DEBUG_USART); - LL_USART_ClearFlag_TC(DEBUG_USART); + /* USART Init */ + LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, baudRate); + LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B); + LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1); + LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE); + LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE); + LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX); + LL_USART_Enable(DEBUG_USART); + LL_USART_ClearFlag_TC(DEBUG_USART); - /**USART GPIO Configuration + /**USART GPIO Configuration PA2 ------> USART1_TX PA3 ------> USART1_RX */ - DEBUG_USART_RX_GPIO_CLK_ENABLE(); - DEBUG_USART_TX_GPIO_CLK_ENABLE(); + DEBUG_USART_RX_GPIO_CLK_ENABLE(); + DEBUG_USART_TX_GPIO_CLK_ENABLE(); - LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP); - LL_GPIO_SetAFPin_0_7(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF); + LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE); + LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); + LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP); + LL_GPIO_SetAFPin_0_7(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF); - LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP); - LL_GPIO_SetAFPin_0_7(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF); + LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE); + LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); + LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP); + LL_GPIO_SetAFPin_0_7(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF); #if defined (__GNUC__) && !defined (__clang__) // To avoid io buffer