目录
RTX介绍
官网文档: https://www.keil.com/pack/doc/cmsis/RTOS/html/index.html
如何查看当前使用的内核版本:
在cmsis_os.h中:
这里可以看到我使用的sdk的RTX版本信息
API版本为:v1.0.1
系统版本为:v4.61
如果你对实时操作系统已经架构有所了解,接下来重要的事情,我们该怎么使用去,那么就需要去查清系统提供的API,可以去查阅文章开头的官网中查阅文档
Function Overview是API的概览,相当于一个简述
Reference中则是更详细的api使用说明。
英语不好的朋友也可以利用Google浏览器自带的翻译插件翻译成中文。
运用示例
下面简要说明一些模块的使用
线程
/*定义!注意:定义的时候可以配置线程的优先级,具体的个数(可以类比结构体数组进行理解),线程堆栈大小等,这里只是一个参考,具体的参数根据实际的需求设定*/
osThreadDef(appTestThread1, (osPriorityAboveNormal), 1, (BESBT_STACK_SIZE), "appTestThread1");
osThreadId app_test1_tid = NULL;
/*处理*/
static void appTestThread1(void const *argument)
{
while(1) {
TRACE(1,"appTestThread1\n");
osMessageGet(app_test1_queue_id, osWaitForever);
app_test1_mail_poll();
//if(osFeature_Wait)
//osDelay(500);
}
}
/*创建*/
void app_test1_thread_init(void)
{
app_test1_tid = osThreadCreate(osThread(appTestThread1), NULL);
TRACE(1,"appTestThread1Init: %p\n", app_test1_tid);
}
Timer
/*定义*/
osTimerDef (APP_TEST_THREAD1_TIMER, (void (*)(void const *))app_test1_timer_handler);
osTimerId app_test1_timer = NULL;
/* 处理*/
static void app_test1_timer_handler(void const *param)
{
...
}
/* 启动 */
static void app_test1_timer_start()
{
...
}
/* 停止 */
static void app_test1_timer_stop()
{
...
}
/* 创建 */
void app_test1_timer_init(void)
{
app_test1_timer = osTimerCreate(osTimer(APP_TEST_THREAD1_TIMER), osTimerOnce, NULL);
}
信号量
/* 定义 */
osSemaphoreDef(app_rtx_test_semaphore);
osSemaphoreId app_rtx_test_semaphore_id = NULL;
/* 获取 */
int app_rtx_test_sem_lock(void)
{
osSemaphoreWait(app_rtx_test_semaphore_id, osWaitForever);
return 0;
}
/* 释放 */
int app_rtx_test_sem_unlock(void)
{
osSemaphoreRelease(app_rtx_test_semaphore_id);
return 0;
}
/* 创建 */
int app_rtx_test_sem_init(void)
{
if (app_rtx_test_semaphore_id == NULL) {
app_rtx_test_semaphore_id = osSemaphoreCreate(osSemaphore(app_rtx_test_semaphore), 1);
}
return 0;
}
互斥锁
/* 定义 */
osMutexDef(app_rtx_test_mutex);
osMutexId app_rtx_test_mutex_id = NULL;
/* 加锁 */
int app_rtx_test_mutex_lock(void)
{
osMutexWait(app_rtx_test_mutex_id, osWaitForever);
return 0;
}
/* 解锁 */
int app_rtx_test_mutex_unlock(void)
{
osMutexRelease(app_rtx_test_mutex_id);
return 0;
}
/* 创建 */
int app_rtx_test_mutex_init(void)
{
if (app_rtx_test_mutex_id == NULL) {
app_rtx_test_mutex_id = osMutexCreate((osMutex(app_rtx_test_mutex)));
}
return 0;
}
内存池
/* 定义!这里去申请内存池的时候,好像是需要固定元素的的个数以及类型,比如这里我的内存池中有10个APP_RTX_TEST_POOL_BLOCK类型的数据,从内存池申请内存块的时候,只能以APP_RTX_TEST_POOL_BLOCK类型进行申请,并且使用中的最多不能超过10个 */
osPoolDef (app_rtx_test_mempool, 10, APP_RTX_TEST_POOL_BLOCK);
osPoolId app_rtx_test_mempool_id = NULL;
/* 从内存池获取一块内存 */
APP_RTX_TEST_POOL_BLOCK *app_rtx_test_pool_malloc(void)
{
...
}
/* 释放 */
int app_rtx_test_pool_free(void *addr)
{
...
}
/* 创建 */
int app_rtx_test_pool_init(void)
{
if (app_rtx_test_mempool_id == NULL)
app_rtx_test_mempool_id = osPoolCreate(osPool(app_rtx_test_mempool));
}
消息队列
/* 定义 */
osMessageQDef(app_test1_queue, 128, uint32_t);
osMessageQId app_test1_queue_id = NULL;
/* 发送消息 */
void app_test1_queue_put(void)
{
if (osMessageGetSpace (app_test1_queue_id) > 5 ) {
osMessagePut(app_test1_queue_id, 0xFF, 0);
}
}
/* 创建 */
static int32_t app_test1_queue_init(void)
{
app_test1_queue_id = osMessageCreate(osMessageQ(app_test1_queue), NULL);
if (app_test1_queue_id == NULL) {
TRACE(0,"Failed to Create app_test_thread1_queue");
return -1;
}
return 0;
}
/* 定义 */
osMailQDef (app_test1_mailbox, APP_TEST1_MAX_MAILBOX, APP_TEST1_MAIL);
static osMailQId app_test1_mailbox_id = NULL;
static int app_test1_mail_alloc(APP_TEST1_MAIL** mail)
{
...
}
/* 发送 */
static int app_test1_mail_send(APP_TEST1_MAIL* mail)
{
...
}
static int app_test1_mail_free(APP_TEST1_MAIL* mail_p)
{
...
}
/* 获取 */
static int app_test1_mail_get(APP_TEST1_MAIL** mail_p)
{
...
}
/* 创建 */
static int32_t app_test1_mailbox_init(void)
{
app_test1_mailbox_id = osMailCreate(osMailQ(app_test1_mailbox), NULL);
if (app_test1_mailbox_id == NULL) {
TRACE(0,"Failed to Create app_test_thread1_mailbox");
return -1;
}
return 0;
}
上面有些我可能只贴出了部分,完整代码以及相关的测试代码,我已经放到<bes2300开发调试笔记>底部的网盘链接中了,需要的可以去下载!
测试代码使用方法
- 将解压的rtx_test文件夹放到/apps目录下
- 修改/apps目录下的Makefile,添加rtx_test目录
- 由于我的两个模块初始化接口是在app_init中的
所以还需要修改/apps/main文件下面的Makefile文件,添加相应的包含路径
添加好之后,重新build~download就可以可以看到两个线程模块已经跑起来了。
需要说明的是,thread1与thread2模块的代码几乎是一模一样的,主要是为了方便测试线程间的同步与通信,common模块则是放的一些两个线程公共使用的模块,方便测试互斥锁、信号量和内存池。
相关资料请到<bes2300开发调试笔记>文章底部的网盘链接中下载!