单片机
返回首页

[单片机框架][os层] RTX4 中间件 公共函数

2022-09-19 来源:csdn

重新封装RTX4函数,以便适配RTX5 / FREERTOS / FREERTOS_NRF_RTC。

在这里插入图片描述

Keil RTX是为ARM和Cortex-M设备设计的免版税,确定性的实时操作系统。它允许您创建同时执行多个功能的程序,并帮助创建更好的结构和更容易维护的应用程序。


特征

具有源代码的免版权,确定性RTOS

灵活的调度:循环,抢占和协作

具有低中断延迟的高速实时操作

为资源有限的系统提供小封装

无限数量的任务每个具有254个优先级

无限数量的邮箱,信号量,互斥量和计时器

支持多线程和线程安全操作

内核感知调试支持MDK-ARM

使用μVision配置向导的基于对话框的设置

优点

尽管无需实时操作系统(通过在超级循环中执行一个或多个功能)就可以创建实时程序,这个应该指的是裸机了,但KeilRTX为您解决的RTOS有许多调度,维护和计时问题。


注意事项

所有MDK-ARM版本都包含RTX源代码。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

【RTX内核在新工程中的使用步骤】

在keil开发环境搭建好的情况下,设置在工程中使用RTX内核,选择 Project —> Options for Target,然后,为操作系统[ Operating system]选择 RTX kernel 并点击 OK;

从 KeilARMBoardsSTSTM32F10X_EVALRTX_Blinky 文件夹中为目标设备复制 RTX_Config.c 配置文件到 User/ 下;

// 如果没有针对独特设备的文件,那么就从Philips文件夹下面复制文件,并且依照目标设备进行修改。

在 stm32f10x_it.c中注释掉 SVC_Handler() PendSV_Handler() SysTick_Handler()三个函数,因为使用了RTX,为了避免函数名被重复定义,这三个函数必须注释掉,要不RTX就没法运行;

在RTX_Config.c 中的配置选项可以:


指定当前运行任务的数目;

指定使用用户自定堆栈任务的数目;

指定为每个任务分配堆栈的大小;

开启或是禁止堆栈校核;

指定CPU定时器作为系统定时器;

为选中的定时器指定输入的时钟频率;;

指定定时器节拍间隔;

开启或是禁止轮转任务调度;

为轮转任务调度指定时间片;

定义空闲任务操作;

指定用户定时器的数目;

为用户定时器回调函数指定代码;

/********************************************************************************

* @file    os_api.c

* @author  jianqiang.xue

* @Version V1.0.0

* @Date    2021-04-03

* @brief   大部分RTX系统函数在:**Keil_v5ArmPacksARMCMSIS5.6.0CMSISRTOSRTXSRC

********************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include

#include

/* Private includes ----------------------------------------------------------*/

#include 'cmsis_os.h'

#include 'os_api.h'


/* Public function prototypes -----------------------------------------------*/

/*********************************OS_KERNEL***********************************/

os_status os_kernel_initialize(void)

{

    return (os_status)osKernelInitialize();

}


os_status os_kernel_start(void)

{

    return (os_status)osKernelStart();

}


os_status os_delay(uint32_t ms)

{

    return (os_status)osDelay(ms);

}


uint32_t os_get_tick(void)

{

    return osKernelSysTick();

}


extern void rt_tsk_lock(void);

os_status os_kernel_lock(void)

{

    rt_tsk_lock();

    return (os_status)0;

}


extern void rt_tsk_unlock(void);

os_status os_kernel_unlock(void)

{

    rt_tsk_unlock();

    return (os_status)0;

}

/************************************OS_THREAD************************************/

os_thread_id os_thread_create(const os_thread_def_t *thread_def, void *arg)

{

    return (os_thread_id)osThreadCreate((const osThreadDef_t *)thread_def, NULL);

}


/************************************OS_TIMER************************************/

os_timer_id os_timer_create(const os_timer_def_t *timer_def, os_timer_t type, void *arg)

{

    return osTimerCreate((const osTimerDef_t *)timer_def, (os_timer_type)type, arg);

}


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************************************/

os_mail_qid os_mail_create(const os_mailq_def_t *queue_def, os_thread_id thread_id)

{

    return (os_mail_qid)osMailCreate((const osMailQDef_t *)queue_def, thread_id);

}


void *os_mail_alloc(os_mail_qid queue_id, uint32_t millisec)

{

    return osMailAlloc((osMailQId)queue_id, millisec);

}


void *os_mail_clean_and_alloc(os_mail_qid queue_id, uint32_t millisec)

{

    return osMailCAlloc((osMailQId)queue_id, millisec);

}


os_status os_mail_put(os_mail_qid queue_id, void *mail)

{

    return (os_status)osMailPut((osMailQId)queue_id, mail);

}


os_event os_mail_get(os_mail_qid queue_id, uint32_t millisec, void *arg)

{

    osEvent event;

    os_event event_t;


    event = osMailGet((osMailQId)queue_id, millisec);

    memcpy(&event_t, &event, sizeof(osEvent));

    return event_t;

}


os_status os_mail_free(os_mail_qid queue_id, void *mail)

{

    return (os_status)osMailFree((osMailQId)queue_id, mail);

}


/************************************OS_POOL************************************/

os_pool_id os_pool_create(const os_pool_def_t *pool_def)

{

    return (os_pool_id)osPoolCreate((const osPoolDef_t *)pool_def);

}

void *os_pool_alloc(os_pool_id pool_id)

{

    return osPoolAlloc((osPoolId)pool_id);

}

void *os_pool_calloc(os_pool_id pool_id)

{

   return osPoolCAlloc((osPoolId)pool_id);

}

os_status os_pool_free(os_pool_id pool_id, void *block)

{

    return (os_status)osPoolFree((osPoolId)pool_id, block);

}

/************************************OS_MSG_QUEUE************************************/

/**

 * @brief  [消息队列] 创建消息队列空间

 * @note   NULL

 * @param  queue_def : 消息队列信息(大小)

 * @param  thread_id : 线程ID(可以无视不填)

 * @retval None

 */

os_message_qid os_message_create(const os_messageq_def_t *queue_def, os_thread_id thread_id)

{

    return (os_message_qid)osMessageCreate((const osMessageQDef_t *)queue_def, thread_id);

}


/**

 * @brief  [消息队列] 发送一组消息队列数据

 * @note   NULL

 * @param  queue_id: 消息队列ID

 * @param  info    : 消息指针

 * @param  millisec: 超时时间 0xFFFFFFFF 无限等待

 * @retval None

 */

os_status os_message_put(os_message_qid queue_id, uint32_t info, uint32_t millisec)

{

    return (os_status)osMessagePut((osMessageQId)queue_id, info, millisec); // Send Message

}


/**

 * @brief  [消息队列] 得到一组消息队列数据

 * @note   NULL

 * @param  queue_id: 消息队列ID

 * @param  millisec: 等待时间 0xFFFFFFFF 无限等待

 * @retval None

 */

os_event os_message_get(os_message_qid queue_id, uint32_t millisec)

{

    osEvent event;

    os_event event_t;

    event = osMessageGet((osMessageQId)queue_id, millisec);

    memcpy(&event_t, &event, sizeof(osEvent));

    return event_t;

}

/************************************OS_SIGNAL************************************/

extern int32_t isrSignalSet(osThreadId thread_id, int32_t signals);

int32_t isr_signal_set(os_thread_id thread_id, int32_t signals)

{

    return isrSignalSet(thread_id, signals);

}


int32_t os_signal_set(os_thread_id thread_id, int32_t signals)

{

    return osSignalSet(thread_id, signals);

}


int32_t os_signal_clear(os_thread_id thread_id, int32_t signals)

{

    return osSignalClear(thread_id, signals);

}


// signals = 0,则等待任意信号.

os_event os_signal_wait(int32_t signals, uint32_t millisec)

{

    osEvent event;

    os_event event_t;


    event = osSignalWait(signals, millisec);

    memcpy(&event_t, &event, sizeof(osEvent));

    return event_t;

}


/********************************************************************************

* @file    os_api.h

* @author  jianqiang.xue

* @version V1.0.0

* @date    2021-04-03

* @brief   NULL

********************************************************************************/


#include

#include 'cmsis_os.h'


/// Timeout value.

#define OS_WAIT_FOREVER     0xFFFFFFFFU    ///< wait forever timeout value


/************************************OS_KERNEL************************************/

typedef enum {

    OS_OK                     =     0,       ///< function completed; no error or event occurred.

    OS_EVENT_SIGNAL           =  0x08,       ///< function completed; signal event occurred.

    OS_EVENT_MESSAGE          =  0x10,       ///< function completed; message event occurred.

    OS_EVENT_MAIL             =  0x20,       ///< function completed; mail event occurred.

    OS_EVENT_TIMEOUT          =  0x40,       ///< function completed; timeout occurred.

    OS_ERROR_PARAMETER        =  0x80,       ///< parameter error: a mandatory parameter was missing or specified an incorrect object.

    OS_ERROR_RESOURCE         =  0x81,       ///< resource not available: a specified resource was not available.

    OS_ERROR_TIMEOUTRESOURCE  =  0xC1,       ///< resource not available within given time: a specified resource was not available within the timeout period.

    OS_ERROR_ISR              =  0x82,       ///< not allowed in ISR context: the function cannot be called from interrupt service routines.

    OS_ERROR_ISRRECURSIVE     =  0x83,       ///< function called multiple times from ISR with same object.

    OS_ERROR_PRIORITY         =  0x84,       ///< system cannot determine priority or thread has illegal priority.

    OS_ERROR_NOMEMORY         =  0x85,       ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.

    OS_ERROR_VALUE            =  0x86,       ///< value of a parameter is out of range.

    OS_ERROR_OS               =  0xFF,       ///< unspecified RTOS error: run-time error but no other error message fits.

    OS_STATUS_RESERVED        =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.

} 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);

/************************************OS_EVENT************************************/

typedef struct os_mailq_cb    *os_mail_qid;

typedef struct os_messageq_cb *os_message_qid;


typedef struct  {

    os_status                 status;     ///< status code: event or error information

    union  {

      uint32_t                    v;     ///< message as 32-bit value

      void                       *p;     ///< message or mail as void pointer

      int32_t               signals;     ///< signal flags

    } value;                             ///< event value

    union  {

      os_mail_qid             mail_id;   ///< mail id obtained by ref osMailCreate

      os_message_qid       message_id;   ///< message id obtained by ref osMessageCreate

    } def;                               ///< event definition

} os_event;


/************************************OS_THREAD************************************/

#ifndef FREERTOS

typedef enum {

    OS_PRIORITY_IDLE          = -3,          ///< priority: idle (lowest)

    OS_PRIORITY_LOW           = -2,          ///< priority: low

    OS_PRIORITY_BELOWNORMAL   = -1,          ///< priority: below normal

    OS_PRIORITY_NORMAL        =  0,          ///< priority: normal (default)

    OS_PRIORITY_ABOVENORMAL   = +1,          ///< priority: above normal

    OS_PRIORITY_HIGH          = +2,          ///< priority: high

    OS_PRIORITY_REALTIME      = +3,          ///< priority: realtime (highest)

    OS_PRIORITY_ERROR         =  0x84        ///< system cannot determine priority or thread has illegal priority

} os_priority_t;

#else

typedef enum {

    OS_PRIORITY_IDLE          = 0,          ///< priority: idle (lowest)

    OS_PRIORITY_LOW           = 1,          ///< priority: low

    OS_PRIORITY_BELOWNORMAL   = 2,          ///< priority: below normal

    OS_PRIORITY_NORMAL        = 3,          ///< priority: normal (default)

    OS_PRIORITY_ABOVENORMAL   = 4,          ///< priority: above normal

    OS_PRIORITY_HIGH          = 5,          ///< priority: high

    OS_PRIORITY_REALTIME      = 6,          ///< priority: realtime (highest)

    OS_PRIORITY_ERROR         = 0x84        ///< system cannot determine priority or thread has illegal priority

} os_priority_t;

#endif


typedef struct os_thread_cb *os_thread_id;

typedef void (*os_pthread) (void const *argument);


typedef struct {

    os_pthread             pthread;      ///< start address of thread function

    os_priority_t          tpriority;    ///< initial thread priority

    uint32_t               instances;    ///< maximum number of instances of that thread function

    uint32_t               stacksize;    ///< stack size requirements in bytes; 0 is default stack size

} 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);


/************************************OS_TIMER************************************/

typedef struct os_timer_cb *os_timer_id;

typedef void (*os_ptimer) (void const *argument);


typedef struct

{

    os_ptimer ptimer; ///< start address of a timer function

    void *timer;      ///< pointer to internal data

} os_timer_def_t;


typedef enum

{

    OS_TIMER_ONCE     = 0,    ///< one-shot timer

    OS_TIMER_PERIODIC = 1     ///< repeating timer

} 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);


/************************************OS_MAIL************************************/

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; ///< number of elements in the queue

    uint16_t item_sz;  ///< size of an item

    void *pool;        ///< memory array for mail

} 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);


/************************************OS_MSG_QUEUE************************************/

/// Message ID identifies the message queue (pointer to a message queue control block).

typedef struct os_messageq_cb *os_message_qid;

typedef struct os_messageq_def

{

    uint32_t queue_sz;            ///< number of elements in the queue

#if (osCMSIS < 0x20000U)

    void *pool;                   ///< memory array for messages

#else

    osMessageQueueAttr_t  attr;   ///< message queue attributes

#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


/// brief Access a Message Queue Definition.

/// param         name          name of the queue

#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);

/************************************OS_POOL************************************/

/// Pool ID identifies the memory pool (pointer to a memory pool control block).

typedef struct os_pool_cb *os_pool_id;

typedef struct os_pool_deft

{

    uint32_t pool_sz; ///< number of items (elements) in the pool

    uint32_t item_sz; ///< size of an item

    void *pool;       ///< pointer to memory for 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);

/************************************OS_SIGNAL************************************/

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


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章