Hay una funcion llamada RingBuffer_Pop la cual saca 1 dato del RB, pero lo que hace es realmente sacarlo, yo solo quiero leerlo:Pero ademas lo que lo saca lo hace desde el tail
Y no posee una funciona esa libreria de buffer circular para tomar el ultimo valor?
Y no es mejor leer siempre lo que llega ?
o Pensas revisar cada tanto para ver si no llega mas nada y ahi verificar si esta el ultimo char indicando el final?
Y si llegan mas cosas y ese char que te indica el fin queda en el medio ?
Supongamos que la hiciste vos, y yo creo que estas intentado buscar una funcion que lea lo ultimo ingresado. Estoy intentando comprender como hacer, por que es bastante simple si es que es un pointer a uint8_t
El ultimo valor esta dado por (head-1), por que se pre-incrementa al ingresar el dato apuntando a la direccion siguiente. Para un ptr de 8 bits se me ocurre que deberia ser asi:Código: C
static uint8_t RingBuffer_ReadByte( const RINGBUFF_T *RingBuff) { uint8_t ui8Temp; // Revisar que exista el buffer (no NULL), revisar que NO este vacio aca. Y recien ahi proceder ui8Temp = Ringbuff->data[(Ringbuff->head)-1]; return ui8Temp; }
El tema es que es un void. Y habria que castearlo a un uint8_t.Código: C
static uint8_t RingBuffer_ReadByte( const RINGBUFF_T *RingBuff) { uint8_t ui8Temp; // Revisar que exista el buffer (no NULL), revisar que NO este vacio aca. ui8Temp = ((uint8_t *)Ringbuff->data)[(Ringbuff->head)-1]; return ui8Temp; }
Realmente no se si estoy haciendo algo malo o bueno pero es lo unico que se me ocurre en estos momentos. Y como que se vuelve un poquito jodido probarlo.
EDIT:
Cambie el codigo. Espero que funcione. El acceso a la estructura a traves de un pointer tiene la mas alta prioridad, luego como los [] tiene mayor orden de precedencia que el cast, debo ponerle otros parentesis ya que () y [] son asociativos de izquierda a derecha, primero se ejecuta el (). Y esa es la explicacion de como se llego a eso :P
Y una cosa mas..
no entiendo como en tu
RingBuffer_Insert()
No wrapeas el indice ( head ), ya que lo unico que haces es incrementarlo. Pero no veo en ningun lado que se fije si llego al maximo y que lo lleve a 0 para comenzar por el otro lado. Como realmente un Ring Buffer haria. Si jamas lo vas a llenar y siempre terminas vaciandolo y borrando todo ( poniendo head/tail a 0 ) entonces no hace falta el codigo del wrap que puse. ni la comprobacion esa. Pero dejaria de ser un Ring Buffer como tal, y un buffer mas :P
No es mío, es de NXP :P
Por lo que vi van incrementando el head y el tail siempre y la cantidad de datos actuales sale como la diferencia * size. He leido que es una forma más de trabajar con los RB:
http://www.simplyembedded.org/tutorials/interrupt-free-ring-buffer/
Código: C
ui8Temp = ((uint8_t *)Ringbuff->data)[((Ringbuff->head)-1) & (RingBuff->count - 1)];
De esa forma se resta 1 al head indicando la posicion anterior, y luego se hace la AND con el count-1. Asi formatearlo a lo que seria el indice.
no sé x q al compilador dejó de gustarle el -> y quiere . y no tengo tiepo de investigarlo
Le desconfío al encoding del FatFS... Voy a investigar un poco...
Citarno sé x q al compilador dejó de gustarle el -> y quiere . y no tengo tiepo de investigarlo
Si te referis a esto:
key = ((uint8_t *)rxring.data)[lastpos];
es obvio el por que. ya que normalmente en las funciones que estuvimos haciendo arriba era un puntero a la estructura: RINGBUFF_T *RingBuff
Mientras que aca estas accediendo a la estructura. Y un elemento de la misma es data, Para poner un ejemplo:
RINGBUFF_T *RingBuff = &rxring;
key = ((uint8_t *)RingBuff->data)[lastpos];
CitarLe desconfío al encoding del FatFS... Voy a investigar un poco...
Es raro por que no se preocupa por eso. Por que se complicaria la vida con eso? Directamente manda todos los bytes en fila... Lo unico que deberia preocuparse es por el '\0' en una string.
Y una ultima cosa que me esta carcomiendo la cabeza.
Imagino que esto es todo sin optimizaciones activas, ya que veo que no hay ningun "volatile" dando vueltas, especialmente en el buffer de lectura/escritura
Si, no he habilitado las optimizaciones y no he verificado los VOLATILES. Ahora que está funcionando voy a ir retocando esas cosas.
Las optimizaciones nunca las uso... será cuestion de empezar a usarlas... o no...
Excelente, ahí obtuve el último caracter con ese código!
En mis pruebas le estaba errando en el casteo a uint8_t *. yo ponía (uint8_t *)(Ringbuff->data)[....].... no termino de entender como funcionan los paréntesis en cada caso...
Cambie el codigo. Espero que funcione. El acceso a la estructura a traves de un pointer tiene la mas alta prioridad ( -> ), luego como los [] tiene mayor orden de precedencia que el cast, debo ponerle otros parentesis ya que () y [] son asociativos de izquierda a derecha, primero se ejecuta el (). Y esa es la explicacion de como se llego a eso :P
Y una ultima cosa que me esta carcomiendo la cabeza.
Imagino que esto es todo sin optimizaciones activas, ya que veo que no hay ningun "volatile" dando vueltas, especialmente en el buffer de lectura/escritura
P.D. En mis implementaciones de ring buffers, siempre usé ese método de calcular el tamaño por diferencia entre las posiciones iniciales y finales de la cola, pero tiene un problema si no se agregan controles adicionales: cuando el buffer se llena, la posición final iguala a la inicial y por ende podemos creer que el buffer está vacío cuando en realidad está lleno...
Mi duda es que cosa puede hacer el compilador (con la optimizacion habilitada) que tenga un mal funcionamiento?
Por que estoy pasando siempre a las funciones del RB la direccion del RingBuffer, dicha direccion no cambia nunca, entonces no veo que el compilador pueda hacer macana. No sé como funciona el almacenaje de los miembros de la estructura... Quizá si el compilador almacena en un registro el miembro "count" que no es volatile y en algúna parte peligrosa del codigo yo cambiara ese miembro puede ser que haya problemas. Pero el unico miembro que cambia es "data" que al ser un puntero no volatile, no sé que pueda pasar....
- deshabilitar interrupcion/es;
- modificar variable compartida;
- rehabilitar interrupcion/es;
alcanza para garantizar la no corrupción de la variable?
RB_INDH(RingBuff)RB_INDT(RingBuff)Tengo pendiente responderte KILLER, perdoná. No creas que es un examen! Yo planteo las preguntas para todos! No tengo necesariamente las respuestas! Es un tema de debate, no de profesor/alumno!
y qué pasa con el miembro count de la struct del RB? acaso no lo modificás desde fuera y dentro de la interr si modificás el tail y el head?
Podrias pasar que hace estas funciones:Código: [Seleccionar]RB_INDH(RingBuff)Código: [Seleccionar]RB_INDT(RingBuff)Y como decis. Si usas uno y otro no deberia haber ningun problema. A no ser que uses tambien alguna otra como la de un flush del buffer.
Si querés mudo esto a otro hilo para no ensuciarle más este a Leo.
Pasa que movw carga sólo los 16 bits de la parte baja, y movt sólo los 16 bits de la parte baja de r1. Por ende el valor final del registro r1 sería: 0x20000214
20000214 g O .data 00000001 .hidden activarBomba
Todavía te debo mis comentarios sobre las formas de lograr o no generar código seguro.