前言:本人使用的是STM32F103VC开发板,标准的8MHz晶振,72MHz主频运行。
用M3处理器的话,不用实时操作系统显得太没效率了。正好也看到Micrium官方把uC/OS-III的源代码放出来了。于是从官网下了一个针对STM32F版本的uC/OS-III,修改了下里面的任务函数,改成点亮发光二极管,编译下载后不执行。一看Micrium官方这个版本是针对STM32F107的,互联网型,标准晶振是25MHz,我想可能是频率设置不对,我也不想去探索如何解决。
我从Keil官网上下载最新的MDK423,看到里面关于RTX_Kernel的介绍。以前写51单片机程序的时候知道RTX这个东西,但从来没用过。这次打算用下RTX_Kernel试试,毕竟RTX_Kernel是商用免费的,uC/OS是商用收费的。另外是ARM Keil自家的东西,想必也不错。
正式开始我的RTX_Kernel使用例程:
1、我的Keil MDK版本是此时从官网下载的最新版本MDK423,之前的Keil注册机在这里可用。
2、在ST官方网站下载STM32F10x_StdPeriph_Lib_V3.5.0,用这里面的工程作为工程模板。
3、依据ST官方库的例子,建立一个GPIO/IOToggle
工程。修改里面的IO端口与你的板子匹配。编译运行成功。
4、开始使用RTX_Kernel。在main.c中加入
项目选项里,在Target下,Operating
system选择 RTX Kernel复制
D:\Keil\ARM\Boards\ST\STM32F10X_EVAL\RTX_Blinky\RTX_Config.h到项目目录下,并将RTX_Config.h添加到项目中。
然后main.c的主要代码如下:
- /*----------------------------------------------------------------------------
-
* Task 1
-
*---------------------------------------------------------------------------*/
-
__task void task1 (void) {
-
for (;;) {
-
led1on(); //点亮LED1,函数具体内容依照你的开发板
-
os_dly_wait (10);
-
led1off(); //熄灭LED1
- os_dly_wait (10);
-
}
-
}
-
/*----------------------------------------------------------------------------
-
* Task 2
-
*---------------------------------------------------------------------------*/
-
__task void task2 (void) {
-
for (;;) {
-
led2off();
//熄灭LED2,函数具体内容依照你的开发板
-
os_dly_wait (10);
-
led2on();
-
os_dly_wait (10);
-
}
-
}
-
/*----------------------------------------------------------------------------
-
* Task 'init': 建立所有的任务
-
*---------------------------------------------------------------------------*/
-
__task void init_task (void) {
-
-
id1 = os_tsk_create (task1, 0); /* start task phaseA */
-
id2 = os_tsk_create (task2, 0); /* start task phaseB */
-
os_tsk_delete_self ();
-
}
-
int main(void)
-
{
-
/*!< At this stage the microcontroller clock setting is already configured,
-
this is done through SystemInit() function which is called from startup
-
file (startup_stm32f10x_xx.s) before to branch to application main.
-
To reconfigure the default setting of SystemInit() function, refer to
-
system_stm32f10x.c file
-
*/
-
-
/* To achieve GPIO toggling maximum frequency, the following sequence is mandatory.
-
You can monitor PD0 or PD2 on the scope to measure the output signal.
-
If you need to fine tune this frequency, you can add more GPIO set/reset
-
cycles to minimize more the infinite loop timing.
-
This code needs to be compiled with high speed optimization option.
- */
-
-
GPIO_Config(); //IO口初始化函数,具体根据你的开发板
-
os_sys_init (init_task);
-
-
}
上面代码很简单,不用解释,一看即明白。编译,运行,会看到两个发光二极管一闪一闪的。恭喜你,RTX
Kernel成功运行了!
说明:编译时如果提示有3个函数定义冲突,在stm32f10x_it.c中屏蔽掉那三个函数即可。
5、RTX Kernel教程
实际上RTX Kernel API比较简单,相对于uC/OS-III而言。有一些uc/OS的基础的话,参照Keil帮助文档和rtl.h头文件,即可轻松使用RTX的API。简要总结如下:
首先说明一点,RTX是时间片轮转调度的,即相同任务优先级每个任务分得一定的时间片运行。uC/OS-II是不支持时间片轮转的,uC/OS-III开始支持时间片轮转调度。
(1)事件管理:os_evt_wait_and(), os_evt_wait_or()
os_evt_set()
isr_evt_set()
让一个进程等待一个事件,这个事件可以由其它进程和中断触发。
(2)邮箱管理: os_mbx_declare(), os_mbx_init()
os_mbx_wait()
os_mbx_send(), isr_mbx_send()
建立一个邮箱,里面可以存放一定数目的消息(比如20条)。进程可以等待邮箱队列,如果邮箱里有消息,则取出,进程继续执行;如果邮箱为空,则继续等待。
(3)互斥管理:os_mut_init ()
os_mut_wait() //上锁
os_mut_release() //解锁
进程独占的资源,加个锁,别的进程需要等待。
(4)信号量管理:os_sem_init, os_sem_send, os_sem_wait, isr_sem_send
信号量与事件类似,进程等待的信号量大于0时,进程继续执行,信号量-1。发送信号量时,信号量+1.
(5)延时: os_dly_wait(),延时指定数目的系统节拍事件。
整个RTX Kernel组成图如下:
6、中断
中断函数的编写与非RTX程序一样,注意中断及时的返回,不要发生意外嵌套。
7、小结
RTX的使用明显比uC/OS容易些,如果在M3下使用RTOS的话,个人感觉优先RTX。至于具体的RTX学习资料,Keil参考手册和rtl.h头文件这两个文档足矣。
阅读(17696) | 评论(0) | 转发(0) |