8.1-uC/OS-III多任务应用
1.app.c:
( 1) .分别为每个任务分配一个OS_TCB。
(2). 斥信号量( mutex)是一个内核对象(一个结构体),用于保护共享资源。任务要访问共享资源就必须先获得 mutex。 mutex的拥有者使用完这个资源后就必须释放这个mutex。 这个例子示范了这个过程。
(3). 消息队列是一个内核对象, ISR或任务可以直接发送消息到另一个任务。发送者制定一个消息并将其发送到目标任务的消息队列。 目标任务等待消息的到达。 如果消息到达了, 目标任务取得这些消息。 如果消息队列为空, 目标将会被安放在挂起队列中并与消息队列保持联系。
(4). 为每个任务分配堆栈。 {由于是CPU_STK类型, 它是
32位的,所以128个CPU_STK即位512B}。
(5).用户需要申明这些任务。
2.main.
(1).调用OSMutexCreate()创建一个mutex。 指定OS_MUTEX对象的地址。可以为mutex定义一个ASCII名字,对调试会很有用处。
(2).调用OSQCreate()创建消息队列, 并指定OS_Q对象的地址。
为消息队列命名。定义该消息队列可接受消息的个数。 这个值必须大于0。 如果消息者发送消息数超过了消息接收任务的承受能力。那么消息将会被丢失。可以通过增加消息队列的大小或者提供消息接收任务的优先级提升其承受能力
(3).一个应用任务被创建。
3.多任务创建:
(1).通过调用 OSTaskCreate()创建任务#1。如果被创建任务的优先级大于创建它的任务的优先级。 uC/OS-III会转向执行任务#1.如果被创建任务的优先级小于创建它的任务的优先级,OSTaskCreate()将会返回AppTaskStart()继续执行下面的代码。
(2).任务#2被创建,如果其优先级大于AppTaskStart()的优先级 。那么uC/OS-III将会立即去执行任务#2。
4.任务函数1:
(1).该任务在执行前先等待一个时基。 如果uC/OS-III的时基频率为1000HZ。那么这个任务每毫秒被执行一次。
(2).该任务向消息队列AppQ发送一个消息。 为了说明, 在例子中发送的是一个 void* 1。但实际上消息中包含着的是一个地址。内存地址、函数的地址、或者其它需要被传送的地址。
(3).该任务等待一个信号量。 如果它需要访问已被其它任务占用的资源, APPTaskStart1()等待这个mutex被释放。 第二个参数为其等待时限,以时基为单位,若0时就会一直等待下去。
(4).当 OSMutexPend()返回了,就表明该任务占用了这个共享资源。共享资源可能是变量、数组、数据域、 IO等。
(5).如果任务完成对共享资源的使用,它必须调用OSMutexPost()
释放这个mutex。
5.任务函数2:
(1). 任务#2开始执行, 并等待消息队列AppQ中的消息,这个任务会无限等待下去因为第三个参数为0,意味着无限等待。
消息的发送者和接收者都必须知道这个消息中所包含的信息。接收消息的大小存于”msg_size”。”p_msg”是调用该函数后返回的消息地址,指向内存且”msg_size”中包含这这个内存区的大小。
当接收到消息时, “ts”中包含的是消息被发送时的时间戳。 时间戳的值读取于硬件定时器。时间戳是一个32位(或更大)的值。
(2).测得消息是什么时候被发送的,用户就能测得任务接收这个消息所用的时间。读取现在的时间戳并减去消息被发送时的时间戳。 请注意, 消息被发送时, 等待消息的任务可能不会立即接收到消息,因为ISR或更高优先级的任务需要被运行。
(3).处理接收到的消息。