发新帖我要提问
12
返回列表
打印
[应用相关]

FreeRtos——移植到 STM32 MCU 上面

[复制链接]
楼主: goodluck09876
手机看帖
扫描二维码
随时随地手机跟帖
21
goodluck09876|  楼主 | 2018-9-9 20:30 | 只看该作者 |只看大图 回帖奖励 |倒序浏览


使用特权

评论回复
22
goodluck09876|  楼主 | 2018-9-9 20:31 | 只看该作者
/*********************************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 任务创建,为了方便管理,所有的任务创建函数都可以放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  ********************************************************************************/
static void AppTaskCreate(void)
{
    xTaskCreate(vTaskLed1,           /* 任务函数名 */
                "Task Led1",         /* 任务名,字符串形式,方便调试 */
                 512,                /* 栈大小,单位为字,即4个字节 */
                 NULL,               /* 任务形参 */
                 1,                  /* 优先级,数值越大,优先级越高 */
                 &xHandleTaskLED1);  /* 任务句柄 */
}

使用特权

评论回复
23
goodluck09876|  楼主 | 2018-9-9 20:31 | 只看该作者
int main(void)
{
    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
    /* LED 端口初始化 */
    LED_GPIO_Config();
    /*创建任务*/
    AppTaskCreate();
    /*启动任务调度器,任务开始执行*/
    vTaskStartScheduler();
    while (1)
    {

    }
}

使用特权

评论回复
24
goodluck09876|  楼主 | 2018-9-9 20:32 | 只看该作者
这样编译下载之后,可以看到LED灯闪烁,即移植成功,其中省略了基础硬件初始化部分,建立在你可以不使用操作系统点亮LED灯的基础上,完成系统移植。

其中关于任务参数做一点说明:

在我的LED实验中没有使用任务参数,但是如果有相似功能的函数,我们可以不用使用多个任务函数实体,而在一个任务函数中多次创建任务,具体例子如下所示:

例 1 中创建的两个任务几乎完全相同,唯一的区别就是打印输出的字符串。这种重
复性可以通过创建同一个任务代码的两个实例来去除。这时任务参数就可以用来传递各
自打印输出的字符串。
程序清单 8 包含了例 2 中用到的唯一一个任务函数代码(vTaskFunction)。这一个
任务函数代替了例 1 中的两个任务函数(vTask1 与 vTask2)。这个函数的任务参数被强
制转化为 char*以得到任务需要打印输出的字符串。

使用特权

评论回复
25
goodluck09876|  楼主 | 2018-9-9 20:32 | 只看该作者
void vTaskFunction( void *pvParameters )
{
char *pcTaskName;
volatile unsigned long ul;
/* 需要打印输出的字符串从入口参数传入。强制转换为字符指针。 */
pcTaskName = ( char * ) pvParameters;
/* As per most tasks, this task is implemented in an infinite loop. */
for( ;; )
{
/* Print out the name of this task. */
vPrintString( pcTaskName );
/* Delay for a period. */
for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
{
/* This loop is just a very crude delay implementation. There is
nothing to do in here. Later exercises will replace this crude
loop with a proper delay/sleep function. */
}
}
}

使用特权

评论回复
26
goodluck09876|  楼主 | 2018-9-9 20:33 | 只看该作者
尽管现在只有一个任务实现代码(vTaskFunction),但是可以创建多个任务实例。每
个任务实例都可以在 FreeRTOS 调度器的控制下独运行。
传递给 API 函数 xTaskCreate()的参数 pvPrameters 用于传入字符串文本。

/* 定义将要通过任务参数传递的字符串。定义为const,且不是在栈空间上,以保证任务执行时也有效。 */
static const char *pcTextForTask1 = “Task 1 is running\r\n”;
static const char *pcTextForTask2 = “Task 2 is running\t\n”;
int main( void )
{
/* Create one of the two tasks. */
xTaskCreate( vTaskFunction, /* 指向任务函数的指针. */
"Task 1", /* 任务名. */
1000, /* 栈深度. */
(void*)pcTextForTask1, /* 通过任务参数传入需要打印输出的文本. */
1, /* 此任务运行在优先级1上. */
NULL ); /* 不会用到此任务的句柄. */
/* 同样的方法创建另一个任务。至此,由相同的任务代码(vTaskFunction)创建了多个任务,仅仅是传入
的参数不同。同一个任务创建了两个实例。 */
xTaskCreate( vTaskFunction, "Task 2", 1000, (void*)pcTextForTask2, 1, NULL );
/* Start the scheduler so our tasks start executing. */
vTaskStartScheduler();
/* If all is well then main() will never reach here as the scheduler will
now be running the tasks. If main() does reach here then it is likely that
there was insufficient heap memory available for the idle task to be created.
CHAPTER 5 provides more information on memory management. */
for( ;; );
}
程序清单 9 例 2 中的 main()函数实现代码

使用特权

评论回复
27
goodluck09876|  楼主 | 2018-9-9 20:33 | 只看该作者
既然官方手册都给出了参考了,那么作为学习,我们也该操练一下,使用任务参数,完成三个LED灯切换:

更改任务函数如下:

void vTaskLed1(void *pvParameters)
{
    /* 任务都是一个无限,不能返回 */
    int *piParameters;
    piParameters=(int *)pvParameters;
    while(1)
    {
        if(*piParameters==1)
        {
            LED1( ON );
            /* 阻塞延时,单位ms */        
            vTaskDelay( 500 );
            LED1( OFF );   
            vTaskDelay( 500 );
        }
        else if(*piParameters==2)
        {
            LED2( ON );
            /* 阻塞延时,单位ms */        
            vTaskDelay( 500 );
            LED2( OFF );   
            vTaskDelay( 500 );
        }
        else if(*piParameters==3)
        {
            LED3( ON );
            /* 阻塞延时,单位ms */        
            vTaskDelay( 500 );
            LED3( OFF );   
            vTaskDelay( 500 );
        }
    }   
}

使用特权

评论回复
28
goodluck09876|  楼主 | 2018-9-9 20:33 | 只看该作者
全局区增加标志定义:

static const int task_led1=1;
static const int task_led2=2;
static const int task_led3=3;

使用特权

评论回复
29
goodluck09876|  楼主 | 2018-9-9 20:34 | 只看该作者
static void AppTaskCreate(void)
{
    xTaskCreate(vTaskLed1,           /* 任务函数名 */
                "Task Led1",         /* 任务名,字符串形式,方便调试 */
                 512,                /* 栈大小,单位为字,即4个字节 */
                 (void *)&task_led3,  // task_led1-task_led3可以切换   /* 任务形参 */
                 1,                  /* 优先级,数值越大,优先级越高 */
                 &xHandleTaskLED1);  /* 任务句柄 */
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则