* Furi: remove CMSIS thread api, migrate to FuriThread, remove unused CMSIS APIs * Furi: magic thread catcher validating thread completion; backtrace improver * Furi: allow furi_thread_get_current_id outside of thread context * Furi: use IRQ instead of ISR for core primitives
		
			
				
	
	
		
			218 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "mutex.h"
 | 
						|
#include "check.h"
 | 
						|
#include "common_defines.h"
 | 
						|
 | 
						|
#include <semphr.h>
 | 
						|
 | 
						|
osMutexId_t osMutexNew(const osMutexAttr_t* attr) {
 | 
						|
    SemaphoreHandle_t hMutex;
 | 
						|
    uint32_t type;
 | 
						|
    uint32_t rmtx;
 | 
						|
    int32_t mem;
 | 
						|
 | 
						|
    hMutex = NULL;
 | 
						|
 | 
						|
    if(FURI_IS_IRQ_MODE() == 0U) {
 | 
						|
        if(attr != NULL) {
 | 
						|
            type = attr->attr_bits;
 | 
						|
        } else {
 | 
						|
            type = 0U;
 | 
						|
        }
 | 
						|
 | 
						|
        if((type & osMutexRecursive) == osMutexRecursive) {
 | 
						|
            rmtx = 1U;
 | 
						|
        } else {
 | 
						|
            rmtx = 0U;
 | 
						|
        }
 | 
						|
 | 
						|
        if((type & osMutexRobust) != osMutexRobust) {
 | 
						|
            mem = -1;
 | 
						|
 | 
						|
            if(attr != NULL) {
 | 
						|
                if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
 | 
						|
                    /* The memory for control block is provided, use static object */
 | 
						|
                    mem = 1;
 | 
						|
                } else {
 | 
						|
                    if((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
 | 
						|
                        /* Control block will be allocated from the dynamic pool */
 | 
						|
                        mem = 0;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                mem = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            if(mem == 1) {
 | 
						|
#if(configSUPPORT_STATIC_ALLOCATION == 1)
 | 
						|
                if(rmtx != 0U) {
 | 
						|
#if(configUSE_RECURSIVE_MUTEXES == 1)
 | 
						|
                    hMutex = xSemaphoreCreateRecursiveMutexStatic(attr->cb_mem);
 | 
						|
#endif
 | 
						|
                } else {
 | 
						|
                    hMutex = xSemaphoreCreateMutexStatic(attr->cb_mem);
 | 
						|
                }
 | 
						|
#endif
 | 
						|
            } else {
 | 
						|
                if(mem == 0) {
 | 
						|
#if(configSUPPORT_DYNAMIC_ALLOCATION == 1)
 | 
						|
                    if(rmtx != 0U) {
 | 
						|
#if(configUSE_RECURSIVE_MUTEXES == 1)
 | 
						|
                        hMutex = xSemaphoreCreateRecursiveMutex();
 | 
						|
#endif
 | 
						|
                    } else {
 | 
						|
                        hMutex = xSemaphoreCreateMutex();
 | 
						|
                    }
 | 
						|
#endif
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
#if(configQUEUE_REGISTRY_SIZE > 0)
 | 
						|
            if(hMutex != NULL) {
 | 
						|
                if((attr != NULL) && (attr->name != NULL)) {
 | 
						|
                    /* Only non-NULL name objects are added to the Queue Registry */
 | 
						|
                    vQueueAddToRegistry(hMutex, attr->name);
 | 
						|
                }
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
            if((hMutex != NULL) && (rmtx != 0U)) {
 | 
						|
                /* Set LSB as 'recursive mutex flag' */
 | 
						|
                hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* Return mutex ID */
 | 
						|
    return ((osMutexId_t)hMutex);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
    Acquire a Mutex or timeout if it is locked.
 | 
						|
*/
 | 
						|
osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) {
 | 
						|
    SemaphoreHandle_t hMutex;
 | 
						|
    osStatus_t stat;
 | 
						|
    uint32_t rmtx;
 | 
						|
 | 
						|
    hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
 | 
						|
 | 
						|
    /* Extract recursive mutex flag */
 | 
						|
    rmtx = (uint32_t)mutex_id & 1U;
 | 
						|
 | 
						|
    stat = osOK;
 | 
						|
 | 
						|
    if(FURI_IS_IRQ_MODE() != 0U) {
 | 
						|
        stat = osErrorISR;
 | 
						|
    } else if(hMutex == NULL) {
 | 
						|
        stat = osErrorParameter;
 | 
						|
    } else {
 | 
						|
        if(rmtx != 0U) {
 | 
						|
#if(configUSE_RECURSIVE_MUTEXES == 1)
 | 
						|
            if(xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) {
 | 
						|
                if(timeout != 0U) {
 | 
						|
                    stat = osErrorTimeout;
 | 
						|
                } else {
 | 
						|
                    stat = osErrorResource;
 | 
						|
                }
 | 
						|
            }
 | 
						|
#endif
 | 
						|
        } else {
 | 
						|
            if(xSemaphoreTake(hMutex, timeout) != pdPASS) {
 | 
						|
                if(timeout != 0U) {
 | 
						|
                    stat = osErrorTimeout;
 | 
						|
                } else {
 | 
						|
                    stat = osErrorResource;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* Return execution status */
 | 
						|
    return (stat);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
    Release a Mutex that was acquired by osMutexAcquire.
 | 
						|
*/
 | 
						|
osStatus_t osMutexRelease(osMutexId_t mutex_id) {
 | 
						|
    SemaphoreHandle_t hMutex;
 | 
						|
    osStatus_t stat;
 | 
						|
    uint32_t rmtx;
 | 
						|
 | 
						|
    hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
 | 
						|
 | 
						|
    /* Extract recursive mutex flag */
 | 
						|
    rmtx = (uint32_t)mutex_id & 1U;
 | 
						|
 | 
						|
    stat = osOK;
 | 
						|
 | 
						|
    if(FURI_IS_IRQ_MODE() != 0U) {
 | 
						|
        stat = osErrorISR;
 | 
						|
    } else if(hMutex == NULL) {
 | 
						|
        stat = osErrorParameter;
 | 
						|
    } else {
 | 
						|
        if(rmtx != 0U) {
 | 
						|
#if(configUSE_RECURSIVE_MUTEXES == 1)
 | 
						|
            if(xSemaphoreGiveRecursive(hMutex) != pdPASS) {
 | 
						|
                stat = osErrorResource;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
        } else {
 | 
						|
            if(xSemaphoreGive(hMutex) != pdPASS) {
 | 
						|
                stat = osErrorResource;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* Return execution status */
 | 
						|
    return (stat);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
    Get Thread which owns a Mutex object.
 | 
						|
*/
 | 
						|
FuriThreadId osMutexGetOwner(osMutexId_t mutex_id) {
 | 
						|
    SemaphoreHandle_t hMutex;
 | 
						|
    FuriThreadId owner;
 | 
						|
 | 
						|
    hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
 | 
						|
 | 
						|
    if((FURI_IS_IRQ_MODE() != 0U) || (hMutex == NULL)) {
 | 
						|
        owner = 0;
 | 
						|
    } else {
 | 
						|
        owner = (FuriThreadId)xSemaphoreGetMutexHolder(hMutex);
 | 
						|
    }
 | 
						|
 | 
						|
    /* Return owner thread ID */
 | 
						|
    return (owner);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
    Delete a Mutex object.
 | 
						|
*/
 | 
						|
osStatus_t osMutexDelete(osMutexId_t mutex_id) {
 | 
						|
    osStatus_t stat;
 | 
						|
#ifndef USE_FreeRTOS_HEAP_1
 | 
						|
    SemaphoreHandle_t hMutex;
 | 
						|
 | 
						|
    hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
 | 
						|
 | 
						|
    if(FURI_IS_IRQ_MODE() != 0U) {
 | 
						|
        stat = osErrorISR;
 | 
						|
    } else if(hMutex == NULL) {
 | 
						|
        stat = osErrorParameter;
 | 
						|
    } else {
 | 
						|
#if(configQUEUE_REGISTRY_SIZE > 0)
 | 
						|
        vQueueUnregisterQueue(hMutex);
 | 
						|
#endif
 | 
						|
        stat = osOK;
 | 
						|
        vSemaphoreDelete(hMutex);
 | 
						|
    }
 | 
						|
#else
 | 
						|
    stat = osError;
 | 
						|
#endif
 | 
						|
 | 
						|
    /* Return execution status */
 | 
						|
    return (stat);
 | 
						|
}
 |