杨为民 发表于 2023-8-6 13:45:57

STC32G FreeRTOS入门(2):单片机前后台任务编程中的问题

FreeRTOS是一款开源的专为小型嵌入式系统设计的可扩展的实时内核,已经被移植到STC最新的STC32G12K128单片机上了。在STC官网上给出了以STC32G实验箱为平台的FreeRTOS演示范例,该范例充分展示了FreeRTOS的特色、STC32G单片机的性能和STC32G实验箱的功能。通常将单片机程序分为两大类:常见的裸机程序和RTOS程序。本系列文章计划以FreeRTOS为例,由浅入深地介绍RTOS的基本概念和如何进行RTOS编程。本文介绍单片机前后台任务编程中出现的库函数不可重入问题 一、前言STC32GFreeRTOS入门(1)介绍的“后台任务”是一个连续执行的过程,这在自然界中也是一个常见的现象。比如天气一年年周而复始地变化,春夏秋冬四季轮回不止,比如我们每天工作学习,吃饭睡觉,一天一天的过日子,这些就是气候和生活的“后台任务”,构成了气候和生活的基本生命背景。但是气候和生活最精彩的部分却不是这些“后台任务”,而是中断后台任务的进程,突然插入的片段,比如台风来了,所到之处天摇地动,比如你的手机响了,接到的电话会立马产生影响,快乐?忧愁?无限可能。这种中断事物当前的运行,临时处理新事件的过程在操作系统的术语中被称为“前台任务”。前台任务的特点是只执行一个比较短的时间,有开始,有结束,唯独不能像“后台任务”那样无限循环没完没了。在计算机运行过程中,每个中断处理都是典型的“前台任务”,中断服务程序(ISR)就是对应各个前台任务的任务函数。既然前台任务中断了后台任务,那么前台任务执行过后后台任务能不能继续顺利地执行,两者会不会互相影响,这个问题对于不同的单片机,不同的编译器和不同的编程方法,结论是不同的。由于教科书一般只介绍成功的例子:后台任务被中断后能继续正确运行,前后台任务互相没有影响,下面就介绍一些不成功的例子。 二、前台任务(1)单片机最有特色的机制就是中断,中断编程是单片机编程中最重要的内容。STC8H系列单片机有丰富的中断资源,其中定时器中断是最基本的,本文用定时器0产生每秒100次的中断,演示作为前台任务的效果。下图是具体的范例程序:

(2)其中第37行到43行的初始化程序将定时器0设定在10毫秒的中断周期。对于STC8051系列单片机,单片机中断有两级开关,首先一个是总中断开关EA,第50行就是打开中断总开关,其次对于每一个能产生中断的片上设备,都有一个中断允许位,只有设置了这个中断允许位,该设备才能产生中断。第43行程序就是允许定时器0产生中断。为了避免意外,当单片机加电冷复位是,所有的设备中断和总中断都是关闭的,用到谁,打开谁。(3)为了专门显示前台任务的效果,第54行到第57行后台任务就只是一个空循环,什么事都不做。(4)第61行到第71行是定时器0的中断服务程序(前台任务函数),在C51语言,用户用“interrupt”关键字指明中断号,这里是1号中断。作为前台任务的中断,是由单片机硬件产生的,中断服务程序是由硬件调用的,因此前台任务函数没有调用参数,也没有返回值。前台任务函数名可以是任意的,但在整个程序中必须是唯一的。(5)前台任务首先将节拍计数变量“Tick0”加1,然后每当Tick0的值为100的整倍数时,用“printf”库函数输出Tick0变量的值。
下面的视频是前台任务执行的效果。三、前后台任务
(6)我们已经看到了单独的后台任务和单独的前台任务的运行效果,如果我们在一个程序中将前后台任务组合在一起,其效果会不会像教科书中介绍的那样前后台任务独立正确的运行呢?下图是完整的前后台任务程序:

(7)下面是前后台任务程序在STC8H的运行结果视频:
从视频可以看到,前台任务每1秒钟的输出都是正常的,但是每次从串口输入两个数让后台任务做加法时,后台任务的输入输出都是错误的。
(8)下面是运行效果的截屏:
出错的现象奇奇怪怪,出错的不是单片机,也不是程序员,出错的原因是“printf”这个库函数。
(9)结论:对于STC8H单片机,使用Keil的C51编译器,“printf”这个库函数不能在前后台任务中同时使用,因为C51的库函数“printf”是不可重入的。下面是本文范例程序:

jwd 发表于 2023-8-6 22:14:05

请问这种编译不会出错吗?

杨为民 发表于 2023-8-6 22:20:57

jwd 发表于 2023-8-6 22:14
请问这种编译不会出错吗?

不会出错,程序员自己注意不要让两个任务同时调用不可重入函数就可避免。

jwd 发表于 2023-8-6 22:31:11

杨为民 发表于 2023-8-6 22:20
不会出错,程序员自己注意不要让两个任务同时调用不可重入函数就可避免。 ...

好的,谢谢老师指点!

llyymm 发表于 2023-8-6 22:48:26

从基础讲起,感谢版主的知识分享!

向日葵男人 发表于 2024-1-2 20:34:17

有图有真相,写的真好

大锤子 发表于 2024-11-10 17:41:47

杨老师能讲讲 printf这个库函数为什么是不可重入的吗?

杨为民 发表于 2024-11-10 21:11:24

大锤子 发表于 2024-11-10 17:41
杨老师能讲讲 printf这个库函数为什么是不可重入的吗?

因为它使用了全局变量
页: [1]
查看完整版本: STC32G FreeRTOS入门(2):单片机前后台任务编程中的问题