Morse Micro IoT SDK  2.11.2
mmosal.h
1/*
2 * Copyright 2021-2023 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
16#pragma once
17
18#include <stdbool.h>
19#include <stdint.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include "mmport.h"
25
26#ifdef __cplusplus
27extern "C"
28{
29#endif
30
40typedef void (*mmosal_app_init_cb_t)(void);
41
56
61/*
62 * ---------------------------------------------------------------------------------------------
63 */
64
84void *mmosal_malloc_(size_t size);
85
99void *mmosal_malloc_dbg(size_t size, const char *name, unsigned line_number);
100
113void *mmosal_calloc_dbg(size_t nitems, size_t size, const char *name, unsigned line_number);
114
127void *mmosal_realloc_dbg(void *ptr, size_t size, const char *name, unsigned line_number);
128
134void mmosal_free(void *p);
135
146void *mmosal_realloc_(void *ptr, size_t size);
147
158void *mmosal_calloc_(size_t nitems, size_t size);
159
160#ifndef MMOSAL_TRACK_ALLOCATIONS
170#define mmosal_malloc(size) mmosal_malloc_(size)
171
180#define mmosal_calloc(nitems, size) mmosal_calloc_(nitems, size)
181
190#define mmosal_realloc(ptr, size) mmosal_realloc_(ptr, size)
191#else
192/* Note: we use function name because it should be shorter than the full filename path. */
202#define mmosal_malloc(size) mmosal_malloc_dbg(size, __func__, __LINE__)
203
212#define mmosal_calloc(nitems, size) mmosal_calloc_dbg(nitems, size, __func__, __LINE__)
213
222#define mmosal_realloc(ptr, size) mmosal_realloc_dbg(ptr, size, __func__, __LINE__)
223#endif
224
229/*
230 * ---------------------------------------------------------------------------------------------
231 */
232
246typedef void (*mmosal_task_fn_t)(void *arg);
247
250{
261};
262
274struct mmosal_task *mmosal_task_create(mmosal_task_fn_t task_fn,
275 void *argument,
276 enum mmosal_task_priority priority,
277 unsigned stack_size_u32,
278 const char *name);
279
287void mmosal_task_delete(struct mmosal_task *task);
288
294struct mmosal_task *mmosal_task_get_active(void);
295
300
306void mmosal_task_sleep(uint32_t duration_ms);
307
315#define MMOSAL_TASK_ENTER_CRITICAL() \
316 do { \
317 MMPORT_MEM_SYNC(); \
318 mmosal_task_enter_critical(); \
319 } while (0)
320
326#define MMOSAL_TASK_EXIT_CRITICAL() \
327 do { \
328 MMPORT_MEM_SYNC(); \
329 mmosal_task_exit_critical(); \
330 } while (0)
331
342
351
359
367
373const char *mmosal_task_name(void);
374
379/*
380 * ---------------------------------------------------------------------------------------------
381 */
382
398struct mmosal_mutex *mmosal_mutex_create(const char *name);
399
405void mmosal_mutex_delete(struct mmosal_mutex *mutex);
406
415bool mmosal_mutex_get(struct mmosal_mutex *mutex, uint32_t timeout_ms);
416
424bool mmosal_mutex_release(struct mmosal_mutex *mutex);
425
429#define MMOSAL_MUTEX_GET_INF(_mutex) \
430 do { \
431 bool ok__ = mmosal_mutex_get((_mutex), UINT32_MAX); \
432 MMOSAL_ASSERT(ok__); \
433 } while (0)
434
438#define MMOSAL_MUTEX_RELEASE(_mutex) \
439 do { \
440 bool ok__ = mmosal_mutex_release(_mutex); \
441 MMOSAL_ASSERT(ok__); \
442 } while (0)
443
451bool mmosal_mutex_is_held_by_active_task(struct mmosal_mutex *mutex);
452
457/*
458 * ---------------------------------------------------------------------------------------------
459 */
460
479struct mmosal_sem *mmosal_sem_create(unsigned max_count, unsigned initial_count, const char *name);
480
486void mmosal_sem_delete(struct mmosal_sem *sem);
487
497bool mmosal_sem_give(struct mmosal_sem *sem);
498
508bool mmosal_sem_give_from_isr(struct mmosal_sem *sem);
509
518bool mmosal_sem_wait(struct mmosal_sem *sem, uint32_t timeout_ms);
519
527uint32_t mmosal_sem_get_count(struct mmosal_sem *sem);
528
533/*
534 * ---------------------------------------------------------------------------------------------
535 */
536
552struct mmosal_semb *mmosal_semb_create(const char *name);
553
559void mmosal_semb_delete(struct mmosal_semb *semb);
560
570bool mmosal_semb_give(struct mmosal_semb *semb);
571
581bool mmosal_semb_give_from_isr(struct mmosal_semb *semb);
582
591bool mmosal_semb_wait(struct mmosal_semb *semb, uint32_t timeout_ms);
592
597/*
598 * ---------------------------------------------------------------------------------------------
599 */
600
618struct mmosal_queue *mmosal_queue_create(size_t num_items, size_t item_size, const char *name);
619
625void mmosal_queue_delete(struct mmosal_queue *queue);
626
640bool mmosal_queue_pop(struct mmosal_queue *queue, void *item, uint32_t timeout_ms);
641
655bool mmosal_queue_push(struct mmosal_queue *queue, const void *item, uint32_t timeout_ms);
656
668bool mmosal_queue_pop_from_isr(struct mmosal_queue *queue, void *item);
669
681bool mmosal_queue_push_from_isr(struct mmosal_queue *queue, const void *item);
682
687/*
688 * ---------------------------------------------------------------------------------------------
689 */
690
704uint32_t mmosal_get_time_ms(void);
705
712
719
737static inline bool mmosal_time_lt(uint32_t a, uint32_t b)
738{
739 return ((int32_t)(a - b)) < 0;
740}
741
759static inline bool mmosal_time_le(uint32_t a, uint32_t b)
760{
761 return ((int32_t)(a - b)) <= 0;
762}
763
780static inline uint32_t mmosal_time_max(uint32_t a, uint32_t b)
781{
782 if (mmosal_time_lt(a, b))
783 {
784 return b;
785 }
786 else
787 {
788 return a;
789 }
790}
791
799static inline bool mmosal_time_has_passed(uint32_t t)
800{
802}
803
808/*
809 * ---------------------------------------------------------------------------------------------
810 */
811
827struct mmosal_timer;
828
834typedef void (*timer_callback_t)(struct mmosal_timer *timer);
835
852struct mmosal_timer *mmosal_timer_create(const char *name,
853 uint32_t timer_period_ms,
854 bool auto_reload,
855 void *arg,
856 timer_callback_t callback);
857
863void mmosal_timer_delete(struct mmosal_timer *timer);
864
875bool mmosal_timer_start(struct mmosal_timer *timer);
876
884bool mmosal_timer_stop(struct mmosal_timer *timer);
885
896bool mmosal_timer_change_period(struct mmosal_timer *timer, uint32_t new_period);
897
905void *mmosal_timer_get_arg(struct mmosal_timer *timer);
906
914bool mmosal_is_timer_active(struct mmosal_timer *timer);
915
920/*
921 * ---------------------------------------------------------------------------------------------
922 */
923
932#ifndef MMOSAL_FILEID
934#define MMOSAL_FILEID 0
935#endif
936
941#ifndef MMOSAL_MAX_FAILURE_RECORDS
942#define MMOSAL_MAX_FAILURE_RECORDS 4
943#endif
944
947{
949 uint32_t pc;
951 uint32_t lr;
953 uint32_t fileid;
955 uint32_t line;
958 uint32_t platform_info[4];
959};
960
968
969#ifdef MMOSAL_NO_DEBUGLOG
971#define MMOSAL_LOG_FAILURE_INFO(...)
972#else
975#define MMOSAL_LOG_FAILURE_INFO(...) \
976 do { \
977 void *pc; \
978 struct mmosal_failure_info info = { \
979 .lr = (uint32_t)MMPORT_GET_LR(), \
980 .fileid = MMOSAL_FILEID, \
981 .line = __LINE__, \
982 .platform_info = { __VA_ARGS__ }, \
983 }; \
984 MMPORT_GET_PC(pc); \
985 info.pc = (uint32_t)(uintptr_t)pc; \
986 mmosal_log_failure_info(&info); \
987 } while (0)
988#endif
989
996
997/* Note that running with no assertions is untested and not recommended. */
998#ifndef MMOSAL_NOASSERT
1005#ifndef MMOSAL_ASSERT
1006#define MMOSAL_ASSERT(expr) \
1007 do { \
1008 if (!(expr)) \
1009 { \
1010 MMOSAL_LOG_FAILURE_INFO(0); \
1011 mmosal_impl_assert(); \
1012 while (1) \
1013 { \
1014 } \
1015 } \
1016 } while (0)
1017#endif
1018
1026#ifndef MMOSAL_ASSERT_LOG_DATA
1027#define MMOSAL_ASSERT_LOG_DATA(expr, ...) \
1028 do { \
1029 if (!(expr)) \
1030 { \
1031 MMOSAL_LOG_FAILURE_INFO(__VA_ARGS__); \
1032 mmosal_impl_assert(); \
1033 while (1) \
1034 { \
1035 } \
1036 } \
1037 } while (0)
1038#endif
1039#else
1041#define MMOSAL_ASSERT(expr) (void)(expr)
1043#define MMOSAL_ASSERT_LOG_DATA(expr, ...) (void)(expr)
1044#endif
1045
1046#ifdef ENABLE_MMOSAL_DEV_ASSERT
1048#define MMOSAL_DEV_ASSERT(x) MMOSAL_ASSERT(x)
1051#define MMOSAL_DEV_ASSERT_LOG_DATA(x, ...) MMOSAL_ASSERT_LOG_DATA(x, __VA_ARGS__)
1052#else
1054#define MMOSAL_DEV_ASSERT(x) ((void)(x))
1057#define MMOSAL_DEV_ASSERT_LOG_DATA(x, ...) ((void)(x))
1058#endif
1059
1060#if defined(ENABLE_MANUAL_FAILURE_LOG_PROCESSING) && ENABLE_MANUAL_FAILURE_LOG_PROCESSING
1079bool mmosal_extract_failure_info(struct mmosal_failure_info *buf, uint32_t *failure_count);
1080#endif
1096int mmosal_printf(const char *format, ...);
1097
1111static inline bool mmosal_safer_strcpy(char *dst, const char *src, size_t size)
1112{
1113 bool ret;
1114
1115 if (size == 0)
1116 {
1117 return true;
1118 }
1119
1120 strncpy(dst, src, size);
1121
1122 ret = dst[size - 1] != '\0';
1123 dst[size - 1] = '\0';
1124 return ret;
1125}
1126
1138#ifndef MMOSAL_DEPRECATED_API_ENABLED
1141#define MMOSAL_DEPRECATED_API_ENABLED (1)
1142#endif
1143
1144#if MMOSAL_DEPRECATED_API_ENABLED
1145
1154void mmosal_task_join(struct mmosal_task *task);
1155
1171bool mmosal_task_wait_for_notification(uint32_t timeout_ms);
1172
1185void mmosal_task_notify(struct mmosal_task *task);
1186
1199void mmosal_task_notify_from_isr(struct mmosal_task *task);
1200
1201#endif
1202
1205#ifdef __cplusplus
1206}
1207#endif
1208
void mmosal_log_failure_info(const struct mmosal_failure_info *info)
Log failure information in a way that it is preserved across reboots so that it can be available for ...
void mmosal_impl_assert(void)
Assertion handler implementation.
void mmosal_task_join(struct mmosal_task *task)
Block until the given task has terminated.
void mmosal_task_notify_from_isr(struct mmosal_task *task)
Notifies a waiting task (mmosal_task_wait_for_notification()) that it can continue.
void mmosal_task_notify(struct mmosal_task *task)
Notifies a waiting task (mmosal_task_wait_for_notification()) that it can continue.
bool mmosal_task_wait_for_notification(uint32_t timeout_ms)
Blocks the current task until a notification is received.
int mmosal_main(mmosal_app_init_cb_t app_init_cb)
OS main function.
void(* mmosal_app_init_cb_t)(void)
Application initialization callback (see mmosal_main for details).
Definition: mmosal.h:40
void * mmosal_calloc_dbg(size_t nitems, size_t size, const char *name, unsigned line_number)
Equivalent of standard library calloc().
void * mmosal_malloc_dbg(size_t size, const char *name, unsigned line_number)
Allocate memory of the given size and return a pointer to it (malloc) – debug version.
void * mmosal_realloc_(void *ptr, size_t size)
Equivalent of standard library realloc().
void mmosal_free(void *p)
Free the given memory allocation.
void * mmosal_malloc_(size_t size)
Allocate memory of the given size and return a pointer to it (malloc).
void * mmosal_realloc_dbg(void *ptr, size_t size, const char *name, unsigned line_number)
Equivalent of standard library realloc().
void * mmosal_calloc_(size_t nitems, size_t size)
Equivalent of standard library calloc().
int mmosal_printf(const char *format,...)
OS abstracted version of printf used by morselib.
static bool mmosal_safer_strcpy(char *dst, const char *src, size_t size)
A safer version of strncpy.
Definition: mmosal.h:1111
struct mmosal_mutex * mmosal_mutex_create(const char *name)
Create a new mutex.
bool mmosal_mutex_is_held_by_active_task(struct mmosal_mutex *mutex)
Check whether the given mutex is held by the active thread.
bool mmosal_mutex_release(struct mmosal_mutex *mutex)
Release a mutex.
void mmosal_mutex_delete(struct mmosal_mutex *mutex)
Delete a mutex.
bool mmosal_mutex_get(struct mmosal_mutex *mutex, uint32_t timeout_ms)
Acquire a mutex.
bool mmosal_queue_pop_from_isr(struct mmosal_queue *queue, void *item)
Pop an item from the queue (from ISR context).
struct mmosal_queue * mmosal_queue_create(size_t num_items, size_t item_size, const char *name)
Create a new queue.
bool mmosal_queue_push(struct mmosal_queue *queue, const void *item, uint32_t timeout_ms)
Push an item into the queue.
void mmosal_queue_delete(struct mmosal_queue *queue)
Delete a queue.
bool mmosal_queue_push_from_isr(struct mmosal_queue *queue, const void *item)
Push an item into the queue (from ISR context).
bool mmosal_queue_pop(struct mmosal_queue *queue, void *item, uint32_t timeout_ms)
Pop an item from the queue.
bool mmosal_semb_give_from_isr(struct mmosal_semb *semb)
Give a binary semaphore (from ISR context).
bool mmosal_semb_wait(struct mmosal_semb *semb, uint32_t timeout_ms)
Wait for a counting semaphore.
struct mmosal_semb * mmosal_semb_create(const char *name)
Create a new binary semaphore.
bool mmosal_semb_give(struct mmosal_semb *semb)
Give a binary semaphore.
void mmosal_semb_delete(struct mmosal_semb *semb)
Delete the given binary semaphore.
bool mmosal_sem_give(struct mmosal_sem *sem)
Give a counting semaphore.
void mmosal_sem_delete(struct mmosal_sem *sem)
Delete the given counting semaphore.
bool mmosal_sem_give_from_isr(struct mmosal_sem *sem)
Give a counting semaphore (from ISR context).
struct mmosal_sem * mmosal_sem_create(unsigned max_count, unsigned initial_count, const char *name)
Create a new counting semaphore.
uint32_t mmosal_sem_get_count(struct mmosal_sem *sem)
Returns the current count of the semaphore.
bool mmosal_sem_wait(struct mmosal_sem *sem, uint32_t timeout_ms)
Wait for a counting semaphore.
struct mmosal_task * mmosal_task_create(mmosal_task_fn_t task_fn, void *argument, enum mmosal_task_priority priority, unsigned stack_size_u32, const char *name)
Create a new task.
void mmosal_task_yield(void)
Yield the active task.
struct mmosal_task * mmosal_task_get_active(void)
Get the handle of the active task.
void mmosal_task_exit_critical(void)
Exit critical section.
void mmosal_enable_interrupts(void)
Enable interrupts.
const char * mmosal_task_name(void)
Get the name of the running task.
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
void(* mmosal_task_fn_t)(void *arg)
Type definition for task main functions.
Definition: mmosal.h:246
void mmosal_disable_interrupts(void)
Disable interrupts.
void mmosal_task_delete(struct mmosal_task *task)
Delete the given task.
void mmosal_task_enter_critical(void)
Enter critical section.
mmosal_task_priority
Enumeration of task priorities (ordered lowest to highest).
Definition: mmosal.h:250
@ MMOSAL_TASK_PRI_LOW
Low priority.
Definition: mmosal.h:256
@ MMOSAL_TASK_PRI_MIN
Minimum priority.
Definition: mmosal.h:254
@ MMOSAL_TASK_PRI_HIGH
High priority.
Definition: mmosal.h:260
@ MMOSAL_TASK_PRI_NORM
Normal priority.
Definition: mmosal.h:258
@ MMOSAL_TASK_PRI_IDLE
Idle task priority.
Definition: mmosal.h:252
bool mmosal_timer_start(struct mmosal_timer *timer)
Start a timer.
void mmosal_timer_delete(struct mmosal_timer *timer)
Delete a timer.
bool mmosal_timer_change_period(struct mmosal_timer *timer, uint32_t new_period)
Change timer period.
bool mmosal_is_timer_active(struct mmosal_timer *timer)
Queries the timer to determine if it running.
void * mmosal_timer_get_arg(struct mmosal_timer *timer)
Get the opaque argument associated with a given timer.
void(* timer_callback_t)(struct mmosal_timer *timer)
Function type definition for timer callbacks.
Definition: mmosal.h:834
bool mmosal_timer_stop(struct mmosal_timer *timer)
Stop a timer.
struct mmosal_timer * mmosal_timer_create(const char *name, uint32_t timer_period_ms, bool auto_reload, void *arg, timer_callback_t callback)
Create a new timer.
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
static uint32_t mmosal_time_max(uint32_t a, uint32_t b)
Given two times, return the one that is greatest (taking into account wrapping).
Definition: mmosal.h:780
uint32_t mmosal_ticks_per_second(void)
Get the number of ticks in a second.
static bool mmosal_time_le(uint32_t a, uint32_t b)
Check if time a is less than or equal to time b, taking into account wrapping.
Definition: mmosal.h:759
uint32_t mmosal_get_time_ticks(void)
Get the system time in ticks.
static bool mmosal_time_has_passed(uint32_t t)
Check if the given time has already passed.
Definition: mmosal.h:799
static bool mmosal_time_lt(uint32_t a, uint32_t b)
Check if time a is less than time b, taking into account wrapping.
Definition: mmosal.h:737
static unsigned char buf[1024]
Statically allocated buffer for MQTT.
Definition: mqttdemo.c:153
Data structure used to store information about a failure that can be preserved across reset.
Definition: mmosal.h:947
uint32_t fileid
File identifier.
Definition: mmosal.h:953
uint32_t pc
Content of the PC register at assertion.
Definition: mmosal.h:949
uint32_t lr
Content of the LR register at assertion.
Definition: mmosal.h:951
uint32_t line
Source code line at which the assertion was triggered.
Definition: mmosal.h:955
uint32_t platform_info[4]
Arbitrary platform-specific failure info.
Definition: mmosal.h:958