Comprensión del código de función relacionado con el semáforo de tareas uCOS

Enfatice la idea del semáforo de tareas : ① El semáforo de tareas es solo un signo. El éxito significa restar el valor del conteo del semáforo en 1; liberar significa agregar 1 al valor del conteo del semáforo (el valor del conteo permanece sin cambios si se desborda). ② Para obtener el semáforo, debe determinar si el semáforo está disponible (mayor que 0), si está disponible, significa que la adquisición será exitosa (los números mayores que 0 se pueden disminuir en 1 o> = 0), luego puede obtener la marca de tiempo actual y la última versión anterior. La diferencia en la marca de tiempo se usa como el tiempo de espera del semáforo (guardado en el elemento SemPendTime en TCB). ③ En la función de liberación, debido a que la liberación no considera si el semáforo de la tarea está disponible, la liberación es una operación para aumentar el número de semáforos disponibles, por lo que si una serie de comprobaciones de seguridad y parámetros son normales, significa que puede ser liberado, y puede obtenerlo en este momento. La marca de tiempo actual se utiliza como la marca de tiempo del semáforo de tarea lanzado esta vez (guardado en el elemento TS en el TCB).

Elementos en TCB relacionados con los semáforos de tareas :

{

CPU_TS SemPendTime; el tiempo de espera para que una tarea espere su propio semáforo de tarea.

CPU_TS SemPendTimeMax; el tiempo de espera más largo para que una tarea espere el semáforo de la tarea varias veces.

OS_SEM_CTR SemCtr; Valor de recuento del semáforo de la tarea.

CPU_TS TS; la marca de tiempo cuando se libera/libera el semáforo de la tarea.

CPU_INT08U SemID; ID único para depuradores y rastreadores de terceros.

}

OSTaskSemPend: función de adquisición de semáforo de tareas

{

Idea de función : Obtener el semáforo de la tarea es obtener el semáforo de la tarea en sí. Si el número de sus propios semáforos es mayor que 0 (disponibles), tendrá éxito; de lo contrario, es necesario juzgar si está bloqueado y si esperar el semáforo de la tarea.

4 parámetros de entrada : tiempo de espera; opciones; marca de tiempo devuelta (la marca de tiempo cuando se lanzó por última vez el semáforo de la tarea); tipo de error devuelto.

Retorno : valor de recuento del semáforo de la tarea

Proceso de función : ① Primero, verifique la seguridad, los parámetros, las opciones, etc., y no se permite que se llamen en interrupciones; las opciones incluyen OS_OPT_PEND_BLOCKING y OS_OPT_PEND_NON_BLOCKING. ② Si el valor de recuento de semáforos de la tarea (OSTCBCurPtr->SemCtr) es mayor que 0, indica que el semáforo de la tarea está disponible y se puede obtener. El número de semáforos de la tarea se reduce en 1; la marca de tiempo de la última versión del semáforo de la tarea (OSTCBCurPtr->TS), la diferencia con la marca de tiempo actual es el último tiempo de espera del semáforo de la tarea; y en comparación con OSTCBCurPtr->SemPendTimeMax, el valor de SemPendTimeMax se actualiza. ③ Si el semáforo de la tarea no está disponible, debe ingresar al bloqueo y esperar a que se libere el semáforo. Si el usuario selecciona OS_OPT_PEND_NON_BLOCKING y no espera el bloqueo, se devolverá el tipo de error que debe esperar el bloqueo y el valor de recuento del semáforo devuelto será 0. ④ Si el semáforo no está disponible, pero elige ingresar al bloqueo. Luego, primero determine si el programador está bloqueado. Debido a que el programador está bloqueado, la tarea no se puede programar y, naturalmente, el estado de la tarea no se puede cambiar . Si no hay un programador de bloqueo, llame a OS_CRITICAL_ENTER_CPU_EXIT () para bloquear el programador, porque el siguiente paso es realizar una operación de bloqueo en la tarea, y la operación es TCB, que es una variable global. Como recurso de sección crítica, necesita ser protegido . Llame a OS_Pend() para bloquear la tarea. Nota: El semáforo de tarea aquí no es un objeto del kernel, por lo que los parámetros de entrada de la función son (OS_PEND_DATA *)0 y (OS_PEND_OBJ *)0. Debido a que el semáforo de tareas no tiene una lista de espera, el bloqueo consiste simplemente en llamar a OS_TaskBlock() para eliminar la tarea de la lista lista e insertarla en la lista de base de tiempo.(Si el tiempo de espera no es 0). Luego llame a OSSched() para cambiar de tarea. ⑤ Llegar a este paso significa que el tiempo de espera finalizó, se canceló o una tarea liberó el semáforo de la tarea, el semáforo de la tarea está disponible y la tarea ha esperado hasta que se alcance el semáforo de la tarea. Muchas situaciones están relacionadas con el estado de la tarea, por lo que el cambio de caso se basa en el estado de la tarea. Si es OS_STATUS_PEND_OK, significa esperar el semáforo de la tarea normalmente. Realice el paso ② para actualizar los elementos relacionados con el tiempo SemPendTime y SemPendTimeMax en el TCB esperando el semáforo de la tarea. Si es OS_STATUS_PEND_ABORT, significa que se cancela la espera y se devuelve la marca de tiempo de la última vez que se lanzó el semáforo de la tarea y el tipo de error correspondiente. Si no se espera el semáforo OS_STATUS_PEND_TIMEOUT dentro del período de tiempo de espera, se devuelve la marca de tiempo de la última vez que se lanzó el semáforo de la tarea y el tipo de error correspondiente. ⑥ Finalmente, devuelve el valor de recuento actual del semáforo de la tarea.

}

OSTaskSemPost : función de liberación del semáforo de tareas .

{

Aunque una tarea solo puede esperar su propio semáforo, todas las demás tareas o interrupciones pueden liberar semáforos a la tarea.

Diferentes parámetros : el número de parámetros de entrada de la función de liberación del semáforo de la tarea es el mismo que el del semáforo del núcleo, que también es 3. Es solo que el semáforo de la tarea es para la tarea, por lo que el primer parámetro es el puntero TCB que apunta a la tarea de destino , y el semáforo del núcleo es un puntero al semáforo creado.

Retorno : Devuelve el número de semáforos de la tarea. Si se llama desde un ISR, será 0; si se desborda, también devolverá 0; además, si el parámetro es ilegal, también devolverá 0. Por lo tanto, si realiza una operación compleja al implementar una función y devuelve 0; o si la operación devuelve 0 incorrectamente, debe determinar en qué situación se encuentra mediante el tipo de error devuelto (p_err).

Proceso : excepto por algunas diferencias en los parámetros, los procesos son similares a los semáforos del núcleo. ① Primero obtenga la marca de tiempo actual como la marca de tiempo de la última publicación del semáforo de la tarea. Esta marca de tiempo se asignará al elemento TS en la tarea TCB utilizada para registrar la marca de tiempo de la publicación del semáforo de la tarea más adelante en p_tcb->TS = ts;. ( Debido a que el semáforo de la tarea es solo una marca de conteo, siempre que se llame a la función de liberación del semáforo de la tarea, el semáforo de la tarea inevitablemente se liberará cuando una serie de verificaciones de parámetros y seguridad sean normales, y el valor del conteo del semáforo de la tarea aumentará en 1 normalmente, o no habrá cambios, porque se desbordará agregar 1. Por lo tanto, después de verificar normalmente, el código debe obtener la marca de tiempo actual y usarla como la marca de tiempo de la última versión del semáforo de tareas) . ② Si la publicación retrasada de interrupción está habilitada y esta función se llama en una interrupción, llame a OS_IntQPost() para publicar el semáforo de la tarea en la cola de mensajes de interrupción. ③ Si envía una tarea, llame a la función OS_TaskSemPost().

--Llamar a OS_TaskSemPost() :

{

Proceso : Debido a que el semáforo de la tarea es una tarea específica, cada tarea solo define una variable de 32 bits para contar el semáforo de la tarea y no hay lista de espera en la estructura del semáforo del núcleo. La tarea está bloqueada y no entra en lista de espera. Cuando liberamos el semáforo de la tarea, determinamos si la tarea está esperando el semáforo de la tarea en función del estado de la tarea de destino señalada por el semáforo de la tarea . Una vez que se libera el semáforo de la tarea, el semáforo de la tarea está disponible y otras operaciones son similares: si la tarea está bloqueando, desbloquea la tarea y la tarea obtiene el semáforo. Si no hay ninguna tarea en espera, aumente el recuento de semáforos de la tarea en 1.

① Si el puntero del TCB de destino del parámetro está vacío, deje que el TCB de destino apunte al TCB actual y libere el semáforo de la tarea actual. ② Si el estado de la tarea no tiene un estado de espera (pendiente), significa que la tarea de destino no necesita obtener el semáforo de la tarea por el momento, o el semáforo de la tarea disponible es suficiente, la tarea de destino ya lo obtuvo. y no hay necesidad de esperar; no hay ninguna tarea esperando el semáforo de la tarea, luego pase sizeof(OS_SEM_CTR), determina si el semáforo de la tarea se desbordará. Si se desborda, se devolverá el tipo de error "OS_ERR_SEM_OVF" y la tarea El valor del recuento del semáforo será 0; de lo contrario, el valor del recuento del semáforo de la tarea aumentará en 1. ③ Si el estado de la tarea tiene un estado de espera y la tarea está esperando el semáforo de la tarea, llame a OS_Post() para enviar el semáforo de la tarea a la tarea en espera. Esta función insertará la tarea en la lista lista. Dado que el número de tareas en la lista lista ha cambiado, luego llame inmediatamente para determinar si opt selecciona OS_OPT_POST_NO_SCHED, determinando así si llamar a OSSched(). ④ Si la tarea está en estado de espera, pero no está esperando el semáforo de la tarea, continúe con el paso ②. ⑤ Finalmente, devuelve el valor de recuento del semáforo de la tarea actual.

}

}

Supongo que te gusta

Origin blog.csdn.net/m0_43443861/article/details/126373440
Recomendado
Clasificación