¿Puedo tener 1 núcleo de procesador solo para mi programa?

12

Tengo que cronometrar la diferencia horaria entre alta -> baja y baja -> borde de señal alta en los pines GPIO. He escrito un programa simple que hace esto. Después de ejecutarlo durante algún tiempo, estuve bastante contento con el resultado (variaciones de 0,01 s). Pero de vez en cuando había un error de 0,5 s. Estaba pensando que esto puede deberse a algún otro proceso del sistema en ejecución en ese momento. Entonces mi pregunta es:

¿Puedo reservar un núcleo de procesador solo para mi programa y dejar otros 3 núcleos para el sistema?

Estoy usando Raspbian Jessie Lite, así que creo que 3 núcleos serán suficientes para ejecutarlo.

Modelo no estándar
fuente
44
Supongo que está sondeando en un bucle el estado del pin GPIO. Esto es muy susceptible a cómo el sistema operativo decide ejecutar su programa, que pasará la mayor parte del tiempo manteniendo ocupada la CPU sin hacer nada realmente útil. Es posible que desee buscar una manera de configurar una interrupción en un pin GPIO dado, que puede usar para dejar que su programa se suspenda entre los bordes de la señal en los pines GPIO.
Florian Castellane
44
No estoy seguro de cuál es su proyecto, pero a veces un Microcontrolador se adapta mejor, especialmente cuando necesita un sistema más parecido al tiempo real. Arduino ofrece muchas opciones, y puedes escribir tu programa en C / C ++.
SnakeDoc
@Florian Hay una función en RPi.GPIO que es similar a la interrupción. Bloqueará el programa hasta que se detecte el borde (fuente: sourceforge.net/p/raspberry-gpio-python/wiki/Inputs ).
Modelo no estándar
@SnakeDoc Sé que el microcontrolador es mejor. Tenía la esperanza de evitarlo, porque no necesito precisión de microsegundos. 1/100 de segundo es más que suficiente. También necesito solo la diferencia de tiempo, por lo que si hay un retraso, esperaba que fuera lo mismo para iniciar y detener. Si esto no funciona, tengo que ir con el microcontrolador conectado a RPi para almacenar los datos.
Modelo no estándar
1
O obtenga un SO en tiempo real ejecutándose en el PI El problema con su configuración es que depende del "mejor esfuerzo" del sistema operativo. Dependiendo de qué más está sucediendo al mismo tiempo que su programa solicita acceso privilegiado a los GPIO, puede quedar en cola detrás de otras tareas que el sistema operativo está realizando en ese instante. Su programa de usuario tendrá una prioridad menor que las tareas del sistema. También hay derecho de prioridad, que los medios durante la ejecución de su programa puede ser "una pausa y 'dejar de lado' por el sistema operativo para otro proceso de ejecución, es decir, sus observaciones de temporización puede ser sesgada.
SnakeDoc

Respuestas:

13

Dedicar un núcleo es probablemente exagerado.

Te sugiero que pruebes mi biblioteca pigpio . De manera predeterminada, cronometrará los cambios de nivel de GPIO en 10 µs.

Como prueba rápida, le sugiero que mire este ejemplo de Python , que imprimirá cualquier transición de nivel GPIO y el tiempo en microsegundos desde la última transición en ese GPIO.

pigpio no está instalado por defecto en Jessie Lite. Instale la última versión del sitio vinculado o instale la versión anterior en los repositorios.

sudo apt-get install pigpio python-pigpio python3-pigpio

pigpio - Library for Raspberry Pi GPIO control
python-pigpio - Python module which talks to the pigpio daemon (Python 2)
python3-pigpio - Python module which talks to the pigpio daemon (Python 3)
joan
fuente
Probaré tu biblioteca pigpio. En este momento tengo que terminar otro proyecto, pero volveré sobre esto. Informaré en unas semanas. ¡Gracias!
Modelo no estándar
4

Puede bloquear su programa a un núcleo utilizando schedutilscomo se describe en este artículo de Cyberciti :

sudo apt-get install schedutils
sudo taskset -c 3 -p 13545  # Lock PID 13545 to core 3

Sin embargo, todavía se pueden programar otros procesos en el mismo núcleo. Entonces, lo segundo que debe hacer es asegurarse de que su comando se ejecute con la prioridad más alta usando el comando nice (esto le dirá al kernel de Linux que otros procesos deben ser eliminados si es necesario). Comience su programa de esta manera:

nice -n -20 your-program

Hay otras razones posibles para sus problemas de tiempo. No es tan fácil hacer nada al respecto:

  • Si está programando en Python, hay un recolector de basura que a veces detiene su programa para liberar memoria no utilizada.
  • Las interrupciones hacen que la CPU maneje algo más de lo que desea. Por ejemplo, paquetes de red u otra entrada / salida.
  • Si su programa está durmiendo mucho, puede haber otros procesos que llenen los cachés de la CPU (caché L1 / L2). Esto te obliga a esperar el acceso a RAM.
    • Peor aún si su RAM está llena para que su proceso se cambie al disco porque las tarjetas SD son muy bajas.

Hay formas de hacer que su proceso sea en tiempo real , lo que significa que se ejecutará con ciertas garantías de tiempo. El problema con esto es que todo lo demás podría ser más lento y es un tema complejo. Si quieres pasar por este agujero del conejo, te sugiero que comiences a leer sobre procesos en tiempo real en Linux .

Emil Vikström
fuente
2
En lugar de ser agradable, sería mejor darle prioridad al proceso en tiempo real, lo que garantizaría que se ejecute con preferencia a los procesos en tiempo no real.
juan
Buen punto, agregaré una nota al respecto.
Emil Vikström
1
"gc.disable ()" ¿qué sucede si deshabilita el recolector de basura?
Keine
@Keine Puede obtener una pérdida de memoria. Digamos que tiene un objeto A que tiene una variable que apunta a B. Python rastreará esta referencia como un número, sabe que B tiene 1 objeto apuntando hacia él. Elimine A cuando ya no lo necesite. El recuento de referencia para B disminuirá, y si llega a 0, Python también puede liberar a B. Esto se llama recuento de referencias. Pero ahora decir que B tiene una referencia de regreso a A. Ahora usted tiene un grupo de objetos que señalan el uno al otro. Ninguno de ellos llegará a 0 y será liberado. GC puede encontrar dichos grupos y eliminarlos cuando el programa principal no apunta "hacia" el grupo.
Emil Vikström
1
Agregaré las sugerencias que hizo a mi proyecto. Pero espero evitar temas demasiado complejos. En ese caso, supongo que es mejor hacer una detección de interrupción de microcontrolador y conectarla a RPi solo para guardar datos. ¡Gracias!
Modelo no estándar
2

Dado que tiene requisitos de tiempo, Raspberry Pi ya no es la plataforma adecuada para esto. No es una plataforma en tiempo real y muchas fuentes diferentes de interferencia pueden desviar el tiempo.

En su lugar, debe usar un microcontrolador para medir este tiempo, preferiblemente usando interrupciones, y pasar la información al Pi más tarde.

Maxthon Chan
fuente
1
Sin embargo, ¿no es posible obtener interrupciones en los pines GPIO en una Raspberry Pi?
Florian Castellane
Seguramente esto depende de si hay alguna otra parte de los requisitos de diseño que haga que una máquina Linux sea más apropiada que una MCU. RPi puede manejar bien esta tarea, al igual que una MCU con frecuencia de 10 MHz.
Sean Houlihane
1

Según su requisito, no creo que necesite usar un procesador de núcleo único. Lo que necesita es asegurarse de que su programa se ejecute todo el tiempo. Para lograr eso, puede establecer la prioridad de su programa muy alta, para que no se vea afectado por ningún otro proceso.

Hasta donde yo sé, el SO (SO de uso general) que utilizamos no está diseñado para ser utilizado en sistemas en tiempo real, por lo que si desea ejecutar su proceso en tiempo real para que ningún otro proceso lo perturbe, debe ir para un sistema operativo en tiempo real (RTOS). Tal vez se les ocurra una selección central. :)

Vishwajeet Vishu
fuente
1
¿Hay buenos RTOS gratuitos por ahí?
Keine
RTLinux y Vxworks son ejemplos de RTOS y también son buenos. Pero debe estudiar sobre el sistema operativo (cuál fue el enfoque para su creación) antes de la instalación, para que pueda satisfacer sus necesidades.
Vishwajeet Vishu