查看: 3052|回复: 2

[原创] cobemx + HAL 库 + freeRTOS 点灯

[复制链接]
  • TA的每日心情
    开心
    2024-1-16 17:48
  • 签到天数: 592 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2018-10-20 19:35:13 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 robe.zhang 于 2018-10-20 19:40 编辑

    cobemx 配置:freeRTOS 选上,sys 里面有个 source clock ,原本是 systick 的,这个地方要改改,不用 systick,其他随便选一个时钟就行,用的就是基本计时功能,随便一个timer 都可以满足,我顺手选的 timer1
    21.png
    确认 freeRTOS  sys 里面时钟不是 systick 就行,这里忘了也没事,生成代码时候会提醒,再回头改。
    22.png
    这个是系统参数,就是 freertos 配置的选项,本帖就是点个灯,高级功能也不用,看看堆栈大小,记住后面用,全部使用默认选项。
    23.png
    这个是生成代码时候堆栈大小,堆是 15KB,栈是 128字节,点两个灯,每个灯128字节,大概就需要这么多资源,
    我这里随手分了两个 64KB,f407 是 192KB 分出去 128KB , 也没事。
    24.png
    确认完好,点生成代码,使用 keil 打开工程,写点灯程序:( freeRTOS 是 9.0.0 版本的)
    1.   osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
    2.   defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
    复制代码
    这是工程自己带的,默认任务,可以直接用,但是本帖是想要两个任务分别控制一个LED灯,让他闪的,一个任务不够用,所以就没有用这个任务,重新创建两个任务;这里有个小捷径,系统带个任务,比葫芦画瓢,照猫画虎,抄出来两个任务就行了,这个方法最简单,也最有效,就这么干:
    1. osThreadDef(led0_taskname, led0_taskfun, osPriorityNormal, 0, 128);
    2.         osThreadDef(led1_taskname, led1_taskfun, osPriorityNormal, 0, 128);
    3.         
    4.         led0_taskhandle = osThreadCreate(osThread(led0_taskname), NULL);
    5.         led1_taskhandle = osThreadCreate(osThread(led1_taskname), NULL);
    复制代码
    osThreadDef(led0_taskname, led0_taskfun, osPriorityNormal, 0, 128); 这个语句是个宏,括号里面是变量,各个变量有必要浏览一下
    第一个变量led0_taskname, 这个参数是结构体名字,随便取别重复,别太长,16字以内,上面系统配置的时候默认有这个要求,不能大于16字节,没改,要知道有这个要求
    第二个参数,是任务的主体,就是这个任务要执行那个函数,led0_taskfun 就是这个函数的名字。(这个函数需要稍后自己实现,还需要提前声明一下)
    第三个参数是优先级,不用动,照抄
    第四个参数是这个任务里面最大有几个线程,搞得想 linux 了,进程里面跑线程,应该是不支持吧,不懂,人家写0我们也写0
    第五个参数栈大小,就128吧
    完了,里面使用了两个任务函数,需要声明一下1,再实现一下2,

    后两句 led0_taskhandle = osThreadCreate(osThread(led0_taskname), NULL); 就是创建任务函数了,里面就一个参数就是结构体名字,返回值是handle,这个handle 变量没有定义,需要定义3。
    完了,任务就这四条语句就创建完了,能跑了。
    然后1,2,3标识数字的三个地方是遗留的事情,完善一下,编译就可以下载运行了
    1,声明两个任务函数:
    1. void led0_taskfun(void const * argument);
    复制代码
    2,实现了这两个函数
    1. void led0_taskfun(void const * argument)
    2. {
    3.         for(;;)
    4.   {
    5.                 HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);
    6.     osDelay(200);
    7.   }
    8. }
    9. void led1_taskfun(void const * argument)
    10. {
    11.         for(;;)
    12.   {
    13.                 HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);
    14.     osDelay(300);
    15.   }
    16. }
    复制代码
    3,定义连个handle变量:
    1. osThreadId led0_taskhandle;
    2. osThreadId led1_taskhandle;
    复制代码
    编译下载运行,灯就开始闪了。很简答吧,freeRTOS 就这么简单。
    两个任务里面用到了一个系统延时函数,osDelay(300);, 参数单位是毫秒,改改数字让灯交替的闪吧。
    如果是有10个灯,分辨是按照间隔 1 3 5 7 11 13 17 19 这个间隔闪的话,如果不用 freeRTOS ,main 函数逻辑是不是就很难搞了,使用 freeRTOS,直接创建 10 个任务,一个任务一个闪灯和延迟函数,就完事。运行逻辑交给 freeRTOS 不用头疼了。


    回复

    使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2019-1-21 10:51:23 | 显示全部楼层
    是该多加点照片
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-16 17:48
  • 签到天数: 592 天

    连续签到: 1 天

    [LV.9]以坛为家II

     楼主| 发表于 2019-1-21 13:31:23 | 显示全部楼层

    你说的太对了,
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-3-29 01:39 , Processed in 0.139790 second(s), 20 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.