重新封装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

/********************************************************************************
* @file    os_api.c
* @author  jianqiang.xue
* @Version V1.0.0
* @Date    2021-04-03
* @brief
********************************************************************************/#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))
/* Kernel initialization state */
static osKernelState_t KernelState = osKernelInactive;
/************************************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_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************************************/
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************************************/
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************************************/
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************************************/
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_MSG_QUEUE************************************/
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); // Send Message
}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;//LOG_D("os_msg_get:0x%x|0x%x", queue_id, 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);
}/************************************OS_SIGNAL************************************/
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);
}// signals = 0,则等待任意信号.
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 flags before clearing */return (event_t);
}
/********************************************************************************
* @file    os_api.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-03
* @brief   NULL
********************************************************************************/#include <stdint.h>
#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 informationunion  {uint32_t                    v;     ///< message as 32-bit valuevoid                       *p;     ///< message or mail as void pointerint32_t               signals;     ///< signal flags} value;                             ///< event valueunion  {os_mail_qid             mail_id;   ///< mail id obtained by \ref osMailCreateos_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: lowOS_PRIORITY_BELOWNORMAL   = -1,          ///< priority: below normalOS_PRIORITY_NORMAL        =  0,          ///< priority: normal (default)OS_PRIORITY_ABOVENORMAL   = +1,          ///< priority: above normalOS_PRIORITY_HIGH          = +2,          ///< priority: highOS_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: lowOS_PRIORITY_BELOWNORMAL   = 2,          ///< priority: below normalOS_PRIORITY_NORMAL        = 3,          ///< priority: normal (default)OS_PRIORITY_ABOVENORMAL   = 4,          ///< priority: above normalOS_PRIORITY_HIGH          = 5,          ///< priority: highOS_PRIORITY_REALTIME      = 6,          ///< priority: realtime (highest)OS_PRIORITY_ERROR         = 0x84        ///< system cannot determine priority or thread has illegal priority
} os_priority_t;
#endiftypedef struct os_thread_cb *os_thread_id;
typedef void (*os_pthread) (void const *argument);typedef struct {os_pthread             pthread;      ///< start address of thread functionos_priority_t          tpriority;    ///< initial thread priorityuint32_t               instances;    ///< maximum number of instances of that thread functionuint32_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 functionvoid *timer;      ///< pointer to internal data
} os_timer_def_t;typedef enum
{OS_TIMER_ONCE     = 0,    ///< one-shot timerOS_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)}
#endifos_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 queueuint16_t item_sz;  ///< size of an itemvoid *pool;        ///< memory array for mail
} os_mailq_def_t;#define os_mailq(name) &os_mailq_def_##nameos_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
#elseosMessageQueueAttr_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_##nameos_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 pooluint32_t item_sz; ///< size of an itemvoid *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_##nameos_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

[单片机框架][os层] freertos 中间件 公共函数相关推荐

  1. [单片机框架][drivers层][cw2015] fuelgauge 硬件电量计(二)

    接上一篇:[单片机框架][device层] fuelgauge 电量计 [单片机框架][drivers层][cw2015] fuelgauge 硬件电量计(一) 本章是硬件电量计的使用方法,采用IIC ...

  2. [单片机框架][drivers层][cw2015/ADC] fuelgauge 硬件电量计和软件电量计(一)

    接上一篇:[单片机框架][device层] fuelgauge 电量计 CW2015 是一款超紧凑.低成本.主机侧/电池组侧.无传感电阻器的电量计量系统 IC,适用于手持和便携式设备中的锂离子 (Li ...

  3. [单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][ESB(2.4G)] ESB(2.4G)使用说明

    这个指南描述了什么是ESB(Enhanced ShockBurst)以及如何在nRF5系列中使用ESB. ESB支持双向数据包通信,包括数据包缓冲,数据包确认和丢失数据包的自动重传的基本协议.ESB提 ...

  4. [单片机框架][bsp层][cx32l003][bsp_adc] ADC配置和使用

    ADC是模数转换器转换器 的供应商的英文简称,是一种能将模拟信号转变为数字信号的电子元件.通常是将信号采样并保持以后,再进行量化和编码,这两个过程是在转化的同时实现的. 分辨率-说明AD对输入信号的分 ...

  5. thinkphp框架配置验证是否登录公共函数的方法

    一 .首先tp5\application\index\controller下创建Common.php文件 <?php namespace app\index\controller; use th ...

  6. [单片机框架][device层] fuelgauge 电量计

    通过 DEVICE_INITCALL("dev-gauge", fuelgauge_dev_init); 注册驱动,自动在main初始化中运行. 优点:耦合少,可移植性强,适用大团 ...

  7. [单片机框架][bsp层][N32G4FR][bsp_uart] UART配置和使用

    USART 简介 通用同步异步收发器(USART)是一种全双工或半双工,同步或异步的一个串行数据交换接口.USART 提 供了可编程的波特率发生器,能对系统时钟进行分频产生 USART 发送和接收所需 ...

  8. [单片机框架][drivers层][extend_16ch] 16位恒流驱动芯片 MBI5020 JXI5020GP

    文章目录 一.简介 二.特性 三. 示例代码 一.简介 4pin控制16ping,IO扩展器件 二.特性 16 个等电流输出通道 等电流输出值不受输出端负载电压影响等电流范围值, 3-30mA@VDp ...

  9. php封装公共方法,TP框架下封装公共函数详解

    本篇文章讲述了如何在TP框架下封装公共函数,大家对TP框架下封装公共函数不了解的话或者对TP框架下封装公共函数感兴趣的话那么我们就一起来看看本篇文章吧, 好了废话少说进入正题吧 当我们需要在控制层调用 ...

  10. [单片机框架] [app_led] [WS2812x] 利用软定时器实现WS2812x闪烁和呼吸等灯光模式

    引脚编号 引脚名称 说明 1 DO 控制数据信号输出端 2 DI 控制数据信号输入端 3 VCC 控制电路电源正极 4 NC 空脚 5 VDD LED电源正极 6 VSS 电源负极 数据时序图 0,1 ...

最新文章

  1. 神器诞生!E3成首个3.50可降级国产电子狗
  2. 转发:为什么函数式编程至关重要
  3. 矫情这一次,感谢这几个人。
  4. 众神进入瓦尔哈拉_一时冲动:“通往瓦尔哈拉之路的冒险”
  5. udt java_Java DB中的Java用户定义类型(UDT)
  6. 过渡效果_剪映教程:剪映怎么添加视频之间的过渡转场效果?
  7. 用python内置函数算复杂度吗_Python减少代码量的两个内置函数
  8. Linux重启提示A stop job is running for ...
  9. 27款经典的 CSS 框架分享
  10. python小课账号转卖_Python小课笔记--Python报错处理
  11. 信号与系统2022春季学期:作业内容与参考答案-汇总
  12. 台达触摸屏和vfd-m变频器通讯控制监视程序
  13. Oracle创建用户后无法登录,报错ORA-01045: user lacks CREATE SESSION privilege
  14. JeecgBoot新增一个module
  15. ListView的增删改查(实战)
  16. 关于汇编语言中的立即寻址和直接寻址
  17. 淘宝图片怎么编辑处理?淘宝图片处理用什么软件?
  18. 如何搭建“业务化”的指标体系?
  19. 【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
  20. 基于PanoSim仿真开发平台BSD和RCTA的构思

热门文章

  1. 小程序 java在线考试系统python自动阅卷系统php自动组卷系统
  2. golang数据库的操作,更新删除增加单行查找与多行查找
  3. Qt配置OpenCV教程,亲测已试过(详细版)
  4. java图书馆抢座系统_java毕业设计_springboot框架的图书馆座位预约占座
  5. 清华大学计算机科学与技术专业设置,清华大学计算机科学与技术专业介绍
  6. IDEA自带的数据库连接工具连接(DM)达梦数据库
  7. 快收下这份照片模糊变清晰方法攻略
  8. PRML学习总结(1)——Introduction
  9. 经典合成器插件 – LennarDigital Sylenth1 v3.067 WiN
  10. 关于idea注释等颜色设置