Tenemos un sistema de hardware con algunos FPGA y un controlador USB FTDI. El hardware transmite datos a través de la transferencia masiva de USB a la PC a alrededor de 5MB/sy el software tiene la tarea de mantenerse sincronizado, verificar el CRC y escribir los datos en un archivo.Solucionando lagunas en los datos USB transmitidos
El chip FTDI tiene un pin 'ocupado' que sube mientras espera que la PC haga su trabajo. Hay una cantidad limitada de almacenamiento en búfer en el FTDI y en otras partes del hardware.
La línea ocupada va por un tiempo más largo de lo que el hardware puede almacenar (50-100ms) por lo que estamos perdiendo datos. Para evitar que tengamos que volver a diseñar el hardware, se me ha pedido que 'solucione' este problema.
Creo que mi código es lo suficientemente rápido, ya que hemos tenido que correr hasta 15 MB/s, por lo que deja un cuello de botella IO en alguna parte. ¿Estamos esperando demasiado de la PC/OS?
Aquí está mi punto de entrada de datos. Ocasionalmente obtenemos un bit o byte caído. Si la suma de comprobación no se computa, me desplazo hasta que lo haga. los datos de byte [] casi siempre son 4k.
void ftdi_OnData(byte[] data)
{
List<byte> buffer = new List<byte>(data.Length);
int index = 0;
while ((index + rawFile.Header.PacketLength + 1) < data.Length)
{
if (CheckSum.CRC16(data, index, rawFile.Header.PacketLength + 2)) // <- packet length + 2 for 16bit checksum
{
buffer.AddRange(data.SubArray<byte>(index, rawFile.Header.PacketLength));
index += rawFile.Header.PacketLength + 2; // <- skip the two checksums, we dont want to save them...
}
else
{
index++; // shift through
}
}
rawFile.AddData(buffer.ToArray(), 0, buffer.Count);
}
Supongo que una simple prueba sería encender el alcance, comentar la escritura en el archivo y darle una prueba! – Tim
@Tim, esta es la respuesta. La calificación más importante es el requisito de "hilo seguro". Creará un mutex que se comparte entre los dos hilos, bloqueado cada vez que se escribe/lee en la cola. El truco aquí es que en el hilo de escritura de archivos, debe bloquear, copiar un fragmento de datos en un búfer local y luego desbloquearlo. No bloquee más de lo necesario o sus dos hilos no tendrán ninguna ventaja sobre un hilo. –
En realidad yo uso NO mutx - use demasiado tiempo. Uso un Spinlock (nuevo con .net 4.0) porque mi código no tiene otra cosa que sacar algo de la cola o ponerlo;) En la parte superior, si creas nuevas memorias intermedias en cada elemento (como yo lo hago) realmente SOLO bloqueas en insertar/recuperar ... sin operación de copia. – TomTom