重新封装freertos函数,以便适配RTX4 /RTX5 / FREERTOS_NRF_RTC。
FreeRTOS 是一类 RTOS,设计得足够小以在微控制器上运行——尽管它的使用不限于微控制器应用。
微控制器是一种小型且资源受限的处理器,它在单个芯片上集成了处理器本身、只读存储器(ROM 或闪存)以保存要执行的程序,以及程序所需的随机存取存储器 (RAM)执行。通常,程序直接从只读存储器中执行。
微控制器用于深度嵌入式应用程序(那些您从未真正看到处理器本身或其运行的软件的应用程序),这些应用程序通常有非常具体和专门的工作要做。大小限制和专用终端应用程序性质很少保证使用完整的 RTOS 实现 - 或者确实使使用完整的 RTOS 实现成为可能。因此,FreeRTOS 仅提供核心实时调度功能、任务间通信、计时和同步原语。这意味着它被更准确地描述为实时内核或实时执行程序。附加功能(例如命令控制台界面或网络堆栈)可以包含在附加组件中。
为什么选择 FreeRTOS?
-
可信内核 凭借久经考验的稳健性、微小的占用空间和广泛的设备支持,FreeRTOS 内核受到世界领先公司的信赖,成为微控制器和小型微处理器的事实上的标准。 -
加快上市时间 通过详细的预配置演示和物联网 (IoT) 参考集成,无需确定如何设置项目。快速下载、编译并更快地进入市场。 -
广泛的生态系统支持 我们的合作伙伴生态系统提供了广泛的选择,包括社区贡献、专业支持以及集成的 IDE 和生产力工具。 -
长期支持的可预测性 FreeRTOS 通过长期支持 (LTS) 版本提供功能稳定性。FreeRTOS LTS 库提供两年的安全更新和关键错误修复。由 AWS 维护,以造福于 FreeRTOS 社区。
特征
-
小而省电的内核 大小可扩展,可用程序内存占用低至 9KB。一些架构包括无滴答的省电模式 -
支持 40 多种架构 一个代码库,适用于 40 多种 MCU 架构和 15 多种工具链,包括最新的 RISC-V 和 ARMv8-M(Arm Cortex-M33)微控制器 -
模块化库 越来越多的附加库用于所有行业部门,包括安全的本地或云连接 -
AWS 参考集成 利用经过测试的示例,其中包括安全连接到云所必需的所有库 -
MIT 许可,有选项 FreeRTOS 可在其MIT 许可下用于任何目的 。我们的战略合作伙伴还提供 商业许可证和 安全认证。
官网地址:https://www.freertos.org/ FreeRTOS 内核快速入门指南:https://www.freertos.org/FreeRTOS-quick-start-guide.html
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "cmsis_os2.h"
#include "os_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#define IS_IRQ_MODE() (__get_IPSR() != 0U)
#define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (KernelState == osKernelRunning)))
#define MAX_BITS_TASK_NOTIFY 31U
#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
static osKernelState_t KernelState = osKernelInactive;
os_status os_kernel_initialize(void)
{
return (os_status)osKernelInitialize();
}
os_status os_kernel_start(void)
{
return (os_status)osKernelStart();
}
os_status os_kernel_lock(void)
{
return (os_status)osKernelLock();
}
os_status os_kernel_unlock(void)
{
return (os_status)osKernelUnlock();
}
os_status os_delay(uint32_t ms)
{
return (os_status)osDelay(ms);
}
uint32_t os_get_tick(void)
{
return osKernelGetTickCount();
}
os_thread_id os_thread_create(const os_thread_def_t *thread_def, void *arg)
{
if (thread_def == NULL)
{
return NULL;
}
osThreadAttr_t attr = {0};
attr.name = arg;
attr.priority = osPriorityLow;
if (thread_def->tpriority == OS_PRIORITY_LOW)
{
attr.priority = osPriorityLow;
}
else if (thread_def->tpriority == OS_PRIORITY_NORMAL)
{
attr.priority = osPriorityNormal;
}
else if (thread_def->tpriority == OS_PRIORITY_ABOVENORMAL)
{
attr.priority = osPriorityAboveNormal;
}
else if (thread_def->tpriority == OS_PRIORITY_HIGH)
{
attr.priority = osPriorityHigh;
}
else if (thread_def->tpriority == OS_PRIORITY_REALTIME)
{
attr.priority = osPriorityRealtime;
}
else
{
attr.priority = osPriorityLow;
}
attr.stack_size = thread_def->stacksize;
attr.attr_bits = osThreadDetached;
return (os_thread_id)osThreadNew((osThreadFunc_t)thread_def->pthread, arg, &attr);
}
os_timer_id os_timer_create(const os_timer_def_t *timer_def, os_timer_t type, void *arg)
{
return osTimerNew((osTimerFunc_t)timer_def->ptimer, (osTimerType_t)type, arg, NULL);
}
os_status os_timer_start(os_timer_id timer_id, uint32_t millisec)
{
return (os_status)osTimerStart(timer_id, millisec);
}
os_status os_timer_stop(os_timer_id timer_id)
{
return (os_status)osTimerStop(timer_id);
}
os_mail_qid os_mail_create(const os_mailq_def_t *queue_def, os_thread_id thread_id)
{
return (os_mail_qid)osMessageQueueNew(queue_def->queue_sz, queue_def->item_sz, NULL);
}
void *os_mail_alloc(os_mail_qid queue_id, uint32_t millisec)
{
return NULL;
}
void *os_mail_clean_and_alloc(os_mail_qid queue_id, uint32_t millisec)
{
return os_mail_alloc(queue_id, millisec);
}
os_status os_mail_put(os_mail_qid queue_id, void *mail)
{
return (os_status)osMessageQueuePut((osMessageQueueId_t)queue_id, mail, NULL, NULL);
}
os_event os_mail_get(os_mail_qid queue_id, uint32_t millisec, void *arg)
{
osStatus_t status;
os_event event_t;
status = osMessageQueueGet((osMessageQueueId_t)queue_id, arg, NULL, millisec);
event_t.status = (os_status)status;
event_t.def.message_id = (os_message_qid)queue_id;
event_t.value.p = arg;
return event_t;
}
os_status os_mail_free(os_mail_qid queue_id, void *mail)
{
return (os_status)0;
}
os_pool_id os_pool_create(const os_pool_def_t *pool_def)
{
return (os_pool_id)osMemoryPoolNew(pool_def->pool_sz, pool_def->item_sz, NULL);
}
void *os_pool_alloc(os_pool_id pool_id)
{
return osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0);
}
void *os_pool_calloc(os_pool_id pool_id)
{
return os_pool_alloc(pool_id);
}
os_status os_pool_free(os_pool_id pool_id, void *block)
{
return (os_status)osMemoryPoolFree((osMemoryPoolId_t)pool_id, block);
}
os_message_qid os_message_create(const os_messageq_def_t *queue_def, os_thread_id thread_id)
{
return (os_message_qid)osMessageQueueNew(queue_def->queue_sz, 4, &(queue_def->attr));
}
os_status os_message_put(os_message_qid queue_id, uint32_t info, uint32_t millisec)
{
return (os_status)osMessageQueuePut((osMessageQueueId_t)queue_id, (const void *)&info, 0, millisec);
}
os_event os_message_get(os_message_qid queue_id, uint32_t millisec)
{
QueueHandle_t hQueue = (QueueHandle_t)queue_id;
BaseType_t yield;
uint32_t *msg_ptr;
os_event event;
event.status = OS_OK;
if (IS_IRQ())
{
if ((hQueue == NULL) || (millisec != 0U))
{
event.status = OS_ERROR_PARAMETER;
}
else
{
yield = false;
if (xQueueReceiveFromISR(hQueue, &msg_ptr, &yield) != true)
{
event.status = OS_ERROR_RESOURCE;
}
else
{
event.status = OS_EVENT_MESSAGE;
event.value.p = (void *)msg_ptr;
portYIELD_FROM_ISR(yield);
}
}
}
else
{
if (hQueue == NULL)
{
event.status = OS_ERROR_PARAMETER;
}
else
{
if (xQueueReceive(hQueue, &msg_ptr, (TickType_t)millisec) != true)
{
if (millisec != 0U)
{
event.status = OS_EVENT_TIMEOUT;
}
else
{
event.status = OS_ERROR_RESOURCE;
}
}
else
{
event.status = OS_EVENT_MESSAGE;
event.value.p = (void *)msg_ptr;
}
}
}
return event;
}
uint8_t os_message_get_space(os_message_qid queue_id)
{
return (uint8_t)osMessageQueueGetSpace(queue_id);
}
uint8_t os_message_get_count(os_message_qid queue_id)
{
return (uint8_t)osMessageQueueGetCount(queue_id);
}
int32_t isr_signal_set(os_thread_id thread_id, int32_t signals)
{
return osThreadFlagsSet((osThreadId_t)thread_id, signals);
}
int32_t os_signal_set(os_thread_id thread_id, int32_t signals)
{
return osThreadFlagsSet((osThreadId_t)thread_id, signals);
}
int32_t os_signal_clear(os_thread_id thread_id, int32_t signals)
{
return osThreadFlagsClear(signals);
}
os_event os_signal_wait(int32_t signals, uint32_t millisec)
{
BaseType_t rval;
os_event event_t;
if (IS_IRQ())
{
event_t.status = OS_ERROR_ISR;
}
else if ((signals & THREAD_FLAGS_INVALID_BITS) != 0U)
{
event_t.status = OS_ERROR_PARAMETER;
}
else
{
rval = xTaskNotifyWait(signals, 0xFFFFFFFF, (uint32_t *)&(event_t.value.signals), millisec);
if (rval == true)
{
event_t.status = OS_EVENT_SIGNAL;
}
else
{
event_t.status = OS_EVENT_TIMEOUT;
}
}
return (event_t);
}
#include <stdint.h>
#include "cmsis_os.h"
#define OS_WAIT_FOREVER 0xFFFFFFFFU
typedef enum {
OS_OK = 0,
OS_EVENT_SIGNAL = 0x08,
OS_EVENT_MESSAGE = 0x10,
OS_EVENT_MAIL = 0x20,
OS_EVENT_TIMEOUT = 0x40,
OS_ERROR_PARAMETER = 0x80,
OS_ERROR_RESOURCE = 0x81,
OS_ERROR_TIMEOUTRESOURCE = 0xC1,
OS_ERROR_ISR = 0x82,
OS_ERROR_ISRRECURSIVE = 0x83,
OS_ERROR_PRIORITY = 0x84,
OS_ERROR_NOMEMORY = 0x85,
OS_ERROR_VALUE = 0x86,
OS_ERROR_OS = 0xFF,
OS_STATUS_RESERVED = 0x7FFFFFFF
} os_status;
os_status os_kernel_initialize (void);
os_status os_kernel_start(void);
os_status os_kernel_lock(void);
os_status os_kernel_unlock(void);
os_status os_delay(uint32_t ms);
uint32_t os_get_tick(void);
typedef struct os_mailq_cb *os_mail_qid;
typedef struct os_messageq_cb *os_message_qid;
typedef struct {
os_status status;
union {
uint32_t v;
void *p;
int32_t signals;
} value;
union {
os_mail_qid mail_id;
os_message_qid message_id;
} def;
} os_event;
#ifndef FREERTOS
typedef enum {
OS_PRIORITY_IDLE = -3,
OS_PRIORITY_LOW = -2,
OS_PRIORITY_BELOWNORMAL = -1,
OS_PRIORITY_NORMAL = 0,
OS_PRIORITY_ABOVENORMAL = +1,
OS_PRIORITY_HIGH = +2,
OS_PRIORITY_REALTIME = +3,
OS_PRIORITY_ERROR = 0x84
} os_priority_t;
#else
typedef enum {
OS_PRIORITY_IDLE = 0,
OS_PRIORITY_LOW = 1,
OS_PRIORITY_BELOWNORMAL = 2,
OS_PRIORITY_NORMAL = 3,
OS_PRIORITY_ABOVENORMAL = 4,
OS_PRIORITY_HIGH = 5,
OS_PRIORITY_REALTIME = 6,
OS_PRIORITY_ERROR = 0x84
} os_priority_t;
#endif
typedef struct os_thread_cb *os_thread_id;
typedef void (*os_pthread) (void const *argument);
typedef struct {
os_pthread pthread;
os_priority_t tpriority;
uint32_t instances;
uint32_t stacksize;
} os_thread_def_t;
#define os_thread(name) &os_thread_def_##name
#define os_thread_def(name, priority, instances, stacksz) \
const os_thread_def_t os_thread_def_##name = {(name), (priority), (instances), (stacksz)}
os_thread_id os_thread_create(const os_thread_def_t *thread_def, void *arg);
typedef struct os_timer_cb *os_timer_id;
typedef void (*os_ptimer) (void const *argument);
typedef struct
{
os_ptimer ptimer;
void *timer;
} os_timer_def_t;
typedef enum
{
OS_TIMER_ONCE = 0,
OS_TIMER_PERIODIC = 1
} os_timer_t;
#define os_timer(name) &os_timer_def_##name
#if (osCMSIS < 0x20000U)
#define os_timer_def(name, function) static uint8_t os_timer_cb_##name[40];\
static os_timer_def_t os_timer_def_##name = {(function), ((void *)os_timer_cb_##name)}
#else
#define os_timer_def(name, function) static const uint8_t os_timer_cb_##name[10];\
static const os_timer_def_t os_timer_def_##name = {(function), ((void *)os_timer_cb_##name)}
#endif
os_timer_id os_timer_create(const os_timer_def_t *timer_def, os_timer_t type, void *arg);
os_status os_timer_start(os_timer_id timer_id, uint32_t millisec);
os_status os_timer_stop(os_timer_id timer_id);
typedef struct os_mailq_cb *os_mail_qid;
#define os_mail_qdef(name, queue_sz, type) \
static const uint8_t os_mailq_q_##name[4 + (queue_sz)] = {0}; \
static const uint8_t os_mailq_m_##name[3 + ((sizeof(type) + 3) / 4) * (queue_sz)]; \
static void *os_mailq_p_##name[2] = {(os_mailq_q_##name), os_mailq_m_##name}; \
static const os_mailq_def_t os_mailq_def_##name = {(queue_sz), sizeof(type), (os_mailq_p_##name)} \
typedef struct os_mailq_def
{
uint16_t queue_sz;
uint16_t item_sz;
void *pool;
} os_mailq_def_t;
#define os_mailq(name) &os_mailq_def_##name
os_mail_qid os_mail_create(const os_mailq_def_t *queue_def, os_thread_id thread_id);
void *os_mail_alloc(os_mail_qid queue_id, uint32_t millisec);
void *os_mail_clean_and_alloc(os_mail_qid queue_id, uint32_t millisec);
os_status os_mail_put(os_mail_qid queue_id, void *mail);
os_event os_mail_get(os_mail_qid queue_id, uint32_t millisec, void *arg);
os_status os_mail_free(os_mail_qid queue_id, void *mail);
typedef struct os_messageq_cb *os_message_qid;
typedef struct os_messageq_def
{
uint32_t queue_sz;
#if (osCMSIS < 0x20000U)
void *pool;
#else
osMessageQueueAttr_t attr;
#endif
} os_messageq_def_t;
#if (osCMSIS < 0x20000U)
#define os_message_qdef(name, queue_sz, type) \
static uint8_t os_messageq_q_##name[4 + (queue_sz)] = {0}; \
static const os_messageq_def_t os_messageq_def_##name = {(queue_sz), ((void *)os_messageq_q_##name)}
#else
#define os_message_qdef(name, queue_sz, type) \
static const os_messageq_def_t os_messageq_def_##name = {(queue_sz), { NULL, 0U, NULL, 0U, NULL, 0U }}
#endif
#define os_messageq(name) &os_messageq_def_##name
os_message_qid os_message_create(const os_messageq_def_t *queue_def, os_thread_id thread_id);
os_status os_message_put(os_message_qid queue_id, uint32_t info, uint32_t millisec);
os_event os_message_get(os_message_qid queue_id, uint32_t millisec);
uint8_t os_message_get_space(os_message_qid queue_id);
uint8_t os_message_get_count(os_message_qid queue_id);
typedef struct os_pool_cb *os_pool_id;
typedef struct os_pool_deft
{
uint32_t pool_sz;
uint32_t item_sz;
void *pool;
} os_pool_def_t;
#define os_pool_def(name, no, type) \
static const uint8_t os_pool_m_##name[3 + ((sizeof(type) + 3) / 4) * (no)]; \
static const os_pool_def_t os_pool_def_##name = {(no), sizeof(type), (void *)(os_pool_m_##name)}
#define os_pool(name) &os_pool_def_##name
os_pool_id os_pool_create(const os_pool_def_t *pool_def);
void *os_pool_alloc(os_pool_id pool_id);
void *os_pool_calloc(os_pool_id pool_id);
os_status os_pool_free(os_pool_id pool_id, void *block);
uint8_t os_pool_get_space(os_pool_id pool_id);
int32_t isr_signal_set(os_thread_id thread_id, int32_t signals);
int32_t os_signal_set(os_thread_id thread_id, int32_t signals);
int32_t os_signal_clear(os_thread_id thread_id, int32_t signals);
os_event os_signal_wait(int32_t signals, uint32_t millisec);
#ifdef FREERTOS
void get_task_info(void);
#endif
|