mirror of
https://github.com/No-Chicken/Power-Pico.git
synced 2026-04-03 13:02:36 +08:00
移动文件夹
This commit is contained in:
195
software/Power_Pico/Middlewares/LVGL/src/osal/lv_cmsis_rtos2.c
Normal file
195
software/Power_Pico/Middlewares/LVGL/src/osal/lv_cmsis_rtos2.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* @file lv_cmsis_rtos2.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_CMSIS_RTOS2
|
||||
|
||||
#include "../misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
|
||||
void * user_data)
|
||||
{
|
||||
static const osPriority_t prio_map[] = {
|
||||
[LV_THREAD_PRIO_LOWEST] = osPriorityLow,
|
||||
[LV_THREAD_PRIO_LOW] = osPriorityBelowNormal,
|
||||
[LV_THREAD_PRIO_MID] = osPriorityNormal,
|
||||
[LV_THREAD_PRIO_HIGH] = osPriorityHigh,
|
||||
[LV_THREAD_PRIO_HIGHEST] = osPriorityRealtime7,
|
||||
};
|
||||
|
||||
osThreadAttr_t c_tThreadAttribute = {
|
||||
.stack_size = stack_size,
|
||||
.priority = prio_map[prio],
|
||||
};
|
||||
|
||||
*thread = osThreadNew(callback, user_data, &c_tThreadAttribute);
|
||||
|
||||
if(NULL == *thread) {
|
||||
LV_LOG_WARN("Error: Failed to create a cmsis-rtos2 thread.");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||
{
|
||||
osThreadDetach(*thread);
|
||||
osStatus_t status = osThreadTerminate(*thread);
|
||||
if(status == osOK) {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex)
|
||||
{
|
||||
const osMutexAttr_t Thread_Mutex_attr = {
|
||||
"LVGLMutex",
|
||||
osMutexRecursive | osMutexPrioInherit | osMutexRobust,
|
||||
};
|
||||
|
||||
*mutex = osMutexNew(&Thread_Mutex_attr);
|
||||
if(*mutex == NULL) {
|
||||
LV_LOG_WARN("Error: failed to create cmsis-rtos mutex");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
|
||||
{
|
||||
osStatus_t status = osMutexAcquire(*mutex, 0U);
|
||||
if(status != osOK) {
|
||||
LV_LOG_WARN("Error: failed to lock cmsis-rtos2 mutex %d", (int)status);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
|
||||
{
|
||||
osStatus_t status = osMutexAcquire(*mutex, 0U);
|
||||
if(status != osOK) {
|
||||
LV_LOG_WARN("Error: failed to lock cmsis-rtos2 mutex in an ISR %d", (int)status);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
|
||||
{
|
||||
osStatus_t status = osMutexRelease(*mutex);
|
||||
if(status != osOK) {
|
||||
LV_LOG_WARN("Error: failed to release cmsis-rtos2 mutex %d", (int)status);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
|
||||
{
|
||||
osStatus_t status = osMutexDelete(*mutex);
|
||||
if(status != osOK) {
|
||||
LV_LOG_WARN("Error: failed to delete cmsis-rtos2 mutex %d", (int)status);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
|
||||
{
|
||||
*sync = osEventFlagsNew(NULL);
|
||||
if(NULL == *sync) {
|
||||
LV_LOG_WARN("Error: failed to create a cmsis-rtos2 EventFlag");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
|
||||
{
|
||||
uint32_t ret = osEventFlagsWait(*sync, 0x01, osFlagsWaitAny, osWaitForever);
|
||||
if(ret & (1 << 31)) {
|
||||
LV_LOG_WARN("Error: failed to wait a cmsis-rtos2 EventFlag %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
|
||||
{
|
||||
uint32_t ret = osEventFlagsSet(*sync, 0x01);
|
||||
if(ret & (1 << 31)) {
|
||||
LV_LOG_WARN("Error: failed to set a cmsis-rtos2 EventFlag %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
|
||||
{
|
||||
return lv_thread_sync_signal(sync);
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
|
||||
{
|
||||
osStatus_t status = osEventFlagsDelete(*sync);
|
||||
if(status != osOK) {
|
||||
LV_LOG_WARN("Error: failed to delete a cmsis-rtos2 EventFlag %d", (int)status);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_CMSIS_RTOS2*/
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @file lv_cmsis_rtos2.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef LV_CMSIS_RTOS2_H
|
||||
#define LV_CMSIS_RTOS2_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#if LV_USE_OS == LV_OS_CMSIS_RTOS2
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef osThreadId_t lv_thread_t;
|
||||
|
||||
typedef osMutexId_t lv_mutex_t;
|
||||
|
||||
typedef osEventFlagsId_t lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_CMSIS_RTOS2*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OS_CMSIS_RTOS2*/
|
||||
563
software/Power_Pico/Middlewares/LVGL/src/osal/lv_freertos.c
Normal file
563
software/Power_Pico/Middlewares/LVGL/src/osal/lv_freertos.c
Normal file
@@ -0,0 +1,563 @@
|
||||
/**
|
||||
* @file lv_freertos.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
#if LV_USE_OS == LV_OS_FREERTOS
|
||||
|
||||
#include "atomic.h"
|
||||
|
||||
#include "../tick/lv_tick.h"
|
||||
#include "../misc/lv_log.h"
|
||||
#include "../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define ulMAX_COUNT 10U
|
||||
#ifndef pcTASK_NAME
|
||||
#define pcTASK_NAME "lvglDraw"
|
||||
#endif
|
||||
|
||||
#define globals LV_GLOBAL_DEFAULT()
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void prvRunThread(void * pxArg);
|
||||
|
||||
static void prvMutexInit(lv_mutex_t * pxMutex);
|
||||
|
||||
static void prvCheckMutexInit(lv_mutex_t * pxMutex);
|
||||
|
||||
static void prvCondInit(lv_thread_sync_t * pxCond);
|
||||
|
||||
static void prvCheckCondInit(lv_thread_sync_t * pxCond);
|
||||
|
||||
static void prvCheckCondInitIsr(lv_thread_sync_t * pxCond);
|
||||
|
||||
#if !LV_USE_FREERTOS_TASK_NOTIFY
|
||||
static void prvTestAndDecrement(lv_thread_sync_t * pxCond,
|
||||
uint32_t ulLocalWaitingThreads);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if (ESP_PLATFORM)
|
||||
static portMUX_TYPE critSectionMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if (ESP_PLATFORM)
|
||||
#define _enter_critical() taskENTER_CRITICAL(&critSectionMux);
|
||||
#define _exit_critical() taskEXIT_CRITICAL(&critSectionMux);
|
||||
#define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR();
|
||||
#define _exit_critical_isr(x) taskEXIT_CRITICAL_FROM_ISR(x);
|
||||
#else
|
||||
#define _enter_critical() taskENTER_CRITICAL();
|
||||
#define _exit_critical() taskEXIT_CRITICAL();
|
||||
#define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR();
|
||||
#define _exit_critical_isr(x) taskEXIT_CRITICAL_FROM_ISR(x);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(lv_thread_t * pxThread, lv_thread_prio_t xSchedPriority,
|
||||
void (*pvStartRoutine)(void *), size_t usStackSize,
|
||||
void * xAttr)
|
||||
{
|
||||
pxThread->pTaskArg = xAttr;
|
||||
pxThread->pvStartRoutine = pvStartRoutine;
|
||||
|
||||
BaseType_t xTaskCreateStatus = xTaskCreate(
|
||||
prvRunThread,
|
||||
pcTASK_NAME,
|
||||
(configSTACK_DEPTH_TYPE)(usStackSize / sizeof(StackType_t)),
|
||||
(void *)pxThread,
|
||||
tskIDLE_PRIORITY + xSchedPriority,
|
||||
&pxThread->xTaskHandle);
|
||||
|
||||
/* Ensure that the FreeRTOS task was successfully created. */
|
||||
if(xTaskCreateStatus != pdPASS) {
|
||||
LV_LOG_ERROR("xTaskCreate failed!");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * pxThread)
|
||||
{
|
||||
vTaskDelete(pxThread->xTaskHandle);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * pxMutex)
|
||||
{
|
||||
/* If mutex in uninitialized, perform initialization. */
|
||||
prvCheckMutexInit(pxMutex);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * pxMutex)
|
||||
{
|
||||
/* If mutex in uninitialized, perform initialization. */
|
||||
prvCheckMutexInit(pxMutex);
|
||||
|
||||
BaseType_t xMutexTakeStatus = xSemaphoreTake(pxMutex->xMutex, portMAX_DELAY);
|
||||
if(xMutexTakeStatus != pdTRUE) {
|
||||
LV_LOG_ERROR("xSemaphoreTake failed!");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * pxMutex)
|
||||
{
|
||||
/* If mutex in uninitialized, perform initialization. */
|
||||
prvCheckMutexInit(pxMutex);
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
BaseType_t xMutexTakeStatus = xSemaphoreTakeFromISR(pxMutex->xMutex, &xHigherPriorityTaskWoken);
|
||||
if(xMutexTakeStatus != pdTRUE) {
|
||||
LV_LOG_ERROR("xSemaphoreTake failed!");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
|
||||
should be performed to ensure the interrupt returns directly to the highest
|
||||
priority task. The macro used for this purpose is dependent on the port in
|
||||
use and may be called portEND_SWITCHING_ISR(). */
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * pxMutex)
|
||||
{
|
||||
/* If mutex in uninitialized, perform initialization. */
|
||||
prvCheckMutexInit(pxMutex);
|
||||
|
||||
BaseType_t xMutexGiveStatus = xSemaphoreGive(pxMutex->xMutex);
|
||||
if(xMutexGiveStatus != pdTRUE) {
|
||||
LV_LOG_ERROR("xSemaphoreGive failed!");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * pxMutex)
|
||||
{
|
||||
vSemaphoreDelete(pxMutex->xMutex);
|
||||
pxMutex->xIsInitialized = pdFALSE;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvCheckCondInit(pxCond);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
lv_result_t lvRes = LV_RESULT_OK;
|
||||
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvCheckCondInit(pxCond);
|
||||
|
||||
#if LV_USE_FREERTOS_TASK_NOTIFY
|
||||
TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
|
||||
|
||||
_enter_critical();
|
||||
BaseType_t xSyncSygnal = pxCond->xSyncSignal;
|
||||
pxCond->xSyncSignal = pdFALSE;
|
||||
if(xSyncSygnal == pdFALSE) {
|
||||
/* The signal hasn't been sent yet. Tell the sender to notify this task */
|
||||
pxCond->xTaskToNotify = xCurrentTaskHandle;
|
||||
}
|
||||
/* If we have a signal from the other task, we should not ask to be notified */
|
||||
_exit_critical();
|
||||
|
||||
if(xSyncSygnal == pdFALSE) {
|
||||
/* Wait for other task to notify this task. */
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
}
|
||||
/* If the signal was received, no wait needs to be done */
|
||||
#else
|
||||
uint32_t ulLocalWaitingThreads;
|
||||
|
||||
/* Acquire the mutex. */
|
||||
xSemaphoreTake(pxCond->xSyncMutex, portMAX_DELAY);
|
||||
|
||||
while(!pxCond->xSyncSignal) {
|
||||
/* Increase the counter of threads blocking on condition variable, then
|
||||
* release the mutex. */
|
||||
|
||||
/* Atomically increments thread waiting by 1, and
|
||||
* stores number of threads waiting before increment. */
|
||||
ulLocalWaitingThreads = Atomic_Increment_u32(&pxCond->ulWaitingThreads);
|
||||
|
||||
BaseType_t xMutexStatus = xSemaphoreGive(pxCond->xSyncMutex);
|
||||
|
||||
/* Wait on the condition variable. */
|
||||
if(xMutexStatus == pdTRUE) {
|
||||
BaseType_t xCondWaitStatus = xSemaphoreTake(
|
||||
pxCond->xCondWaitSemaphore,
|
||||
portMAX_DELAY);
|
||||
|
||||
/* Relock the mutex. */
|
||||
xSemaphoreTake(pxCond->xSyncMutex, portMAX_DELAY);
|
||||
|
||||
if(xCondWaitStatus != pdTRUE) {
|
||||
LV_LOG_ERROR("xSemaphoreTake(xCondWaitSemaphore) failed!");
|
||||
lvRes = LV_RESULT_INVALID;
|
||||
|
||||
/* Atomically decrements thread waiting by 1.
|
||||
* If iLocalWaitingThreads is updated by other thread(s) in between,
|
||||
* this implementation guarantees to decrement by 1 based on the
|
||||
* value currently in pxCond->ulWaitingThreads. */
|
||||
prvTestAndDecrement(pxCond, ulLocalWaitingThreads + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LV_LOG_ERROR("xSemaphoreGive(xSyncMutex) failed!");
|
||||
lvRes = LV_RESULT_INVALID;
|
||||
|
||||
/* Atomically decrements thread waiting by 1.
|
||||
* If iLocalWaitingThreads is updated by other thread(s) in between,
|
||||
* this implementation guarantees to decrement by 1 based on the
|
||||
* value currently in pxCond->ulWaitingThreads. */
|
||||
prvTestAndDecrement(pxCond, ulLocalWaitingThreads + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pxCond->xSyncSignal = pdFALSE;
|
||||
|
||||
/* Release the mutex. */
|
||||
xSemaphoreGive(pxCond->xSyncMutex);
|
||||
#endif
|
||||
|
||||
return lvRes;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvCheckCondInit(pxCond);
|
||||
|
||||
#if LV_USE_FREERTOS_TASK_NOTIFY
|
||||
_enter_critical();
|
||||
TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify;
|
||||
pxCond->xTaskToNotify = NULL;
|
||||
if(xTaskToNotify == NULL) {
|
||||
/* No task waiting to be notified. Send this signal for later */
|
||||
pxCond->xSyncSignal = pdTRUE;
|
||||
}
|
||||
/* If a task is already waiting, there is no need to set the sync signal */
|
||||
_exit_critical();
|
||||
|
||||
if(xTaskToNotify != NULL) {
|
||||
/* There is a task waiting. Send a notification to it */
|
||||
xTaskNotifyGive(xTaskToNotify);
|
||||
}
|
||||
/* If there was no task waiting to be notified, we sent a signal for it to see later. */
|
||||
#else
|
||||
/* Acquire the mutex. */
|
||||
xSemaphoreTake(pxCond->xSyncMutex, portMAX_DELAY);
|
||||
|
||||
pxCond->xSyncSignal = pdTRUE;
|
||||
|
||||
/* Local copy of number of threads waiting. */
|
||||
uint32_t ulLocalWaitingThreads = pxCond->ulWaitingThreads;
|
||||
|
||||
/* Test local copy of threads waiting is larger than zero. */
|
||||
while(ulLocalWaitingThreads > 0) {
|
||||
/* Atomically check whether the copy in memory has changed.
|
||||
* If not, set the copy of threads waiting in memory to zero. */
|
||||
if(ATOMIC_COMPARE_AND_SWAP_SUCCESS == Atomic_CompareAndSwap_u32(
|
||||
&pxCond->ulWaitingThreads,
|
||||
0,
|
||||
ulLocalWaitingThreads)) {
|
||||
/* Unblock all. */
|
||||
for(uint32_t i = 0; i < ulLocalWaitingThreads; i++) {
|
||||
xSemaphoreGive(pxCond->xCondWaitSemaphore);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Local copy is out dated. Reload from memory and retry. */
|
||||
ulLocalWaitingThreads = pxCond->ulWaitingThreads;
|
||||
}
|
||||
|
||||
/* Release the mutex. */
|
||||
xSemaphoreGive(pxCond->xSyncMutex);
|
||||
#endif
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
#if !LV_USE_FREERTOS_TASK_NOTIFY
|
||||
/* Cleanup all resources used by the cond. */
|
||||
vSemaphoreDelete(pxCond->xCondWaitSemaphore);
|
||||
vSemaphoreDelete(pxCond->xSyncMutex);
|
||||
pxCond->ulWaitingThreads = 0;
|
||||
#endif
|
||||
pxCond->xSyncSignal = pdFALSE;
|
||||
pxCond->xIsInitialized = pdFALSE;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvCheckCondInitIsr(pxCond);
|
||||
|
||||
#if LV_USE_FREERTOS_TASK_NOTIFY
|
||||
uint32_t mask = _enter_critical_isr();
|
||||
TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify;
|
||||
pxCond->xTaskToNotify = NULL;
|
||||
if(xTaskToNotify == NULL) {
|
||||
/* No task waiting to be notified. Send this signal for later */
|
||||
pxCond->xSyncSignal = pdTRUE;
|
||||
}
|
||||
/* If a task is already waiting, there is no need to set the sync signal */
|
||||
_exit_critical_isr(mask);
|
||||
|
||||
if(xTaskToNotify != NULL) {
|
||||
/* There is a task waiting. Send a notification to it */
|
||||
vTaskNotifyGiveFromISR(xTaskToNotify, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
/* If there was no task waiting to be notified, we sent a signal for it to see later. */
|
||||
#else
|
||||
/* Enter critical section to prevent preemption. */
|
||||
uint32_t mask = _enter_critical_isr();
|
||||
|
||||
pxCond->xSyncSignal = pdTRUE;
|
||||
BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
/* Unblock all. */
|
||||
for(uint32_t i = 0; i < pxCond->ulWaitingThreads; i++) {
|
||||
xSemaphoreGiveFromISR(pxCond->xCondWaitSemaphore, &xAnyHigherPriorityTaskWoken);
|
||||
xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken;
|
||||
}
|
||||
|
||||
_exit_critical_isr(mask);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
#endif
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
void lv_freertos_task_switch_in(const char * name)
|
||||
{
|
||||
if(lv_strcmp(name, "IDLE")) globals->freertos_idle_task_running = false;
|
||||
else globals->freertos_idle_task_running = true;
|
||||
|
||||
globals->freertos_task_switch_timestamp = lv_tick_get();
|
||||
}
|
||||
|
||||
void lv_freertos_task_switch_out(void)
|
||||
{
|
||||
uint32_t elaps = lv_tick_elaps(globals->freertos_task_switch_timestamp);
|
||||
if(globals->freertos_idle_task_running) globals->freertos_idle_time_sum += elaps;
|
||||
else globals->freertos_non_idle_time_sum += elaps;
|
||||
}
|
||||
|
||||
uint32_t lv_os_get_idle_percent(void)
|
||||
{
|
||||
if(globals->freertos_non_idle_time_sum + globals->freertos_idle_time_sum == 0) {
|
||||
LV_LOG_WARN("Not enough time elapsed to provide idle percentage");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t pct = (globals->freertos_idle_time_sum * 100) / (globals->freertos_idle_time_sum +
|
||||
globals->freertos_non_idle_time_sum);
|
||||
|
||||
globals->freertos_non_idle_time_sum = 0;
|
||||
globals->freertos_idle_time_sum = 0;
|
||||
|
||||
return pct;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void prvRunThread(void * pxArg)
|
||||
{
|
||||
lv_thread_t * pxThread = (lv_thread_t *)pxArg;
|
||||
|
||||
/* Run the thread routine. */
|
||||
pxThread->pvStartRoutine((void *)pxThread->pTaskArg);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void prvMutexInit(lv_mutex_t * pxMutex)
|
||||
{
|
||||
pxMutex->xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
|
||||
/* Ensure that the FreeRTOS mutex was successfully created. */
|
||||
if(pxMutex->xMutex == NULL) {
|
||||
LV_LOG_ERROR("xSemaphoreCreateMutex failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mutex successfully created. */
|
||||
pxMutex->xIsInitialized = pdTRUE;
|
||||
}
|
||||
|
||||
static void prvCheckMutexInit(lv_mutex_t * pxMutex)
|
||||
{
|
||||
/* Check if the mutex needs to be initialized. */
|
||||
if(pxMutex->xIsInitialized == pdFALSE) {
|
||||
/* Mutex initialization must be in a critical section to prevent two threads
|
||||
* from initializing it at the same time. */
|
||||
_enter_critical();
|
||||
|
||||
/* Check again that the mutex is still uninitialized, i.e. it wasn't
|
||||
* initialized while this function was waiting to enter the critical
|
||||
* section. */
|
||||
if(pxMutex->xIsInitialized == pdFALSE) {
|
||||
prvMutexInit(pxMutex);
|
||||
}
|
||||
|
||||
/* Exit the critical section. */
|
||||
_exit_critical();
|
||||
}
|
||||
}
|
||||
|
||||
static void prvCondInit(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
pxCond->xIsInitialized = pdTRUE;
|
||||
pxCond->xSyncSignal = pdFALSE;
|
||||
|
||||
#if LV_USE_FREERTOS_TASK_NOTIFY
|
||||
pxCond->xTaskToNotify = NULL;
|
||||
#else
|
||||
pxCond->xCondWaitSemaphore = xSemaphoreCreateCounting(ulMAX_COUNT, 0U);
|
||||
|
||||
/* Ensure that the FreeRTOS semaphore was successfully created. */
|
||||
if(pxCond->xCondWaitSemaphore == NULL) {
|
||||
LV_LOG_ERROR("xSemaphoreCreateCounting failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
pxCond->xSyncMutex = xSemaphoreCreateMutex();
|
||||
|
||||
/* Ensure that the FreeRTOS mutex was successfully created. */
|
||||
if(pxCond->xSyncMutex == NULL) {
|
||||
LV_LOG_ERROR("xSemaphoreCreateMutex failed!");
|
||||
/* Cleanup. */
|
||||
vSemaphoreDelete(pxCond->xCondWaitSemaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Condition variable successfully created. */
|
||||
pxCond->ulWaitingThreads = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void prvCheckCondInit(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
/* Check if the condition variable needs to be initialized. */
|
||||
if(pxCond->xIsInitialized == pdFALSE) {
|
||||
/* Cond initialization must be in a critical section to prevent two
|
||||
* threads from initializing it at the same time. */
|
||||
_enter_critical();
|
||||
|
||||
/* Check again that the condition is still uninitialized, i.e. it wasn't
|
||||
* initialized while this function was waiting to enter the critical
|
||||
* section. */
|
||||
if(pxCond->xIsInitialized == pdFALSE) {
|
||||
prvCondInit(pxCond);
|
||||
}
|
||||
|
||||
/* Exit the critical section. */
|
||||
_exit_critical();
|
||||
}
|
||||
}
|
||||
|
||||
static void prvCheckCondInitIsr(lv_thread_sync_t * pxCond)
|
||||
{
|
||||
/* Check if the condition variable needs to be initialized. */
|
||||
if(pxCond->xIsInitialized == pdFALSE) {
|
||||
/* Cond initialization must be in a critical section to prevent two
|
||||
* threads from initializing it at the same time. */
|
||||
uint32_t mask = _enter_critical_isr();
|
||||
|
||||
/* Check again that the condition is still uninitialized, i.e. it wasn't
|
||||
* initialized while this function was waiting to enter the critical
|
||||
* section. */
|
||||
if(pxCond->xIsInitialized == pdFALSE) {
|
||||
prvCondInit(pxCond);
|
||||
}
|
||||
|
||||
/* Exit the critical section. */
|
||||
_exit_critical_isr(mask);
|
||||
}
|
||||
}
|
||||
|
||||
#if !LV_USE_FREERTOS_TASK_NOTIFY
|
||||
static void prvTestAndDecrement(lv_thread_sync_t * pxCond,
|
||||
uint32_t ulLocalWaitingThreads)
|
||||
{
|
||||
/* Test local copy of threads waiting is larger than zero. */
|
||||
while(ulLocalWaitingThreads > 0) {
|
||||
/* Atomically check whether the copy in memory has changed.
|
||||
* If not, decrease the copy of threads waiting in memory. */
|
||||
if(ATOMIC_COMPARE_AND_SWAP_SUCCESS == Atomic_CompareAndSwap_u32(
|
||||
&pxCond->ulWaitingThreads,
|
||||
ulLocalWaitingThreads - 1,
|
||||
ulLocalWaitingThreads)) {
|
||||
/* Signal one succeeded. Break. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Local copy may be out dated. Reload from memory and retry. */
|
||||
ulLocalWaitingThreads = pxCond->ulWaitingThreads;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_FREERTOS*/
|
||||
105
software/Power_Pico/Middlewares/LVGL/src/osal/lv_freertos.h
Normal file
105
software/Power_Pico/Middlewares/LVGL/src/osal/lv_freertos.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @file lv_freertos.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_FREERTOS_H
|
||||
#define LV_FREERTOS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_FREERTOS
|
||||
|
||||
#if (ESP_PLATFORM)
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
void (*pvStartRoutine)(void *); /**< Application thread function. */
|
||||
void * pTaskArg; /**< Arguments for application thread function. */
|
||||
TaskHandle_t xTaskHandle; /**< FreeRTOS task handle. */
|
||||
} lv_thread_t;
|
||||
|
||||
typedef struct {
|
||||
BaseType_t xIsInitialized; /**< Set to pdTRUE if this mutex is initialized, pdFALSE otherwise. */
|
||||
SemaphoreHandle_t xMutex; /**< FreeRTOS mutex. */
|
||||
} lv_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
BaseType_t
|
||||
xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */
|
||||
BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */
|
||||
#if LV_USE_FREERTOS_TASK_NOTIFY
|
||||
TaskHandle_t xTaskToNotify; /**< The task waiting to be signalled. NULL if nothing is waiting. */
|
||||
#else
|
||||
SemaphoreHandle_t xCondWaitSemaphore; /**< Threads block on this semaphore in lv_thread_sync_wait. */
|
||||
uint32_t ulWaitingThreads; /**< The number of threads currently waiting on this condition variable. */
|
||||
SemaphoreHandle_t xSyncMutex; /**< Threads take this mutex before accessing the condition variable. */
|
||||
#endif
|
||||
} lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Set it for `traceTASK_SWITCHED_IN()` as
|
||||
* `lv_freertos_task_switch_in(pxCurrentTCB->pcTaskName)`
|
||||
* to save the start time stamp of a task
|
||||
* @param name the name of the which is switched in
|
||||
*/
|
||||
void lv_freertos_task_switch_in(const char * name);
|
||||
|
||||
/**
|
||||
* Set it for `traceTASK_SWITCHED_OUT()` as
|
||||
* `lv_freertos_task_switch_out()`
|
||||
* to save finish time stamp of a task
|
||||
*/
|
||||
void lv_freertos_task_switch_out(void);
|
||||
|
||||
/**
|
||||
* Set it for `LV_SYSMON_GET_IDLE` to show the CPU usage
|
||||
* as reported based the usage of FreeRTOS's idle task
|
||||
* If it's important when a GPU is used.
|
||||
* @return the idle percentage since the last call
|
||||
*/
|
||||
uint32_t lv_os_get_idle_percent(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_FREERTOS*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_FREERTOS_H*/
|
||||
169
software/Power_Pico/Middlewares/LVGL/src/osal/lv_mqx.c
Normal file
169
software/Power_Pico/Middlewares/LVGL/src/osal/lv_mqx.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @file lv_mqx.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_MQX
|
||||
|
||||
#include "../misc/lv_log.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
|
||||
void * user_data)
|
||||
{
|
||||
TASK_TEMPLATE_STRUCT task_template;
|
||||
|
||||
lv_memzero(&task_template, sizeof(task_template));
|
||||
|
||||
task_template.TASK_ADDRESS = (TASK_FPTR)callback;
|
||||
task_template.TASK_STACKSIZE = stack_size;
|
||||
task_template.TASK_PRIORITY = _sched_get_min_priority(0) - prio;
|
||||
task_template.TASK_NAME = "lvglDraw";
|
||||
task_template.CREATION_PARAMETER = (uint32_t)user_data;
|
||||
|
||||
*thread = _task_create(0, 0, (uint32_t)&task_template);
|
||||
if(*thread == MQX_NULL_TASK_ID) {
|
||||
LV_LOG_WARN("_task_create failed!");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||
{
|
||||
_mqx_uint ret = _task_destroy(*thread);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("_task_destroy failed!");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex)
|
||||
{
|
||||
if(MQX_OK != _mutex_init(mutex, NULL)) {
|
||||
LV_LOG_WARN("create mutex failed");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
|
||||
{
|
||||
_mqx_uint ret = _mutex_lock(mutex);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
|
||||
{
|
||||
_mqx_uint ret = _mutex_lock(mutex);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
|
||||
{
|
||||
_mqx_uint ret = _mutex_unlock(mutex);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
|
||||
{
|
||||
_mqx_uint ret = _mutex_destroy(mutex);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
|
||||
{
|
||||
if(MQX_OK != _lwsem_create(sync, 0)) {
|
||||
LV_LOG_WARN("create semaphore failed");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
|
||||
{
|
||||
_mqx_uint ret = _lwsem_wait(sync);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
|
||||
{
|
||||
_mqx_uint ret = _lwsem_post(sync);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
|
||||
{
|
||||
_mqx_uint ret = _lwsem_destroy(sync);
|
||||
if(ret != MQX_OK) {
|
||||
LV_LOG_WARN("Error: %x", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_MQX*/
|
||||
51
software/Power_Pico/Middlewares/LVGL/src/osal/lv_mqx.h
Normal file
51
software/Power_Pico/Middlewares/LVGL/src/osal/lv_mqx.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file lv_mqx.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_MQX_H
|
||||
#define LV_MQX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_MQX
|
||||
|
||||
#include "mqx.h"
|
||||
#include "mutex.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef _task_id lv_thread_t;
|
||||
|
||||
typedef MUTEX_STRUCT lv_mutex_t;
|
||||
|
||||
typedef LWSEM_STRUCT lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_MQX*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_MQX_H*/
|
||||
71
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os.c
Normal file
71
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file lv_os.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
#include "lv_os_private.h"
|
||||
#include "../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define lv_general_mutex LV_GLOBAL_DEFAULT()->lv_general_mutex
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_os_init(void)
|
||||
{
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
lv_mutex_init(&lv_general_mutex);
|
||||
#endif /*LV_USE_OS != LV_OS_NONE*/
|
||||
}
|
||||
|
||||
void lv_lock(void)
|
||||
{
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
lv_mutex_lock(&lv_general_mutex);
|
||||
#endif /*LV_USE_OS != LV_OS_NONE*/
|
||||
}
|
||||
|
||||
lv_result_t lv_lock_isr(void)
|
||||
{
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
return lv_mutex_lock_isr(&lv_general_mutex);
|
||||
#else /*LV_USE_OS != LV_OS_NONE*/
|
||||
return LV_RESULT_OK;
|
||||
#endif /*LV_USE_OS != LV_OS_NONE*/
|
||||
}
|
||||
|
||||
void lv_unlock(void)
|
||||
{
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
lv_mutex_unlock(&lv_general_mutex);
|
||||
#endif /*LV_USE_OS != LV_OS_NONE*/
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
186
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os.h
Normal file
186
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* @file lv_os.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OS_H
|
||||
#define LV_OS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* OS OPTIONS
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_NONE
|
||||
#include "lv_os_none.h"
|
||||
#elif LV_USE_OS == LV_OS_PTHREAD
|
||||
#include "lv_pthread.h"
|
||||
#elif LV_USE_OS == LV_OS_FREERTOS
|
||||
#include "lv_freertos.h"
|
||||
#elif LV_USE_OS == LV_OS_CMSIS_RTOS2
|
||||
#include "lv_cmsis_rtos2.h"
|
||||
#elif LV_USE_OS == LV_OS_RTTHREAD
|
||||
#include "lv_rtthread.h"
|
||||
#elif LV_USE_OS == LV_OS_WINDOWS
|
||||
#include "lv_windows.h"
|
||||
#elif LV_USE_OS == LV_OS_MQX
|
||||
#include "lv_mqx.h"
|
||||
#elif LV_USE_OS == LV_OS_CUSTOM
|
||||
#include LV_OS_CUSTOM_INCLUDE
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef enum {
|
||||
LV_THREAD_PRIO_LOWEST,
|
||||
LV_THREAD_PRIO_LOW,
|
||||
LV_THREAD_PRIO_MID,
|
||||
LV_THREAD_PRIO_HIGH,
|
||||
LV_THREAD_PRIO_HIGHEST,
|
||||
} lv_thread_prio_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*----------------------------------------
|
||||
* These functions needs to be implemented
|
||||
* for specific operating systems
|
||||
*---------------------------------------*/
|
||||
|
||||
/**
|
||||
* Create a new thread
|
||||
* @param thread a variable in which the thread will be stored
|
||||
* @param prio priority of the thread
|
||||
* @param callback function of the thread
|
||||
* @param stack_size stack size in bytes
|
||||
* @param user_data arbitrary data, will be available in the callback
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
|
||||
void * user_data);
|
||||
|
||||
/**
|
||||
* Delete a thread
|
||||
* @param thread the thread to delete
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread);
|
||||
|
||||
/**
|
||||
* Create a mutex
|
||||
* @param mutex a variable in which the thread will be stored
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex);
|
||||
|
||||
/**
|
||||
* Lock a mutex
|
||||
* @param mutex the mutex to lock
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex);
|
||||
|
||||
/**
|
||||
* Lock a mutex from interrupt
|
||||
* @param mutex the mutex to lock
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex);
|
||||
|
||||
/**
|
||||
* Unlock a mutex
|
||||
* @param mutex the mutex to unlock
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex);
|
||||
|
||||
/**
|
||||
* Delete a mutex
|
||||
* @param mutex the mutex to delete
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex);
|
||||
|
||||
/**
|
||||
* Create a thread synchronization object
|
||||
* @param sync a variable in which the sync will be stored
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync);
|
||||
|
||||
/**
|
||||
* Wait for a "signal" on a sync object
|
||||
* @param sync a sync object
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync);
|
||||
|
||||
/**
|
||||
* Send a wake-up signal to a sync object
|
||||
* @param sync a sync object
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync);
|
||||
|
||||
/**
|
||||
* Send a wake-up signal to a sync object from interrupt
|
||||
* @param sync a sync object
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync);
|
||||
|
||||
/**
|
||||
* Delete a sync object
|
||||
* @param sync a sync object to delete
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync);
|
||||
|
||||
/**
|
||||
* Lock LVGL's general mutex.
|
||||
* LVGL is not thread safe, so a mutex is used to avoid executing multiple LVGL functions at the same time
|
||||
* from different threads. It shall be called when calling LVGL functions from threads
|
||||
* different than lv_timer_handler's thread. It doesn't need to be called in LVGL events because
|
||||
* they are called from lv_timer_handler().
|
||||
* It is called internally in lv_timer_handler().
|
||||
*/
|
||||
void lv_lock(void);
|
||||
|
||||
/**
|
||||
* Same as `lv_lock()` but can be called from an interrupt.
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure
|
||||
*/
|
||||
lv_result_t lv_lock_isr(void);
|
||||
|
||||
/**
|
||||
* The pair of `lv_lock()` and `lv_lock_isr()`.
|
||||
* It unlocks LVGL general mutex.
|
||||
* It is called internally in lv_timer_handler().
|
||||
*/
|
||||
void lv_unlock(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OS_H*/
|
||||
127
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os_none.c
Normal file
127
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os_none.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* @file lv_os_none.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_NONE
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_assert.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
|
||||
void * user_data)
|
||||
{
|
||||
LV_UNUSED(thread);
|
||||
LV_UNUSED(callback);
|
||||
LV_UNUSED(prio);
|
||||
LV_UNUSED(stack_size);
|
||||
LV_UNUSED(user_data);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||
{
|
||||
LV_UNUSED(thread);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex)
|
||||
{
|
||||
LV_UNUSED(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
|
||||
{
|
||||
LV_UNUSED(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
|
||||
{
|
||||
LV_UNUSED(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
|
||||
{
|
||||
LV_UNUSED(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
|
||||
{
|
||||
LV_UNUSED(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
LV_ASSERT(0);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_NONE*/
|
||||
43
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os_none.h
Normal file
43
software/Power_Pico/Middlewares/LVGL/src/osal/lv_os_none.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file lv_os_none.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OS_NONE_H
|
||||
#define LV_OS_NONE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#if LV_USE_OS == LV_OS_NONE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef int lv_mutex_t;
|
||||
typedef int lv_thread_t;
|
||||
typedef int lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_NONE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OS_NONE_H*/
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file lv_os_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OS_PRIVATE_H
|
||||
#define LV_OS_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* OS OPTIONS
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the OS layer
|
||||
*/
|
||||
void lv_os_init(void);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OS_PRIVATE_H*/
|
||||
178
software/Power_Pico/Middlewares/LVGL/src/osal/lv_pthread.c
Normal file
178
software/Power_Pico/Middlewares/LVGL/src/osal/lv_pthread.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* @file lv_pthread.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_PTHREAD
|
||||
|
||||
#include <errno.h>
|
||||
#include "../misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void * generic_callback(void * user_data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
|
||||
void * user_data)
|
||||
{
|
||||
LV_UNUSED(prio);
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
thread->callback = callback;
|
||||
thread->user_data = user_data;
|
||||
pthread_create(&thread->thread, &attr, generic_callback, thread);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||
{
|
||||
int ret = pthread_join(thread->thread, NULL);
|
||||
if(ret != 0) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
int ret = pthread_mutex_init(mutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
|
||||
{
|
||||
int ret = pthread_mutex_lock(mutex);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
|
||||
{
|
||||
int ret = pthread_mutex_lock(mutex);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
|
||||
{
|
||||
int ret = pthread_mutex_unlock(mutex);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
|
||||
{
|
||||
pthread_mutex_destroy(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
|
||||
{
|
||||
pthread_mutex_init(&sync->mutex, 0);
|
||||
pthread_cond_init(&sync->cond, 0);
|
||||
sync->v = false;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
|
||||
{
|
||||
pthread_mutex_lock(&sync->mutex);
|
||||
while(!sync->v) {
|
||||
pthread_cond_wait(&sync->cond, &sync->mutex);
|
||||
}
|
||||
sync->v = false;
|
||||
pthread_mutex_unlock(&sync->mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
|
||||
{
|
||||
pthread_mutex_lock(&sync->mutex);
|
||||
sync->v = true;
|
||||
pthread_cond_signal(&sync->cond);
|
||||
pthread_mutex_unlock(&sync->mutex);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
|
||||
{
|
||||
pthread_mutex_destroy(&sync->mutex);
|
||||
pthread_cond_destroy(&sync->cond);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void * generic_callback(void * user_data)
|
||||
{
|
||||
lv_thread_t * thread = user_data;
|
||||
thread->callback(thread->user_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_PTHREAD*/
|
||||
57
software/Power_Pico/Middlewares/LVGL/src/osal/lv_pthread.h
Normal file
57
software/Power_Pico/Middlewares/LVGL/src/osal/lv_pthread.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file lv_pthread.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_PTHREAD_H
|
||||
#define LV_PTHREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#if LV_USE_OS == LV_OS_PTHREAD
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
pthread_t thread;
|
||||
void (*callback)(void *);
|
||||
void * user_data;
|
||||
} lv_thread_t;
|
||||
|
||||
typedef pthread_mutex_t lv_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
bool v;
|
||||
} lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_PTHREAD*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_PTHREAD_H*/
|
||||
190
software/Power_Pico/Middlewares/LVGL/src/osal/lv_rtthread.c
Normal file
190
software/Power_Pico/Middlewares/LVGL/src/osal/lv_rtthread.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* @file lv_rtthread.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_RTTHREAD
|
||||
|
||||
#include "../misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define THREAD_TIMESLICE 20U
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size,
|
||||
void * user_data)
|
||||
{
|
||||
thread->thread = rt_thread_create("thread",
|
||||
callback,
|
||||
user_data,
|
||||
stack_size,
|
||||
prio,
|
||||
THREAD_TIMESLICE);
|
||||
rt_err_t ret = rt_thread_startup(thread->thread);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||
{
|
||||
rt_err_t ret = rt_thread_delete(thread->thread);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex)
|
||||
{
|
||||
mutex->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_PRIO);
|
||||
if(mutex->mutex == RT_NULL) {
|
||||
LV_LOG_WARN("create mutex failed");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
|
||||
{
|
||||
rt_err_t ret = rt_mutex_take(mutex->mutex, RT_WAITING_FOREVER);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
|
||||
{
|
||||
rt_err_t ret = rt_mutex_take(mutex->mutex, RT_WAITING_FOREVER);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
|
||||
{
|
||||
rt_err_t ret = rt_mutex_release(mutex->mutex);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
|
||||
{
|
||||
rt_err_t ret = rt_mutex_delete(mutex->mutex);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
|
||||
{
|
||||
sync->sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO);
|
||||
if(sync->sem == RT_NULL) {
|
||||
LV_LOG_WARN("create semaphore failed");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
|
||||
{
|
||||
rt_err_t ret = rt_sem_take(sync->sem, RT_WAITING_FOREVER);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
|
||||
{
|
||||
rt_err_t ret = rt_sem_release(sync->sem);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
|
||||
{
|
||||
rt_err_t ret = rt_sem_delete(sync->sem);
|
||||
if(ret) {
|
||||
LV_LOG_WARN("Error: %d", ret);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_RTTHREAD*/
|
||||
54
software/Power_Pico/Middlewares/LVGL/src/osal/lv_rtthread.h
Normal file
54
software/Power_Pico/Middlewares/LVGL/src/osal/lv_rtthread.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file lv_rtthread.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_RTTHREAD_H
|
||||
#define LV_RTTHREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#if LV_USE_OS == LV_OS_RTTHREAD
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
rt_thread_t thread;
|
||||
} lv_thread_t;
|
||||
|
||||
typedef struct {
|
||||
rt_mutex_t mutex;
|
||||
} lv_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
rt_sem_t sem;
|
||||
} lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_RTTHREAD*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_RTTHREAD_H*/
|
||||
222
software/Power_Pico/Middlewares/LVGL/src/osal/lv_windows.c
Normal file
222
software/Power_Pico/Middlewares/LVGL/src/osal/lv_windows.c
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* @file lv_windows.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_os.h"
|
||||
|
||||
#if LV_USE_OS == LV_OS_WINDOWS
|
||||
|
||||
#include <process.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
void (*callback)(void *);
|
||||
void * user_data;
|
||||
} lv_thread_init_data_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static unsigned __stdcall thread_start_routine(void * parameter);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_thread_init(
|
||||
lv_thread_t * thread,
|
||||
lv_thread_prio_t prio,
|
||||
void (*callback)(void *),
|
||||
size_t stack_size,
|
||||
void * user_data)
|
||||
{
|
||||
if(!thread) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
static const int prio_map[] = {
|
||||
[LV_THREAD_PRIO_LOWEST] = THREAD_PRIORITY_LOWEST,
|
||||
[LV_THREAD_PRIO_LOW] = THREAD_PRIORITY_BELOW_NORMAL,
|
||||
[LV_THREAD_PRIO_MID] = THREAD_PRIORITY_NORMAL,
|
||||
[LV_THREAD_PRIO_HIGH] = THREAD_PRIORITY_ABOVE_NORMAL,
|
||||
[LV_THREAD_PRIO_HIGHEST] = THREAD_PRIORITY_HIGHEST,
|
||||
};
|
||||
|
||||
lv_thread_init_data_t * init_data =
|
||||
(lv_thread_init_data_t *)(malloc(
|
||||
sizeof(lv_thread_init_data_t)));
|
||||
if(!init_data) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
init_data->callback = callback;
|
||||
init_data->user_data = user_data;
|
||||
|
||||
/*
|
||||
Reference: https://learn.microsoft.com/en-us/windows/win32/api
|
||||
/processthreadsapi/nf-processthreadsapi-createthread
|
||||
|
||||
A thread in an executable that calls the C run-time library (CRT) should
|
||||
use the _beginthreadex and _endthreadex functions for thread management
|
||||
rather than CreateThread and ExitThread; this requires the use of the
|
||||
multithreaded version of the CRT. If a thread created using CreateThread
|
||||
calls the CRT, the CRT may terminate the process in low-memory conditions.
|
||||
*/
|
||||
*thread = (HANDLE)(_beginthreadex(
|
||||
NULL,
|
||||
(unsigned)(stack_size),
|
||||
thread_start_routine,
|
||||
init_data,
|
||||
0,
|
||||
NULL));
|
||||
if(!*thread) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
Try to set the thread priority. (Not mandatory for creating a new thread.)
|
||||
*/
|
||||
SetThreadPriority(*thread, prio_map[prio]);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||
{
|
||||
lv_result_t result = LV_RESULT_OK;
|
||||
|
||||
if(!TerminateThread(thread, 0)) {
|
||||
result = LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
CloseHandle(thread);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_init(lv_mutex_t * mutex)
|
||||
{
|
||||
InitializeCriticalSection(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
|
||||
{
|
||||
EnterCriticalSection(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
|
||||
{
|
||||
EnterCriticalSection(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
|
||||
{
|
||||
LeaveCriticalSection(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
|
||||
{
|
||||
DeleteCriticalSection(mutex);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
|
||||
{
|
||||
if(!sync) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&sync->cs);
|
||||
InitializeConditionVariable(&sync->cv);
|
||||
sync->v = false;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
|
||||
{
|
||||
if(!sync) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&sync->cs);
|
||||
while(!sync->v) {
|
||||
SleepConditionVariableCS(&sync->cv, &sync->cs, INFINITE);
|
||||
}
|
||||
sync->v = false;
|
||||
LeaveCriticalSection(&sync->cs);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
|
||||
{
|
||||
if(!sync) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&sync->cs);
|
||||
sync->v = true;
|
||||
WakeConditionVariable(&sync->cv);
|
||||
LeaveCriticalSection(&sync->cs);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
|
||||
{
|
||||
if(!sync) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&sync->cs);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
|
||||
{
|
||||
LV_UNUSED(sync);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static unsigned __stdcall thread_start_routine(void * parameter)
|
||||
{
|
||||
lv_thread_init_data_t * init_data = (lv_thread_init_data_t *)(parameter);
|
||||
if(init_data) {
|
||||
init_data->callback(init_data->user_data);
|
||||
free(init_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_WINDOWS*/
|
||||
54
software/Power_Pico/Middlewares/LVGL/src/osal/lv_windows.h
Normal file
54
software/Power_Pico/Middlewares/LVGL/src/osal/lv_windows.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file lv_windows.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_WINDOWS_H
|
||||
#define LV_WINDOWS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_OS == LV_OS_WINDOWS
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef HANDLE lv_thread_t;
|
||||
|
||||
typedef CRITICAL_SECTION lv_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
CRITICAL_SECTION cs;
|
||||
CONDITION_VARIABLE cv;
|
||||
bool v;
|
||||
} lv_thread_sync_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_OS == LV_OS_WINDOWS*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_WINDOWS_H*/
|
||||
Reference in New Issue
Block a user