Red de conocimientos sobre prescripción popular - Conocimiento dental - ¿Cómo aumentar la velocidad en baudios del puerto serie a 921600 en el sistema operativo Linux en S3C2440?

¿Cómo aumentar la velocidad en baudios del puerto serie a 921600 en el sistema operativo Linux en S3C2440?

Permítanme hablar sobre lo que hice. En realidad, parece muy simple: aumentar la velocidad en baudios del puerto serie. En cuanto al entorno de hardware, uso el TE2440-II de Lingfei (más antiguo, no se queje). El sistema operativo es Linux 2.6.28. Como todos sabemos, en circunstancias normales, la velocidad en baudios del puerto serie en Linux es 115200. , porque somos bastante especiales.

Entonces, primero debemos estudiar el hardware para ver si puede cumplir con nuestros requisitos. En el capítulo de UART, el chip de control principal S3C2440 dijo que la velocidad en baudios puede alcanzar 115200 bajo el reloj del sistema, y ​​luego comentó que si el pclk alcanza los 60 M, puede llegar a 921600. Aumentaré la frecuencia principal como él dijo, y aumentaré el Pclk por cierto. Se descubrió que no se podía alcanzar 921600 en absoluto. Aunque la velocidad en baudios de 230400 es aceptable, la tasa de error de bits es muy alta y no resulta útil en absoluto. Luego intenté aumentar Pclk a 70M. De esta manera, la velocidad en baudios se puede aumentar a 230400 y la transmisión es estable, pero no se pueden lograr velocidades en baudios más altas y Pclk no se puede aumentar infinitamente porque nuestra placa de desarrollo todavía está conectada. En el caso de Pclk70M, la pantalla táctil se reiniciaba con frecuencia, lo que indicaba que esta solución no era factible, por lo que se aprobó. Permítanme hablar brevemente sobre cómo cambié los relojes del sistema FCLK, HCLK y PCLK. No entraré en detalles sobre la relación y los métodos de cálculo de estos tres relojes. Me referí principalmente a blog/view/13 b4c 686 b 9d 528 ea 80 c 77904 html. Encontré el archivo mach-smdk2440.c en Linux. Este archivo define la estructura clk utilizada por el puerto serie. Se inicia el sistema Linux. La estructura de configuración inicial del puerto serie. Pero cambié este lugar y le pedí que inicializara la configuración. fclk fue la primera opción como fuente de reloj del puerto serie, pero descubrí que no funciona, así que seguí buscándolo.

Esto deja solo una función a considerar, s3c24xx_serial_getclk(). Cuando ingrese a esta función, encontrará que esta función es una configuración completa del reloj en serie y la velocidad en baudios. Al ingresar a esta función, hay una estructura tmp_clksrc, que es muy crítica. Su contenido es el siguiente:

Estructura estática s 3c 24 xx _ UART _ clk src tmp _ clk src = {

. nombre = "pclk",

. Baudios mínimos

= 0,

. Baudios máximos

= 0,

. Divisor

= 1,

};

Como se puede ver en este nombre, establece la fuente de reloj del puerto serie en pclk, que también es el culpable. Pero cuando cambié el nombre a fclk, todo el sistema no pudo iniciarse, incluida la configuración de inicialización en mach-smdk2440.c mencionada anteriormente. Más tarde, tomé una decisión al configurar el puerto serie. Cuando la velocidad en baudios es inferior a 200.000, la configuración de la fuente del sistema permanece sin cambios. Cuando la velocidad en baudios es superior a 200000, no uso la estructura tmp_clksrc, sino que uso mi propia estructura definida. Por supuesto, cambié el nombre a fclk. Descubrí que aunque algunos parámetros se pueden cambiar usando solo la fuente del reloj, la fuente del reloj sigue siendo pclk, lo que significa que mis cambios no surtieron efecto en absoluto. Como esta llamada de Linux es demasiado complicada, la intentaré. No hay salida. Después de configurar el código del reloj serie, agregué las siguientes líneas de código para cambiar directamente los registros del S3C2440. Sé que no es ético y puede fácilmente causar caos en el sistema, pero lo probé y no esperaba que realmente funcionara.

Agregue el archivo samsung.c

if (baud & gt= 200000)

{

printk("baud >= 200000@Samsung.c\n");

__raw_writel(0x1fc5,s 3c 24 xx_VA_UART s 3c 2410_UCON);

__raw_writel( 0x0fc5, s 3c 24 xx _ VA _ UART 1+s 3c 2410 _ UCON);

__raw_writel(0x8fc5, s 3c 24 xx _ VA _ UART 2+s 3c 2410 _ UCON); 3c 24 xx_VA_UART s 3c 2410_UCON+0x 24); //Asegúrese de que la velocidad en baudios de la consola siga siendo 115200 para su visualización.

__raw_writel(3,s 3c 24 xx _ VA _ UART 1+s 3c 2410 _ UCON+0x 24); //921600

//__raw_writel(3, s 3c 24); xx _ VA _ UART 1+s 3c 2410 _ UCON+0x 24);

}

El código anterior se obtuvo a través de muchos experimentos, porque el sistema maestro que usé al principio El reloj fclk es 400M, por lo que se calcula que la división de frecuencia de URDIV1 debería ser 3, pero en este caso la tasa de error de bits es relativamente alta y aún no se puede transmitir. Así que finalmente entiendo por qué el manual dice que pclk puede alcanzar 921600 a 60M, porque si se calcula usando un reloj de 60M, la división de frecuencia UBRDIV1 es 3.069, que es la más cercana a un entero 3, por lo que se puede lograr una velocidad de transmisión en baudios de 921600 en esta tasa de error de bits Entonces configuré el reloj del sistema fclk en 420M, aquí MDIV=97, PDIV=1, PDIV = 65438Ucon1=0x0fc5, ucon2=0x8fc5, entonces n=1+6=7, entonces la fuente de reloj de la serie. El puerto es fclk/n=60M. Puede obtener la velocidad en baudios precisa 921600. Entonces, para lograr mi objetivo original, se podrían lograr otras velocidades en baudios, como 46088.

Hay otra pequeña idea aquí para aumentar la velocidad en baudios del puerto serie, también podemos usar USB a puerto serie, porque USB a puerto serie puede alcanzar 921600. El controlador de USB a puerto serie está integrado. Linux solo necesita simplemente llamar al nodo USB al puerto serie en la función abierta del puerto serie. Por supuesto, no he probado esta solución porque solo tenemos un puerto USB y también está ocupado. Espero que los amigos que lo necesiten puedan probarlo.