本帖最后由 creep 于 2017-5-6 17:28 编辑
STM32中文官网(www.stmcu.com.cn)
在上一个开箱测试帖子我们进行了简单的串口输出和点灯测试,这次就把这个测试移植到UCOSIII实现。在ST的HAL开发包了cubemx有很多freeRTOS的例子,作为一款免费的RTOS,freeRTOS越来越多被众多开发者使用和讨论,如果要学习freeRTOS,只要去研究ST提供的例子就基本应该可以入门。和freeRTOS相比我更喜欢UCOSIII的代码风格和结构,虽然收费但是目前UCOSIII依旧是开源可以下载到最新的源码。如果选择一个RTOS入门,UCOSIII从教程到代码本身都是一个很好的选择。下面是ST的HAL开发包中提供的freeRTOS的例程。
1、UCOSIII的下载和移植
在UCOSIII的官方网站上注册后可以下载到移植好的很多ST的开发板的例子,从IAR到MDK都可以找到可以参考的例程。如果嫌麻烦不想注册去下载也可以参考国内很多开源的例程中的源码,大致的源码结构如下,具体的移植步骤可以参考原子*野火*安富莱等开源的移植步骤。
■首先是定义一些任务的堆栈、控制块、任务函数这些变量,为了看起来整洁,我把这些任务需要的定义都放在了一个单独的C文件中,然后再main函数中包含这个C文件:
然后在main文件中包含
■ 在main函数中主要是初始化OS,创建一个开始任务,然后启动任务
- int main(void)
- {
- OS_ERR err;
- CPU_SR_ALLOC();
- HAL_Init();
- SystemClock_Config();
- delay_init(80);
- LPUART1_Init();
- LED_Init();
- OSInit(&err);
- OS_CRITICAL_ENTER();
- OSTaskCreate((OS_TCB * )&StartTaskTCB,
- (CPU_CHAR * )"start task",
- (OS_TASK_PTR )start_task,
- (void * )0,
- (OS_PRIO )START_TASK_PRIO,
- (CPU_STK * )&START_TASK_STK[0],
- (CPU_STK_SIZE)START_STK_SIZE/10,
- (CPU_STK_SIZE)START_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void * )0,
- (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
- (OS_ERR * )&err);
- OS_CRITICAL_EXIT();
- OSStart(&err);
- while(1);
- }
复制代码 ■ 然后在开始任务中 创建1个LED闪烁任务,2个串口输出任务
- void start_task(void *p_arg)
- {
- OS_ERR err;
- CPU_SR_ALLOC();
- p_arg = p_arg;
- CPU_Init();
- #if OS_CFG_STAT_TASK_EN > 0u
- OSStatTaskCPUUsageInit(&err);
- #endif
-
- #ifdef CPU_CFG_INT_DIS_MEAS_EN
- CPU_IntDisMeasMaxCurReset();
- #endif
-
- #if OS_CFG_SCHED_ROUND_ROBIN_EN
-
- OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
- #endif
-
- OS_CRITICAL_ENTER();
-
- OSTaskCreate((OS_TCB * )&Task1_TaskTCB,
- (CPU_CHAR * )"Task1 task",
- (OS_TASK_PTR )task1_task,
- (void * )0,
- (OS_PRIO )TASK1_TASK_PRIO,
- (CPU_STK * )&TASK1_TASK_STK[0],
- (CPU_STK_SIZE)TASK1_STK_SIZE/10,
- (CPU_STK_SIZE)TASK1_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void * )0,
- (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
- (OS_ERR * )&err);
-
-
- OSTaskCreate((OS_TCB * )&Task2_TaskTCB,
- (CPU_CHAR * )"task2 task",
- (OS_TASK_PTR )task2_task,
- (void * )0,
- (OS_PRIO )TASK2_TASK_PRIO,
- (CPU_STK * )&TASK2_TASK_STK[0],
- (CPU_STK_SIZE)TASK2_STK_SIZE/10,
- (CPU_STK_SIZE)TASK2_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void * )0,
- (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
- (OS_ERR * )&err);
-
- OSTaskCreate((OS_TCB * )&Task3_TaskTCB,
- (CPU_CHAR * )"task3 task",
- (OS_TASK_PTR )task3_task,
- (void * )0,
- (OS_PRIO )TASK3_TASK_PRIO,
- (CPU_STK * )&TASK3_TASK_STK[0],
- (CPU_STK_SIZE)TASK3_STK_SIZE/10,
- (CPU_STK_SIZE)TASK3_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void * )0,
- (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
- (OS_ERR * )&err);
-
- OS_CRITICAL_EXIT();
- OSTaskDel((OS_TCB*)0,&err);
- }
复制代码 ■ LED任务就是周期的闪烁,串口不停的打印信息
- //LED task1
- void task1_task(void *p_arg)
- {
- static uint8_t sta = ON;
- OS_ERR err;
- while(1)
- {
- LED1(sta);
- LED2(sta);
- LED3(sta);
- sta = !sta;
- OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s
-
- }
- }
- // UART task2
- void task2_task(void *p_arg)
- {
- OS_ERR err;
- CPU_SR_ALLOC();
- while(1)
- {
- OS_CRITICAL_ENTER();
- printf("Please do not respond,the message from Task2!!\r\n");
- OS_CRITICAL_EXIT();
- OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s
- }
- }
- //UART task3
- void task3_task(void *p_arg)
- {
- OS_ERR err;
- CPU_SR_ALLOC();
- while(1)
- {
- OS_CRITICAL_ENTER();
- printf("Please do not respond,the message from Task3!!\r\n");
- OS_CRITICAL_EXIT();
- OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s
- }
- }
复制代码 2、测试结果
LED闪烁效果
与此同时串口输出几乎会“同时”输出信息如下:
STM32L496使用的是M4内核,如果之前做过同样的移植那么移植到Nucleo-L496就会比较方便,如果没有移植过也可以参考很多的教程和文档。
测试代码:
UCOSIII-LED.rar
(1.49 MB, 下载次数: 101)
|
其实这个和哪个系列关系不大,只要移植好一个工程模板,freeRTOS的其他功能的移植可以参考其他系列其他开发板里面的例子,都是一样的。
嗯,从L496移植到L432应该很方便.