Comprender los códigos de función relacionados con el semáforo uCOS

OSSemCreate() : crea una función de semáforo.

{

Después de definir la variable de estructura del semáforo, llame a esta función para la inicialización, principalmente para asignar algunos valores a la estructura del semáforo.

Cuatro parámetros de entrada : puntero a la estructura del semáforo; nombre del semáforo; número de recursos o indicador de si ocurre un evento (valor binario); puntero de tipo de error devuelto.

Proceso de implementación de la función : ① Primero, realice la verificación de seguridad, interrumpa la verificación de llamadas ilegales y la verificación de parámetros La verificación de parámetros verifica si el semáforo existe y si está definido. ② Si la verificación pasa, asigne un valor al elemento de estructura. El tipo de marca es un objeto de semáforo; especifique el número de semáforos; la marca de tiempo se inicializa en 0; si el código de depuración y las variables están habilitados (habilitados de forma predeterminada), especifique el nombre del semáforo. ③ Llame a OS_PendListInit() para inicializar la lista de espera del semáforo. Como dijimos antes, generalmente la estructura se inicializará escribiendo una función separada, aquí, como la lista de espera de la cola de mensajes, se usa una estructura, pero la lista vinculada es diferente. En OS_PendListInit(), el puntero en la lista de espera se asigna a NULL y el número se borra a 0. ④ Llame a OS_SemDbgListAdd() para agregar el semáforo a la lista vinculada de depuración de semáforos. ⑤ Agregue 1 a la variable global OSSemQty que registra el número de semáforos y no devolverá ningún error.

}

OSSemDel() : función de eliminación de semáforo  

{

Idea de función : La función de eliminación del semáforo es la misma que la función de mensaje de la cola de mensajes. Debido a que hay tareas esperando el semáforo o la cola de mensajes, debe elegir según la opción si hay una tarea esperando para no hacerlo. eliminar y luego clasificar la operación: si elige no hacerlo Si la tarea elimina el semáforo (OS_OPT_DEL_NO_PEND) mientras la tarea está esperando el semáforo, se juzgará si hay una tarea en la lista de espera actual. se eliminará. Si lo hay, se devolverá un error que indica que hay una tarea en espera. Si elige eliminar la tarea independientemente de si está esperando el semáforo (OS_OPT_DEL_ALWAYS), si hay una tarea en la lista de espera, debe restaurar la tarea en la lista de espera al estado listo y luego eliminarla; si no , elimínelo directamente.

La eliminación no liberará espacio : la eliminación de tareas y la eliminación de colas de mensajes solo borra el bloque de control de tareas y los valores de los elementos de la estructura de la cola de mensajes. La eliminación del semáforo es lo mismo que la eliminación de la tarea y la eliminación de la cola de mensajes: solo borra el valor del elemento del semáforo y no libera el espacio de la pila .

Parámetros de entrada : puntero de semáforo; opciones; tipo de error de retorno.

Devuelve : Devuelve el número de tareas que esperan el semáforo antes de eliminarlo.

Proceso de implementación de la función : ① Primero, realice la verificación de seguridad, interrumpa la verificación de llamadas ilegales y verifique los parámetros. Además de verificar si el semáforo está vacío, la verificación de parámetros aquí también verifica si las opciones cumplen con las expectativas (principalmente por el bien de la experiencia del usuario, por temor a que el usuario escriba la opción incorrecta o seleccione la opción incorrecta). Eliminar no es como crear un semáforo: debe verificar si el tipo de semáforo es un tipo de semáforo para asegurarse de que el tipo de objeto del núcleo sea correcto. ② Ingrese a la sección crítica y obtenga la lista de espera del semáforo y el número de tareas en la lista de espera. ③De acuerdo con la opción, si el semáforo OS_OPT_DEL_NO_PEND solo se elimina cuando no hay ninguna tarea en espera, entonces determine si el número de tareas es 0, que es 0, y llame a OS_SemDbgListRemove() para eliminar el semáforo de la lista de depuración; reduzca el número de semáforos por 1; Llame a OS_SemClr() para borrar el contenido del semáforo. ③ Si es OS_OPT_DEL_ALWAYS, ingrese al ciclo while, llame a OS_PendObjDel() para eliminar las tareas de la lista de espera una por una y luego realice la operación con el número de tareas en ② siendo 0. ④ Devuelve el número de tareas que esperan el semáforo antes de eliminarlo.

Llame a OS_SemClr(): elimine la función OS_SemClr() llamada por la función de semáforo OSSemDel() para borrar el contenido del semáforo. Deje que el elemento puntero sea NULL, la variable solo sea 0, el tipo de objeto sea ninguno y luego llame a OS_PendListInit() para borrar la lista de espera Contenido.

}

OSSemPost() : función de liberación de semáforo

{

Si el semáforo se utiliza como semáforo binario, cuando creamos el semáforo, su rango de valor inicial es 0 ~ 1. Si el valor inicial es 1 semáforo disponible, dejará de ser válido si se obtiene una vez. Entonces debemos liberarlo. el semáforo.uCOS proporciona una función de liberación de semáforo . Cada vez que se llama a esta función, se libera un semáforo. Pero surge una pregunta: ¿se puede publicar todo el tiempo? Obviamente, si se usa como un semáforo binario, liberar el semáforo todo el tiempo no logrará el efecto de sincronización o exclusión mutua del acceso. Aunque el semáforo de uCOS puede liberarse todo el tiempo, el rango del semáforo aún necesita ser Ser determinado por el propio usuario. Tome una decisión basada en sus necesidades y asegúrese de que el semáforo esté dentro del rango de uso . Cuando se utiliza como semáforo binario, se debe garantizar que su valor disponible esté dentro del rango de 0 ~ 1; cuando se utiliza como semáforo de conteo, su rango lo determina el usuario en función de la situación real.

3 parámetros de entrada : puntero de semáforo; opciones; tipo de error de retorno

Retorno : valor de recuento de semáforos (es decir, el número actual de semáforos).

Proceso de función : ① Primero realice la verificación de seguridad, la verificación de parámetros y la verificación del tipo de objeto. La verificación de parámetros incluye verificar si se creó el semáforo y verificar las opciones.

Las opciones esperadas son: OS_OPT_POST_FIFO /* (Predeterminado) Enviar en modo FIFO*/

OS_OPT_POST_LIFO /*Usar el método LIFO para enviar volumen de mensajes*/ (las dos opciones anteriores no están marcadas)

OS_OPT_POST_1 /*Publicar el volumen de mensajes en la tarea de espera de mayor prioridad*/

OS_OPT_POST_ALL /*Volumen de mensajes de transmisión a todas las tareas en espera*/

OS_OPT_POST_NO_SCHED /*Enviar volumen de mensajes pero no programar tareas*/

② Llame a OS_TS_GET() para obtener la marca de tiempo actual como marca de tiempo para enviar el semáforo. ③ Si el semáforo se envía en una interrupción, llame a OS_IntQPost(); si se envía en una tarea, llame a la función OS_SemPost().

- Llamar a OS_SemPost() :

4 funciones de entrada : puntero de semáforo; opciones; marca de tiempo; tipo de error devuelto

Retorno : número de semáforos

Proceso de función : ① Desactive las interrupciones y cargue la lista de espera del semáforo, lo que significa asignar el puntero de la lista de espera del semáforo a una variable para una operación conveniente. ¿ Por qué necesitamos ingresar aquí a la sección crítica ? Debido a que las variables de estructura de semáforo definidas son globales, la creación de una función de semáforo solo inicializa los elementos internos y, al acceder a recursos públicos, las interrupciones deben desactivarse para evitar errores. ② Si no hay ninguna tarea esperando el semáforo, primero use la declaración de selección de múltiples ramas de switch-case para determinar si el semáforo liberado causará que el valor de conteo del semáforo se desborde, porque como se mencionó anteriormente, la función proporcionada por uCOS permite que el semáforo se liberará continuamente sin errores, por lo que aquí Para determinar si el valor del conteo se desborda, regrese. Este es el método proporcionado por uCOS: le permite seguir llamando a la función de semáforo de liberación. Juzgaré la función y la devolveré cuando se desborde. Aquí, el número máximo de semáforos se juzga por el número de bytes del tipo de semáforo (tamaño de) . Hay 8 bytes, 16 bytes y 32 bytes. El número de semáforos desbordados es: 2^8-1, 2^16-1, 2^32-1. Sin embargo, el límite superior para juzgar el desbordamiento del semáforo aquí es el número que el tipo de datos puede acomodar, no el valor máximo definido por el usuario . Por ejemplo, para 8 bytes, determina si ha llegado a 256, pero lo que el usuario realmente creó puede decir que el semáforo disponible actualmente es 6 y así sucesivamente. ③ Si no hay ninguna tarea esperando el semáforo y el semáforo no se desborda, aumente el número de semáforos en 1 y actualice la marca de tiempo del semáforo. Nota: El semáforo no es una cola de mensajes . Cuando no hay ninguna tarea esperando un mensaje, la cola de mensajes debe enviar el mensaje enviado por la tarea a la lista de mensajes. El semáforo es un número, solo un signo, y no transmitir cualquier otro mensaje de datos, como indicar un evento y ; el semáforo tiene un mecanismo de bloqueo. Cuando la tarea se bloquea mientras se espera el semáforo, la CPU no programará la tarea y tiene una mayor eficiencia ( esto es la diferencia entre el semáforo y la interrupción del cambio de bandera de variable global). ④ Si hay una tarea esperando el semáforo, el semáforo se entrega a la tarea en espera; si está en modo de transmisión, todas las tareas en la lista de espera obtendrán el semáforo y el número de semáforos permanece sin cambios; y la tarea es eliminado de la lista de espera (estado de bloqueo) eliminado. Debido a que necesita operar la lista de tareas y semáforos, el sistema no quiere que otras tareas interfieran, por lo que cierra el programador. Dependiendo de la opción, si desea publicar el semáforo en todas las tareas en espera, obtenga el número de tareas; de lo contrario, el número de tareas es 1. Luego realice un bucle basado en esta cantidad de tareas, llamando a OS_Post() para eliminar tareas de la lista de base de tiempo y de la lista de espera por turno, e insértelas en la lista lista. Lo que hay que tener en cuenta aquí es que llamar a OS_Post() en el semáforo solo restaura la tarea desde el estado bloqueado y no asigna el mensaje a la tarea como la cola de mensajes . Entonces, ¿cómo determinar si la tarea ha obtenido el semáforo ? Debido a que el semáforo es solo una bandera, la cantidad de semáforos no se asignará a la tarea. Cuando la tarea se recupera del estado de bloqueo, se considera que la tarea ha obtenido el semáforo . ⑤ Si la opción no selecciona "No programar tareas al publicar", se realizará la programación de tareas.

}

OSSemPend() : función de adquisición de semáforo

{

Mecanismo de adquisición de semáforo : Correspondiente a liberar un semáforo es adquirir un semáforo. Sabemos que una tarea puede adquirir un semáforo cuando el semáforo es válido. Cuando una tarea adquiere un determinado semáforo, el número de semáforos disponibles es Simplemente disminuya en uno. Cuando disminuye a 0, la tarea ya no se puede adquirir y la tarea adquirida entrará en el estado de bloqueo (lista de espera), esperando que una tarea libere el semáforo. uCOS admite múltiples tareas en el sistema para obtener el mismo semáforo. Si hay múltiples tareas esperando en el semáforo, estas tareas se organizarán en orden de prioridad. Si el semáforo elige liberarse a una sola tarea cuando se libera, Luego, la tarea con la mayor prioridad entre todas las tareas en espera obtiene el semáforo primero, y si el semáforo se libera a todas las tareas cuando se libera, todas las tareas en espera obtendrán el semáforo.

5 parámetros de entrada : puntero de semáforo; tiempo de espera; opciones; marca de tiempo de liberación, suspensión o eliminación del semáforo; tipo de error de devolución. ( Tenga en cuenta que la marca de tiempo aquí es la marca de tiempo cuando se libera el semáforo, no la marca de tiempo cuando espera o espera el semáforo. Y los usuarios pueden pasar el puntero nulo de la marca de tiempo, lo que significa que los usuarios no necesitan devolver la marca de tiempo )

Retorno : número de semáforos (número de recursos)

Proceso de función : ① Realizar verificación de seguridad, verificación de llamadas ilegales en interrupción, verificación de parámetros (si el semáforo está vacío, verificación de opciones) y verificación de tipo de objeto. Las opciones para la adquisición de semáforos incluyen OS_OPT_PEND_BLOCKING (bloqueo cuando no hay ningún objeto disponible), OS_OPT_PEND_NON_BLOCKING (sin bloqueo cuando no hay ningún objeto disponible). ② Para obtener el semáforo, primero determine si el recurso del semáforo está disponible, es decir, es mayor que 0. Si el semáforo está disponible, no es necesario que la tarea ingrese a la lista de espera, el número de recurso directo se reduce en 1 y no se produce ningún error y se devuelve el número de recurso actual del semáforo. ③ Si no hay recursos disponibles, la tarea debe insertarse en la lista de espera. Si la opción no es bloquear la tarea, el tipo de error de retorno es "Esperando bloqueo de sed" (puede optar por no esperar para juzgar el error devuelto para determinar si el semáforo se ha agotado) . ). ④ Si no hay recursos disponibles y se selecciona una tarea de bloqueo, primero determine si el programador está bloqueado. Si está bloqueado, el tipo de error se devolverá como "El programador está bloqueado". De lo contrario, llame a OS_Pend() para insertar la tarea. en la lista de espera y en la lista de base de tiempos (si hay un retraso). ⑤ Llame a OSSched () para realizar el cambio de tareas, porque la tarea está bloqueada en espera, lo que equivale a un bloqueo retrasado. Para utilizar eficientemente la CPU, se debe dar control a otras tareas durante el período de espera de mensajes. ⑥ Cuando el programa se ejecuta hasta este punto, la tarea debería haber obtenido el semáforo o haber agotado el tiempo de espera, y se clasificará y procesará de acuerdo con el estado actual de la tarea. Finalmente, obtenga el número actual de recursos del semáforo y devuélvalo.

}

}

Supongo que te gusta

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