0% encontró este documento útil (0 votos)
35 vistas27 páginas

Dispatch

El documento contiene código fuente en C que define funciones para manejar interrupciones y tareas en un sistema basado en RISC-V. Incluye la instalación y desinstalación de manejadores de interrupciones, así como la ejecución de tareas cíclicas con temporización. Además, se implementan funciones para habilitar y deshabilitar interrupciones, así como para gestionar el tiempo de ejecución de las tareas.

Cargado por

00darkstriker00
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
35 vistas27 páginas

Dispatch

El documento contiene código fuente en C que define funciones para manejar interrupciones y tareas en un sistema basado en RISC-V. Incluye la instalación y desinstalación de manejadores de interrupciones, así como la ejecución de tareas cíclicas con temporización. Además, se implementan funciones para habilitar y deshabilitar interrupciones, así como para gestionar el tiempo de ejecución de las tareas.

Cargado por

00darkstriker00
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

10/1/25, 11:32 dispatch.

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P3A\dispatch.h

1 #ifndef DISPATCH_H
2 #define DISPATCH_H
3
4 #define RISCV_MACHINE_CALL_M­
_MODE (11)
5
6 void syscall_dispatch(uint32_t code, uint32_t param);
7 void excepcion_dispatch(uint32_t code);
8 void irq_dispatch(uint32_t code);
9
10 void install_irq_handler( uint32_t irq_num, void (*f)(void) );
11 /*Esta función se utiliza para instalar/registrar un ISR (manejador de instrucciones) para un
número específico de instruccion IRQ
12 * irq_num: numero q identifica la IRQ q se quiere manejar(cada dispositivo/evento q puede
generar una interrupcion tiene un número asociado)
13 * void (*f): Puntero a una función q no recibe parámetros ni devuelve valores. Esto
significa q puedes pasar cualquier funcion q siga esta firma como argumento a install handler
14 * CUando se active la interrupcion correspondiete, el sistema llamará a f*/
15
16 void uninstall_irq_handle­
r( uint32_t irq_num );
17 /*función q se utiliza para eliminar un ISR (manejador de instrucciones) previamente
instalado para un número específico de IQR. Si no quieres usar mas esa interrupcion, puedes
18 * puedes usar esta funcion para desregistrar el ISR asociado a la IRQ*/
19
20 void install_local_timer_­
handler( void (*f)(void) );
21 void uninstall_local_time­
r_handler();
22 void local_timer_set_gap( uint64_t gap );
23
24 void raise_SW_interrupt( uint32_t hart );
25
26 // SET STATUS REG MIE BIT (Global IRQ enable)
27 void enable_irq(void);
28 /*AL habilitar la función, el procesador será capaz de responder a cualquier
interrupción(interna o externa) q esté permitida en el sitema*/
29
30 // CLEAR STATUS REG MIE BIT (Global IRQ disable)
31 void disable_irq(void);
32 /*SI activamos esto el procesador NO ATENDERÁ NINGUNA INSTRUCCIÓN*/
33 // SET MIE REG EXT_IRQ BIT (EXT IRQ enable)
34 void enable_ext_irq(void);
35 /*Permite q el procesador responda a las interrupciones q provienen de dispositivos
externos(teclado). Internamente, la funcion ajusta el bit correspondiente en el registro
36 * MIE q controla las interrupciones externas. Al poner este bit a 1 el procesador queda
habilitado para atender cualquier instruccion externa. Al ejecutar esta instruccion
37 * cualquier interrupcion externa no enmascarada será atendida por el procesador cunado
ocurra*/
38
39 // CLEAR MIE REG EXT_IRQ BIT (EXT IRQ disable)
40 void disable_ext_irq(void);
41 /*Pone el bit q controla las interrupciones externas a 0, de esta forma, el procesador
ignorará todas las interrupciones externas hasta q se vuelva a habilitar*/
42 // SET MIE REG TIMER BIT (Timer irq enable)
43 void enable_timer_clinc_i­
rq(void);

localhost:57236/1bbfe3f3-7687-43cf-84e3-372d9cb8a01d/ 1/2
10/1/25, 11:32 dispatch.h

44
45 // CLEAR MIE REG TIMER BIT (Timer irq disable)
46 void disable_timer_clinc_­
irq(void);
47
48 // SET MIE REG SW BIT
49 void enable_SW_IRQ(void);
50
51 // CLEAR MIE REG SW BIT
52 void disable_SW_IRQ(void);
53
54 // MASK PLIC external IRQ
55 void plic_irq_mask(uint32_t source);
56 /* Se utiliza para enmascarar/ignorar interrupciones. Source es el número de la IQR q
queremos ignorar*/
57
58 // UNMASK PLIC external IRQ
59 void plic_irq_unmask(uint32_t source);
60 /*Desenmascara una instruccion previamente enmascarada y el procesador podrá manejarla*/
61
62 // syscall (Executive call)
63 void syscall(uint32_t N, uint32_t param );
64
65 #endif /* DISPATCH_H */
66

localhost:57236/1bbfe3f3-7687-43cf-84e3-372d9cb8a01d/ 2/2
10/1/25, 11:30 main.c

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P3B\main.c

1 // Modificado el ciclo cíclico y la ejecución de las tareas


2
3 #include "riscv_types.h"
4 #include "riscv_uart.h"
5 #include "clinc.h"
6 #include "dispatch.h"
7 #include "log.h"
8 #include "riscv_monotonic_cloc­
k.h"
9
10 #define NULL (0)
11
12 void emu_execution_time(uint32_t mseconds) {
13 // Convertir milisegundos a ticks
14 uint64_t = (uint64_t)mseconds * (CLINT_CLOCK / 1000); //Convertir mseg a ticks
15 uint64_t start_ticks = get_ticks_from_reset­
(); //Obtener ticks actuales
16 wait_until(start_ticks + ticks); //Esperar el tiempo calculado
17 }
18
19 // Tareas según la tabla dada
20 void TAvoidObstacle(void) {
21 printf(" Start Avoid Obstacles\n");
22 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
23 emu_execution_time(2000);
24 printf(" End Avoid Obstacles\n");
25 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
26 }
27
28 void TPathTracking(void) {
29 printf(" Start Path Tracking\n");
30 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
31 emu_execution_time(3000);
32 printf(" End Path Tracking\n");
33 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
34 }
35
36 void TSensorFusion(void) {
37 printf(" Start Sensor Fusion\n");
38 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
39 emu_execution_time(5000);
40 printf(" End Sensor Fusion\n");
41 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
42 }
43
44 void TCalculatePath(void) {
45 printf(" Start Calculate Path\n");
46 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
47 emu_execution_time(6000);
48 printf(" End Calculate Path\n");
49 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
50 }
51 // Configuración de la secuencia de tareas cíclicas

localhost:57236/90478b45-5b77-4995-ae05-c9331345804e/ 1/4
10/1/25, 11:30 main.c

52 #define CYCLIC_EXECUTIVE_PER­
IOD_IN_SECONDS 10 //Segun la imagen de la ultima parte de la
practica
53
54 #define CYCLIC_EXECUTIVE_PER­
IOD_IN_TICKS (CYCLIC_EXECUTIVE_PER­
IOD_IN_SECONDS * CLINT_CLOCK)
55
56 #define CYCLIC_EXECUTIVE_HYP­
ER_PERIOD 3
57 #define CYCLIC_EXECUTIVE_TAS­
KS_NUMBER 4
58
59 void (*cyclic_executive[CYCLIC_EXECUTIVE_HYP­
ER_PERIOD]
60 [CYCLIC_EXECUTIVE_TAS­KS_NUMBER+1])(void) = {
61 {TAvoidObstacle, TPathTracking, TSensorFusion, NULL, NULL}, //Periodo 0
62 {TAvoidObstacle, TCalculatePath, NULL, NULL, NULL}, //Periodo 1
63 {TAvoidObstacle, TPathTracking, NULL, NULL, NULL}, //Periodo 2
64 };
65
66 int main() {
67 // Inicialización de variables
68 uint8_t current_period = 0;
69 int task_index = 0;
70 uint64_t next_period_in_ticks­
_from_reset;
71 // Inicialización de la hora de inicio
72 InitMonotonicClock(date_time_to_Y2K(12, 10, 23, 12, 40, 0)); // 12/10/2023 12:40
73 // Obtener la referencia de tiempo absoluta desde el reinicio
74 next_period_in_ticks­
_from_reset = get_ticks_from_reset­
();
75
76 while (1) {
77 task_index = 0; // Se reinicia al comienzo de cada periodo básico
78
79 printf("\nStart period: %d\n", current_period);
80 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
81
82 // Ejecutar las tareas de este periodo
83 while (cyclic_executive[current_period][task_index] != NULL) {
84 cyclic_executive[current_period][task_index](); // Ejecutar tarea
85 task_index++;
86 }
87
88 // Sincronización con el inicio del siguiente periodo
89 next_period_in_ticks­
_from_reset += CYCLIC_EXECUTIVE_PER­
IOD_IN_TICKS;
90 wait_until(next_period_in_ticks­
_from_reset);
91
92 // Avanzar al siguiente periodo
93 current_period++;
94 if (current_period == CYCLIC_EXECUTIVE_HYP­
ER_PERIOD) {
95 current_period = 0;
96 printf("\n****************\n");
97 printf("Next hyperperiod\n");
98 printf("\n****************\n");
99 }
100
101 }
102
103 return 0;
104 }

localhost:57236/90478b45-5b77-4995-ae05-c9331345804e/ 2/4
10/1/25, 11:30 main.c

105
106
107
108
109
110
111 /////////////////////////////////////////OTRO
EJEMPLO/////////////////////////////////////////
112
113 void emu_execution_time( uint32_t mseconds )
114 {
115
116 // Convertir milisegundos a ticks
117 uint64_t = (uint64_t)mseconds * (CLINT_CLOCK / 1000); //Convertir mseg a ticks
118 uint64_t start_ticks = get_ticks_from_reset­
(); //Obtener ticks actuales
119 wait_until(start_ticks + ticks); //Esperar el tiempo calculado
120 }
121
122 // Task code T1
123 void Task1(void)
124 {
125 printf(" Start T1\n");
126 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
127 emu_execution_time(1000); //execution time 1000 ms
128 printf(" End T1\n");
129 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
130 }
131
132 // Task code T2
133 void Task2(void)
134 {
135 printf(" Start T2\n");
136 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
137 emu_execution_time(300); //execution time 300 ms
138 printf(" End T2\n");
139 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
140 }
141
142 // Task code T3
143 void Task3(void)
144 {
145 printf(" Start T3\n");
146 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
147 emu_execution_time(500); //execution time 500 ms
148 printf(" End T3\n");
149 print_date_time_from­
_Y2K(GetUniversalTime_Y2K­
());
150 }
151
152 // Definition of the configuration macros
153 // CLINT_CLOCK is 10000000
154 #define CYClIC_EXECUTIVE_PER­
IOD_IN_SECONDS 2
155 #define CYClIC_EXECUTIVE_PER­
IOD_IN_TICKS (CYClIC_EXECUTIVE_PER­
IOD_IN_SECONDS\
156 * CLINT_CLOCK)
157

localhost:57236/90478b45-5b77-4995-ae05-c9331345804e/ 3/4
10/1/25, 11:30 main.c

158 #define CYClIC_EXECUTIVE_HYP­


ER_PERIOD 6
159 #define CYClIC_EXECUTIVE_TAS­
KS_NUMBER 3
160
161 // Two-dimensional function pointer array to define
162 // the sequence of tasks of the cyclic executive
163 void (*cyclic_executive [CYClIC_EXECUTIVE_HYP­
ER_PERIOD]
164 [CYClIC_EXECUTIVE_TAS­
KS_NUMBER+1])(void) = {
165 {Task1,Task2,Task3,NULL},
166 {Task1,NULL,NULL,NULL},
167 {Task2,Task1,Task3,NULL},
168 {Task1,Task2,NULL,NULL},
169 {Task1,Task3,NULL,NULL},
170 {Task2,Task1,NULL,NULL}
171 };
172
173

localhost:57236/90478b45-5b77-4995-ae05-c9331345804e/ 4/4
10/1/25, 11:35 mainn.c

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P3A\mainn.c

1 #include "log.h"
2 #include "riscv_types.h"
3 #include "factorial.h"
4 #include "riscv_uart.h"
5 #include "serialize.h"
6 #include "ccds_pus_format.h"
7 #include "ccds_pus_stdio.h"
8 #include "dispatch.h"
9 #include "riscv_monotonic_cloc­
k.h"
10 #include "clinc.h"
11 #define TICKS_1SG 10000000
12 /*ESte programa tiene como objetivo demostrar el manejo de syscalls(interfaz para q el
usuario pueda solicitar servicios como acceso a archivos, manejo de procesos...) y
13 * excepciones (interrupciones q desvianel flujo normal de un programa, provocados por
errores o por ciertas instrucciones q el hardware debe manejar de manera especial)
14 * en un entorno de ejecucion de bajo nivel. El código esta diseñado para provocar llamadas
al sistema (syscalls) como excepciones que desencadenan situaciones de error,
15 * permitiendo observar cómo el sistema reacciona a ellas*/
16
17
18 //int main()
19 //{
20 // //ZONA SYSCALLS:
21 // printf("----------SyscallS--------------\n");
22 //
23 // printf("syscall 22\n");
24 // syscall(22, 1); //Llamada al sistema
25 //
26 // printf("syscall 15\n");
27 // syscall(15, 2);
28 //
29 // printf("----------EXCEPTIONS---------\n");
30 //
31 // printf("Write NULL pointer\n");
32 // uint32_t *p = 0; //Puntero que apunta a la direccion 0 (direccion donde tendria q
haber un entero de 32 bits)
33 // *p = 234; //Intenta escribir en la direccion 0, 234 dando lugar a una excepción
ya que la mayoria de los sistemas no permiten acceder a la dir. 0
34 //
35 // printf("READ NULL pointer\n");
36 // uint32_t x = *p; //Intentamos leer algo (almacenandolo en x) que está en una dirección
de memoria q no es válida
37 //
38 // printf("UNALIGNED WRITE\n");
39 // p = (uint32_t *)123; //Ahora asigna al puntero p una direccion no alineada (dato
alineado: aquel que se almacena en una direccion que es múltiplo de su tamaño de bytes)
40 // *p = 334; // Attempt to write an uint32_t value to an odd address
41 //
42 // printf("UNALIGNED READ\n");
43 // x = *p; // Attempt to read an uint32_t value from an odd address
44 //

localhost:57236/2f315283-fbaa-4833-ab82-f31cd919df30/ 1/5
10/1/25, 11:35 mainn.c

45 //// Excepción 4: Unaligned Load (Lectura no alineada) — Se genera cuando se intenta leer
un valor desde una dirección no alineada.
46 //// Excepción 5: Load Access Fault (Fallo de acceso de lectura) — Se genera al intentar
leer desde una dirección de memoria inválida o protegida.
47 //// Excepción 6: Unaligned Store (Escritura no alineada) — Se genera cuando se intenta
escribir un valor en una dirección no alineada.
48 //// Excepción 7: Store Access Fault (Fallo de acceso de escritura) — Se genera al
intentar escribir en una dirección de memoria inválida o protegida
49 //
50 // return 0;
51 //
52 //}
53
54
55 //#define ESC 27
56 //
57 //char car;
58 //volatile uint32_t flag = 0;
59 //uint32_t end = 0;
60 //
61 //
62 //// UART ISR handler
63 //// It is going to be called each time a new car is received
64 //void uart_rx_irq_handler (void) //Declaramos la funcion q vamos a llamar. Cada vez que
introduzcamos un caracter, esta funcion será llamada
65 //{
66 // car = (char)riscv_getchar();//GUardo en car el caracter q voy a recibir
67 // flag = 1;
68 //}
69 //
70 //int main()
71 //{
72 //
73 // // TX/RX enable
74 // riscv_uart_enable_TX­
();
75 // riscv_uart_enable_RX­
();
76 //
77 // // Install uart handler
78 // install_irq_handler( UART_IRQ, uart_rx_irq_handler );
79 //
80 // riscv_uart_enable_RI­
(); // Enable RX irq
81 // plic_irq_unmask( UART_IRQ ); // Digo al procesador q puede manejar esa instruccion
82 // enable_ext_irq(); // Habilito interrupciones externas
83 // enable_irq(); // Global interrupt enable
84 //
85 // riscv_print_string("Programación de Dispositivos e Interfaces\n"); //Imprimo una cadena
de caracteres
86 //
87 // while( !end ) //COntinua funcionando hasta q end se pone en 1
88 // {
89 // if ( flag )
90 // {
91 // printf("%d: ", car);
92 // if ( car == ESC ) // ESC

localhost:57236/2f315283-fbaa-4833-ab82-f31cd919df30/ 2/5
10/1/25, 11:35 mainn.c

93 // {
94 // end = 1;
95 // }
96 // else
97 // {
98 // printf("%c\n", car);
99 // riscv_putchar(car);
100 // flag = 0;
101 // }
102 // }
103 // // else do nothing
104 // }
105 //
106 // printf("Program end\n");
107 // return 0;
108 //}
109
110 int32_t rec;
111 uint8_t tc_header[16];
112 uint32_t idx=0;
113 uint8_t dato;
114 uint8_t flag=0;
115 char * pchar="El telecomando se ha procesado correctamente\n"; //Defino un puntero con el
que luego imprimiré la cadena de caracteres
116
117 void uart_rx_irq_handler(void){
118
119 rec = riscv_getchar();
120 dato=(uint8_t)rec;
121 if(idx==0){
122 if(dato==0x1B){
123 tc_header[idx]=dato;
124 idx++;
125 }
126 }else{
127 if(idx<6){
128 tc_header[idx]=dato;
129 idx++;}
130 if(idx==6){
131 flag=1;
132 }
133 }
134
135 }
136
137 uint32_t ticks = 0;
138 uint32_t contador1 = 0;
139 uint32_t contador5 = 0;
140 uint8_t flag_1seg = 0;
141 uint8_t flag_5seg = 0;
142
143 void timer_handler(void)
144 {
145 contador1 ++;

localhost:57236/2f315283-fbaa-4833-ab82-f31cd919df30/ 3/5
10/1/25, 11:35 mainn.c

146 contador5 ++;


147 if(contador1 >= 10)
148 {
149 flag_1seg = 1;
150 contador1 = 0;
151 }
152
153 if(contador5 >= 50)
154 {
155 flag_5seg = 1;
156 contador5 = 0;
157 }
158 }
159 /*
160 int main()
161 {
162 printf("----------TIMER IRQ---------\n");
163 install_local_timer_­
handler( timer_handler );
164 local_timer_set_gap( 1000000 ); // CLINT timer clock is 10Mhz
165
166 enable_timer_clinc_i­
rq();
167 enable_irq(); // Global interrupt enable
168
169 while(1)
170 {
171 if(flag_1seg)
172 {
173 printf("Msg 1\n");
174 flag_1seg = 0;
175 }
176
177 if(flag_5seg)
178 {
179 printf(" Msg 2\n");
180 flag_5seg = 0;
181 }
182
183 }//while
184
185 }//main
186
187 */
188
189
190 /*
191 //Main para la parte 2
192 int main()
193 {
194 printf("----------MONOTONIC TIME---------\n");
195
196 // Time set: 12/10/2023 12:40
197 InitMonotonicClock(date_time_to_Y2K(21, 11, 24, 17, 51, 30 ));
198
199 uint32_t previous = 0;
localhost:57236/2f315283-fbaa-4833-ab82-f31cd919df30/ 4/5
10/1/25, 11:35 mainn.c

200 uint32_t current = 0;


201
202 do {
203 current = GetUniversalTime_Y2K­
();
204
205 if ( current != previous )
206 {
207 print_date_time_from­
_Y2K( current );
208 previous = current;
209 }
210 } while ( 1 );
211
212 printf("\n----------END---------\n");
213 }
214 */
215
216 //Main usando delay
217 int main()
218 {
219 printf("----------MONOTONIC TIME---------\n");
220
221 // Configurar la hora inicial: 12/10/2023 12:40
222 InitMonotonicClock(date_time_to_Y2K(21, 11, 24, 19, 41, 0));
223
224 uint32_t current = 0;
225 uint64_t wait = get_ticks_from_reset­
();
226 // Imprime el tiempo universal cada segundo
227 do {
228 // Obtiene el tiempo actual
229 current = GetUniversalTime_Y2K­
();
230 print_date_time_from­
_Y2K(current);
231 wait += TICKS_1SG; //Se puede hacer tambien con 10000000
232 // Espera un segundo
233 //delay(1*10000000); // Suponiendo 1 tick = 1 microsegundo
234
235 wait_until(wait);
236
237 } while (1);
238
239 printf("\n----------END---------\n");
240 }
241
242
243 //Main usando wait_until
244
245
246
247
248
249
250

localhost:57236/2f315283-fbaa-4833-ab82-f31cd919df30/ 5/5
10/1/25, 11:36 mainnnn.c

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P4\mainnnn.c

1 #include "riscv_types.h"
2 #include "log.h"
3
4 #include "riscv_uart.h"
5
6 #include "tc_fifo.h"
7 #include "tm_tc_handling.h"
8 #include "serialize.h"
9 #include "dispatch.h"
10 #include "crc.h"
11
12 #include "epd_pus_mission.h"
13
14 void processTC(uint8_t tc_bytes[], uint32_t tc_len )
15 {
16 uint8_t tm_bytes[TC_FIFO_TAM_TC];
17 uint32_t tm_len;
18
19 uint16_t tm_seq_counter = 1;
20
21 uint16_t tc_packet_id = deserialize_uint16( &tc_bytes[0] );
22 uint16_t tc_packet_seq_ctrl = deserialize_uint16( &tc_bytes[2] );
23
24 uint16_t crc_received = deserialize_uint16( &tc_bytes[tc_len-2] );
25 uint16_t crc_calculated = cal_crc_16(tc_bytes, tc_len - 2);
26
27 printf("PacketID: %04X\n", tc_packet_id );
28 printf("PacketSeqCtrl %04X\n", tc_packet_seq_ctrl );
29 printf("[CRCs] Rec: 0x%04X Calc: 0x%04X\n", crc_received, crc_calculated );
30
31 if ( crc_received != crc_calculated )
32 {
33 printf("ERROR: CRC Error: TM(1,2)\n");
34
35 // CRC ERROR: Generate TM (1,2) - Reject
36 tm_len = build_response_tm_1_­2(tm_bytes, tm_seq_counter++, tc_packet_id,
tc_packet_seq_ctrl, CRC_ERROR_CODE );
37 sendTM( tm_bytes, tm_len );
38 }
39 else
40 {
41 // TC response
42 uint8_t service_type = tc_bytes[7];
43 uint8_t service_subtype = tc_bytes[8];
44
45 if ( (service_type == 17) && (service_subtype == 1 ) )
46 {
47 // TO COMPLETE: Test ACK field
48
49 // Bit 3: ack of successful acceptance. 1=TM(1,1) required; 0=TM(1,1) not
required
50 // Bit 2: 0, not used.
localhost:57236/74f0ef6f-0c0d-4c3f-b5e2-bd51901d5820/ 1/3
10/1/25, 11:36 mainnnn.c

51 // Bit 1: 0, not used.


52 // Bit 0: 1=TM(1,7) is required; 0=TM(1,7) not required
53
54 //if TM(1,1) required {
55 //build TM(1,1) and sendTM
56 // printf("TM(1,1)\n");
57
58 if ( tc_bytes[6] & 0x08 )
59 {
60 printf("TM(1,1)\n");
61 tm_len = build_response_tm_1_­
1(tm_bytes, tm_seq_counter++,
tc_packet_id, tc_packet_seq_ctrl );
62 sendTM( tm_bytes, tm_len );
63 }
64
65
66 printf("TC(17,1) ---> TM(17,2)\n");
67 // build TM(17,2) and sendTM
68 tm_len = build_response_tm_17­
_2(tm_bytes, tm_seq_counter++, tc_packet_id,
tc_packet_seq_ctrl);
69 sendTM(tm_bytes, tm_len);
70
71 //if TM1,7) required {
72 // printf("TM(1,7)\n");
73 if ( tc_bytes[6] & 0x01 )
74 {
75 printf("TM(1,7)\n");
76 tm_len = build_response_tm_1_­
7(tm_bytes, tm_seq_counter++,
tc_packet_id, tc_packet_seq_ctrl );
77 sendTM( tm_bytes, tm_len );
78 }
79 }
80 else
81 {
82 printf("ERROR: Service not supported: TM(1,2)\n");
83
84 // Error: service nor supported TM(1,2) - Reject
85 tm_len = build_response_tm_1_­2(tm_bytes, tm_seq_counter++, tc_packet_id,
tc_packet_seq_ctrl, SERVICE_UNKNOWN_ERRO­
R_CODE);
86 sendTM( tm_bytes, tm_len );
87 }
88 }
89 }
90
91 int main()
92 {
93 uint8_t tc_bytes[TC_FIFO_TAM_TC];
94 uint32_t tc_len;
95
96 tc_fifo_init( &tc_fifo ); // tc_fifo is declared in tm_tc_handling.c
97
98 printf("TM/TC RISCV Handler\n");
99
100 // TX/RX enable

localhost:57236/74f0ef6f-0c0d-4c3f-b5e2-bd51901d5820/ 2/3
10/1/25, 11:36 mainnnn.c

101 riscv_uart_enable_TX­
();
102 riscv_uart_enable_RX­
();
103
104 // E/S por interrupción con mapeo socket
105 install_irq_handler( UART_IRQ, uart_rx_irq_handler ); // Install uart handler
106 riscv_uart_enable_RI­
(); // Enable RX irq
107 plic_irq_unmask( UART_IRQ ); // PLIC UART irq unmask
108 enable_ext_irq(); // Enable [Link]
109 enable_irq(); // Global interrupt enable
110 install_local_timer_­
handler( timer_handler );
111 local_timer_set_gap( 1000000 ); // CLINT timer clock is 10Mhz
112 enable_timer_clinc_i­
rq();
113
114 while(1)
115 {
116 /*
117 * if FIFO is not empty
118 * POP TC in mutual exclusion to avoid UART IRQ
119 * Just print received TC
120 */
121
122 //----------
123 if ( tc_fifo_not_empty( &tc_fifo) )
124 {
125 plic_irq_mask( UART_IRQ ); // PLIC UART irq mask
126 tc_fifo_pop( &tc_fifo, tc_bytes, &tc_len );
127 plic_irq_unmask( UART_IRQ ); // PLIC UART irq unmask
128
129 print_buffer( tc_bytes, tc_len );
130 processTC( tc_bytes, tc_len );
131 }
132 //----------
133 }
134 return 0;
135 }
136

localhost:57236/74f0ef6f-0c0d-4c3f-b5e2-bd51901d5820/ 3/3
10/1/25, 11:31 riscv_monotonic_clock.c

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P3B\riscv_monotonic_clock.c

1 /*
2 * riscv_monotonic_cloc­
k.c
3 *
4 * Created on: Mar 15, 2020
5 * Author: user
6 */
7
8 #include "riscv_types.h"
9 #include "clinc.h"
10 #include "log.h"
11 #include "riscv_monotonic_cloc­
k.h"
12
13 //*******************************************************************
14 /** \brief Universal Time Reference in seconds from 1/1/2000 */
15 static uint32_t UniversalTimeRefY2K;
16
17 //*******************************************************************
18
19 void InitMonotonicClock( uint32_t current_time )
20 {
21 UniversalTimeRefY2K = current_time;
22 }
23
24
25 uint32_t GetUniversalTime_Y2K­
()
26 {
27 uint32_t seconds_from_boot;
28 seconds_from_boot = (uint32_t)(get_ticks_from_reset­
()/CLINT_CLOCK); // WARNING, posible
lose of precision
29 return (UniversalTimeRefY2K+seconds_from_boot);
30 }
31
32 #define DAYS_TO_1_FEBRUARY 31
33 #define DAYS_TO_1_MARCH_NO_L­
EAP_YEAR (DAYS_TO_1_FEBRUARY + 28)
34 #define DAYS_TO_1_APRIL_NO_L­
EAP_YEAR (DAYS_TO_1_MARCH_NO_L­
EAP_YEAR +31)
35 #define DAYS_TO_1_MAY_NO_LEA­
P_YEAR (DAYS_TO_1_APRIL_NO_L­
EAP_YEAR +30)
36 #define DAYS_TO_1_JUNE_NO_LE­
AP_YEAR (DAYS_TO_1_MAY_NO_LEA­
P_YEAR +31)
37 #define DAYS_TO_1_JULY_NO_LE­
AP_YEAR (DAYS_TO_1_JUNE_NO_LE­
AP_YEAR +30)
38 #define DAYS_TO_1_AUGUST_NO_­
LEAP_YEAR (DAYS_TO_1_JULY_NO_LE­
AP_YEAR +31)
39 #define DAYS_TO_1_SEPTEMBER_­
NO_LEAP_YEAR (DAYS_TO_1_AUGUST_NO_­
LEAP_YEAR +31)
40 #define DAYS_TO_1_OCTOBER_NO­
_LEAP_YEAR (DAYS_TO_1_SEPTEMBER_­
NO_LEAP_YEAR +30)
41 #define DAYS_TO_1_NOVEMBER_N­
O_LEAP_YEAR (DAYS_TO_1_OCTOBER_NO­
_LEAP_YEAR +31)
42 #define DAYS_TO_1_DECEMBER_N­
O_LEAP_YEAR (DAYS_TO_1_NOVEMBER_N­
O_LEAP_YEAR +30)
43
44 //*******************************************************************
45
46 void print_date_time_from­
_Y2K(uint32_t seconds_from_y2K){
47
48 uint32_t aux;
49
50 uint8_t second;
51 uint8_t minute;
localhost:57236/5f3ea704-b1df-4b7a-8259-e8cc5edd9c78/ 1/4
10/1/25, 11:31 riscv_monotonic_clock.c

52 uint8_t hour;
53 uint16_t day;
54 uint8_t month;
55
56 uint32_t year;
57 uint8_t leap_year=0; //false
58
59 aux=seconds_from_y2K;
60
61 second=aux%60;
62
63 aux=(aux-second)/60; //minutes
64 minute=aux%60;
65
66 aux=(aux-minute)/60; //hours
67 hour=aux%24;
68
69 aux=(aux-hour)/24; //days
70
71 //Year
72
73 year=aux/365;
74
75 if (year>0){
76 day=aux-year*365;
77
78 if (day >= ((year-1)/4 +1))
79 day=day-((year-1)/4 +1);
80 else{
81 year--;
82 day=day+365-((year-1)/4 +1);
83 }
84
85 if(((year-1)%4)==0)
86 leap_year=1; // true
87
88 }else {
89 day=aux;
90 leap_year=1; //true
91 }
92
93 day++; //first day is 0
94
95 if(day >= (DAYS_TO_1_DECEMBER_N­
O_LEAP_YEAR + 1*leap_year)){
96 month=12; day=day-(DAYS_TO_1_DECEMBER_N­
O_LEAP_YEAR + 1*leap_year);
97 }else if(day >= (DAYS_TO_1_NOVEMBER_N­
O_LEAP_YEAR + 1*leap_year)){
98 month=11; day=day-(DAYS_TO_1_NOVEMBER_N­
O_LEAP_YEAR + 1*leap_year);
99 }else if(day >= (DAYS_TO_1_OCTOBER_NO­
_LEAP_YEAR + 1*leap_year)){
100 month=10; day=day-(DAYS_TO_1_OCTOBER_NO­
_LEAP_YEAR + 1*leap_year);
101 }else if(day >= (DAYS_TO_1_SEPTEMBER_­
NO_LEAP_YEAR + 1*leap_year)){
102 month=9; day=day-(DAYS_TO_1_SEPTEMBER_­
NO_LEAP_YEAR + 1*leap_year);
103 }else if(day >= (DAYS_TO_1_AUGUST_NO_­
LEAP_YEAR + 1*leap_year)){
104 month=8; day=day-(aux-(DAYS_TO_1_AUGUST_NO_­
LEAP_YEAR + 1*leap_year));
105 }else if(day >= (DAYS_TO_1_JULY_NO_LE­
AP_YEAR + 1*leap_year)){
localhost:57236/5f3ea704-b1df-4b7a-8259-e8cc5edd9c78/ 2/4
10/1/25, 11:31 riscv_monotonic_clock.c

106 month=7; day=day-(aux-(DAYS_TO_1_JULY_NO_LE­


AP_YEAR + 1*leap_year));
107 }else if(day >= (DAYS_TO_1_JUNE_NO_LE­
AP_YEAR + 1*leap_year)){
108 month=6; day=day-(DAYS_TO_1_JUNE_NO_LE­
AP_YEAR + 1*leap_year);
109 }else if(day >= (DAYS_TO_1_MAY_NO_LEA­
P_YEAR + 1*leap_year)){
110 month=5; day=day-(DAYS_TO_1_MAY_NO_LEA­
P_YEAR + 1*leap_year);
111 }else if(day >= (DAYS_TO_1_APRIL_NO_L­
EAP_YEAR + 1*leap_year)){
112 month=4; day=day-(DAYS_TO_1_APRIL_NO_L­
EAP_YEAR + 1*leap_year);
113 }else if(day >= (DAYS_TO_1_MARCH_NO_L­
EAP_YEAR + 1*leap_year)){
114 month=3; day=day-(DAYS_TO_1_MARCH_NO_L­
EAP_YEAR + 1*leap_year);
115 }else if(day >= (DAYS_TO_1_FEBRUARY )){
116 month=2; day=day-(DAYS_TO_1_FEBRUARY);
117 }else month=1;
118
119 printf("Fecha: %d | %d | %d Hora: %d:%d:%d\n", day, month, year+2000, hour, minute,
second);
120 }
121
122 //*******************************************************************
123
124 uint32_t date_time_to_Y2K(uint8_t day, uint8_t month, uint8_t year
125 , uint8_t hour, uint8_t minutes, uint8_t seconds ){
126
127 uint8_t leap_year;
128
129 uint32_t total_days;
130 uint32_t y2K;
131
132 total_days=year*365;
133
134 if(year){
135 total_days+=(year-1)/4 + 1;
136 leap_year= ((year-1)%4==0);
137 }else
138 leap_year=1; // true
139
140 switch(month){
141 case(2):
142 total_days+=DAYS_TO_1_FEBRUARY;break;
143 case(3):
144 total_days+=DAYS_TO_1_MARCH_NO_L­
EAP_YEAR+1*leap_year;break;
145 case(4):
146 total_days+=DAYS_TO_1_APRIL_NO_L­
EAP_YEAR+1*leap_year;break;
147 case(5):
148 total_days+=DAYS_TO_1_MAY_NO_LEA­
P_YEAR+1*leap_year;break;
149 case(6):
150 total_days+=DAYS_TO_1_JUNE_NO_LE­
AP_YEAR+1*leap_year;break;
151 case(7):
152 total_days+=DAYS_TO_1_JULY_NO_LE­
AP_YEAR+1*leap_year;break;
153 case(8):
154 total_days+=DAYS_TO_1_AUGUST_NO_­
LEAP_YEAR+1*leap_year;break;
155 case(9):
156 total_days+=DAYS_TO_1_SEPTEMBER_­
NO_LEAP_YEAR+1*leap_year;break;
157 case(10):
158 total_days+=DAYS_TO_1_OCTOBER_NO­
_LEAP_YEAR+1*leap_year;break;

localhost:57236/5f3ea704-b1df-4b7a-8259-e8cc5edd9c78/ 3/4
10/1/25, 11:31 riscv_monotonic_clock.c

159 case(11):
160 total_days+=DAYS_TO_1_NOVEMBER_N­
O_LEAP_YEAR+1*leap_year;break;
161 case(12):
162 total_days+=DAYS_TO_1_DECEMBER_N­
O_LEAP_YEAR+1*leap_year;break;
163 }void delay( uint64_t ticks );
164 void wait_until( uint64_t ticks_from_reset );
165
166
167 total_days+= (day-1);
168
169 y2K=((total_days*24 + hour)*60 + minutes)*60 + seconds;
170
171 return y2K;
172 }
173
174 /*
175 uint64_t get_ticks_from_reset­
()
176 {
177 return *p_clinc_mtime;
178 }
179 */
180
181 void delay( uint64_t ticks_to_wait )
182 {
183 uint64_t target_ticks = get_ticks_from_reset­
() + ticks_to_wait;
184 uint64_t current_ticks;
185
186 do {
187 current_ticks = get_ticks_from_reset­
();
188 } while ( current_ticks < target_ticks );
189 }
190
191 void wait_until( uint64_t target_ticks )
192 {
193 uint64_t current_ticks;
194
195 do {
196 current_ticks = get_ticks_from_reset­
();
197 } while ( current_ticks < target_ticks );
198 }
199

localhost:57236/5f3ea704-b1df-4b7a-8259-e8cc5edd9c78/ 4/4
10/1/25, 11:33 riscv_monotonic_clock.h

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P3A\riscv_monotonic_clock.h

1 #ifndef RISCV_MONOTONIC_H_
2 #define RISCV_MONOTONIC_H_
3
4 #define CLINT_CLOCK (10000000)
5
6 void InitMonotonicClock( uint32_t current_time );
7
8 uint32_t GetUniversalTime_Y2K­
();
9
10 void print_date_time_from­
_Y2K(uint32_t seconds_from_y2K);
11
12 uint32_t date_time_to_Y2K( uint8_t day, uint8_t month, uint8_t year,
13 uint8_t hour, uint8_t minutes, uint8_t seconds );
14
15 // uint64_t get_ticks_from_reset­
();
16 #define get_ticks_from_reset­
() ((volatile uint64_t)(*p_clinc_mtime))
17 void delay( uint64_t ticks_to_wait );
18 void wait_until( uint64_t ticks_from_reset );
19
20 //Cuando utilizo estas dos funciones, el define get_ticks_from_reset­me dice que el puntero
clinc_mtime no está declarado
21
22 void delay( uint64_t ticks_to_wait );
23
24 void wait_until( uint64_t target_ticks );
25
26
27 //ASÍ SE HACEN LAS FUNCIONES ESTAS
28 void delay( uint64_t ticks_to_wait )
29 {
30 uint64_t target_ticks = get_ticks_from_reset­
() + ticks_to_wait;
31 uint64_t current_ticks;
32
33 do {
34 current_ticks = get_ticks_from_reset­
();
35 } while ( current_ticks < target_ticks );
36 }
37
38 void wait_until( uint64_t target_ticks )
39 {
40 uint64_t current_ticks;
41
42 do {
43 current_ticks = get_ticks_from_reset­
();
44 } while ( current_ticks < target_ticks );
45 }
46
47 #endif /* RISCV_MONOTONIC_H_*/
48

localhost:57236/2d3d068a-ce88-48ee-a861-e21df6563949/ 1/1
10/1/25, 11:36 tm_tc_handling.c

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P4\tm_tc_handling.c

1 #include "ccsds_pus_format.h"
2 #include "riscv_uart.h"
3
4 #include "serialize.h"
5 #include "crc.h"
6 #include "epd_pus_mission.h"
7 #include "tc_fifo.h"
8 #include "tm_tc_handling.h"
9
10 #include "log.h"
11
12 uint32_t idx=0;
13 uint32_t bytes_to_read=0; // Total bytes to read
14 uint8_t tc_buffer[TC_FIFO_TAM_TC];
15 uint32_t receiver_state = IDLE;
16
17 uint32_t counter = 0;
18
19 void timer_handler(void)
20 {
21 if ( counter != 0 )
22 {
23 counter--;
24
25 if ( counter == 0 )
26 {
27 receiver_state = IDLE;
28 idx=0;
29 }
30 }
31 }
32
33
34
35
36 void uart_rx_irq_handler(void){
37 uint8_t data;
38
39 data = riscv_getchar();
40
41 switch (receiver_state)
42 {
43 case IDLE:
44
45 // TO COMPLETE: Wait for TC HEADER start (0x1B)
46
47
48 if(data==0x1B)
49 {
50 tc_buffer[idx]=data;
51 idx++;

localhost:57236/44e087aa-8d84-458a-b82c-265fdfd2cb1d/ 1/6
10/1/25, 11:36 tm_tc_handling.c

52 receiver_state = READING_CCSDS_HEADER­
;
53
54 counter = 10; // esperamos 10 ticks de una decima
55 }
56
57 break;
58 case READING_CCSDS_HEADER­
:
59
60 // TO COMPLETE: Read TC HEADER
61 tc_buffer[idx] = data;
62 idx++;
63
64 if(idx == TC_HEADER_SIZE)//TC_HEADER_SIZE = 6
65 {
66 uint16_t packet_length = deserialize_uint16(&tc_buffer[4]);
67 bytes_to_read = 6 + packet_length + 1;
68 receiver_state = READING_PACKET_DF;
69
70 }
71
72
73 break;
74 case READING_PACKET_DF:
75
76
77 // TO COMPLETE: Read packet data field and checksum
78 // TO COMPLETE: When TC complete PUSH tc_buffer into FIFO
79
80 tc_buffer[idx] = data;
81 idx++;
82
83 if(idx == bytes_to_read)
84 {
85 //uint8_t tc_fifo_push(tc_fifo_t *p_tc_fifo, uint8_t *p_data, uint32_t n)
86
87 tc_fifo_push(&tc_fifo, tc_buffer, bytes_to_read); //tc_fifo lo dice la
función//el puntero es nuestro array tc_buffer//El tamaño total es bytes_to_read que ya lo
he calculado antes
88 idx = 0;
89 bytes_to_read = 0;
90 receiver_state = IDLE;
91
92
93 counter = 0; // Se ha recibido el TC completo, desactivamos el contador
94 }
95
96 break;
97 }
98 }
99
100 /*
101 Build TM 17.2 example
102 */

localhost:57236/44e087aa-8d84-458a-b82c-265fdfd2cb1d/ 2/6
10/1/25, 11:36 tm_tc_handling.c

103 uint32_t build_response_tm_17­


_2(uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl)
104 {
105 struct ccds_pus_tmtc_packet­
_header tm_packet_header;
106 struct ccds_pus_tm_df_heade­
r df_header;
107
108 tm_packet_header.packet_id = ccsds_pus_tm_build_p­
acket_id(EPD_APID);
109 tm_packet_header.packet_seq_ctrl = ccsds_pus_tm_build_p­
acket_seq_ctrl(0x3,
tm_seq_count); // verify packet sequence (0x3)
110 tm_packet_header.packet_length = 4+2 - 1; // pus header + checksum - 1
111
112 df_header.version = 0x10; // 0001 0000
113 df_header.type = 17;
114 df_header.subtype = 2;
115 df_header.destinationID = EPD_DESTINATION_ID;
116
117 serialize_uint16(tm_packet_header.packet_id, &tm_bytes[0]);
118 serialize_uint16(tm_packet_header.packet_seq_ctrl, &tm_bytes[2]);
119 serialize_uint16(tm_packet_header.packet_length, &tm_bytes[4]);
120
121 // Store version field into the corresponding byte
122 tm_bytes[6] = df_header.version;
123
124 // Store the remaining fields into their respective locations
125 tm_bytes[7] = df_header.type;
126 tm_bytes[8] = df_header.subtype;
127 tm_bytes[9] = df_header.destinationID;
128
129 // This TM has no data
130
131 uint16_t crc_value = cal_crc_16(tm_bytes, 6+4); // 6 bytes CCSDS header, 4 bytes PUS
header
132 serialize_uint16(crc_value, &tm_bytes[10]);
133
134 return 6+4+2; // packet header + pus header + checksum
135 }
136
137 uint32_t build_response_tm_1_­
1(uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl)
138 {
139 // TO COMPLETE: This TM has app data before checksum
140 struct ccds_pus_tmtc_packet­
_header tm_packet_header;
141 struct ccds_pus_tm_df_heade­
r df_header;
142
143 tm_packet_header.packet_id = ccsds_pus_tm_build_p­
acket_id(EPD_APID);
144 tm_packet_header.packet_seq_ctrl = ccsds_pus_tm_build_p­
acket_seq_ctrl(0x3,
tm_seq_count); // verify packet sequence (0x3)
145 tm_packet_header.packet_length = 4+4+2 - 1; // pus header + application data(Tc
application ID(4) ) + checksum - 1(convenio)
146
147 df_header.version = 0x10; // 0001 0000
148 df_header.type = 1; //es 1,1 asi que 1
149 df_header.subtype = 1; //es 1,1 asi que 1
150 df_header.destinationID = EPD_DESTINATION_ID; //Es igual en todos

localhost:57236/44e087aa-8d84-458a-b82c-265fdfd2cb1d/ 3/6
10/1/25, 11:36 tm_tc_handling.c

151
152 serialize_uint16(tm_packet_header.packet_id, &tm_bytes[0]);
153 serialize_uint16(tm_packet_header.packet_seq_ctrl, &tm_bytes[2]);
154 serialize_uint16(tm_packet_header.packet_length, &tm_bytes[4]);
155
156 // Store version field into the corresponding byte
157 tm_bytes[6] = df_header.version;
158
159 // Store the remaining fields into their respective locations
160 tm_bytes[7] = df_header.type;
161 tm_bytes[8] = df_header.subtype;
162 tm_bytes[9] = df_header.destinationID;
163
164 // Create app data
165 serialize_uint32(tc_packet_id, &tm_bytes[10]);//El application data entra en la
posicion 10
166
167 uint16_t crc_value = cal_crc_16(tm_bytes, 6+4+4); // 6 bytes CCSDS header, 4
bytes PUS header, 4 application data
168 serialize_uint16(crc_value, &tm_bytes[14]); //Esto es el crc
169
170 return 6+4+4+2; // packet header + pus header + tc_packet_id + checksum
171 }
172
173 uint32_t build_response_tm_1_­
2(uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl, uint8_t error_code)
174 {
175 struct ccds_pus_tmtc_packet­
_header tm_packet_header;
176 struct ccds_pus_tm_df_heade­
r df_header;
177
178 tm_packet_header.packet_id = ccsds_pus_tm_build_p­
acket_id(EPD_APID);
179 tm_packet_header.packet_seq_ctrl = ccsds_pus_tm_build_p­
acket_seq_ctrl(0x3,
tm_seq_count); // verify packet sequence (0x3)
180 tm_packet_header.packet_length = 4+4+1+2 - 1; // pus header + application data(Tc
application ID(4) + error(1)) + checksum - 1(convenio)
181
182 df_header.version = 0x10; // 0001 0000
183 df_header.type = 1; //es 1,2 asi que 1
184 df_header.subtype = 2; //es 1,2 asi que 2
185 df_header.destinationID = EPD_DESTINATION_ID; //Es igual en todos
186
187 serialize_uint16(tm_packet_header.packet_id, &tm_bytes[0]);
188 serialize_uint16(tm_packet_header.packet_seq_ctrl, &tm_bytes[2]);
189 serialize_uint16(tm_packet_header.packet_length, &tm_bytes[4]);
190
191 // Store version field into the corresponding byte
192 tm_bytes[6] = df_header.version;
193
194 // Store the remaining fields into their respective locations
195 tm_bytes[7] = df_header.type;
196 tm_bytes[8] = df_header.subtype;
197 tm_bytes[9] = df_header.destinationID;
198
199 // Create app data

localhost:57236/44e087aa-8d84-458a-b82c-265fdfd2cb1d/ 4/6
10/1/25, 11:36 tm_tc_handling.c

200 serialize_uint32(tc_packet_id, &tm_bytes[10]);//El application data entra en la


posicion 10
201 tm_bytes[14] = error_code; //El error entra en la posicion 14
202
203 uint16_t crc_value = cal_crc_16(tm_bytes, 6+4+4+1); // 6 bytes CCSDS header, 4 bytes
PUS header, 4 bytes APP ID, 1 byte error
204 serialize_uint16(crc_value, &tm_bytes[15]); //Esto es el crc
205
206
207
208 return 6+4+4+1+2; // packet header + pus header + tc_packet_id + error code + checksum
209 }
210
211 uint32_t build_response_tm_1_­
7(uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl)
212 {
213 // TO COMPLETE: This TM has app data before checksum
214 struct ccds_pus_tmtc_packet­
_header tm_packet_header;
215 struct ccds_pus_tm_df_heade­
r df_header;
216
217 tm_packet_header.packet_id = ccsds_pus_tm_build_p­
acket_id(EPD_APID);
218 tm_packet_header.packet_seq_ctrl = ccsds_pus_tm_build_p­
acket_seq_ctrl(0x3,
tm_seq_count); // verify packet sequence (0x3)
219 tm_packet_header.packet_length = 4+4+2 - 1; // pus header + application data(Tc
application ID(4)) + checksum - 1(convenio)
220
221 df_header.version = 0x10; // 0001 0000
222 df_header.type = 1; //es 1,7 asi que 1
223 df_header.subtype = 7; //es 1,7 asi que 7
224 df_header.destinationID = EPD_DESTINATION_ID; //Es igual en todos
225
226 serialize_uint16(tm_packet_header.packet_id, &tm_bytes[0]);
227 serialize_uint16(tm_packet_header.packet_seq_ctrl, &tm_bytes[2]);
228 serialize_uint16(tm_packet_header.packet_length, &tm_bytes[4]);
229
230 // Store version field into the corresponding byte
231 tm_bytes[6] = df_header.version;
232
233 // Store the remaining fields into their respective locations
234 tm_bytes[7] = df_header.type;
235 tm_bytes[8] = df_header.subtype;
236 tm_bytes[9] = df_header.destinationID;
237
238 // Create app data
239 serialize_uint32(tc_packet_id, &tm_bytes[10]);//El application data entra en la
posicion 10
240
241 uint16_t crc_value = cal_crc_16(tm_bytes, 6+4+4); // 6 bytes CCSDS header, 4
bytes PUS header, 5 application data
242 serialize_uint16(crc_value, &tm_bytes[14]); //Esto es el crc
243
244 return 6+4+4+2; // packet header + pus header + tc_packet_id + checksum
245 }
246

localhost:57236/44e087aa-8d84-458a-b82c-265fdfd2cb1d/ 5/6
10/1/25, 11:36 tm_tc_handling.c

247 uint32_t build_response_tm_1_­


8(uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl, uint8_t error)
248 {
249 // TO COMPLETE: This TM has app data and error code before checksum
250
251 return 6+4+4+1+2; // packet header + pus header + tc_packet_id + error code + checksum
252 }
253
254
255 void sendTM( uint8_t tm_bytes[], uint32_t tm_len )
256 {
257 for (int i=0;i<tm_len;i++)
258 {
259 uint8_t error = riscv_putchar( tm_bytes[i]);
260 if ( error )
261 break; // discard response
262 }
263 }
264
265

localhost:57236/44e087aa-8d84-458a-b82c-265fdfd2cb1d/ 6/6
10/1/25, 11:36 tm_tc_handling.h

~\Desktop\Física e instrumentación espacial\Segundo\PDI\PEI2\Imprimir P4\tm_tc_handling.h

1 #ifndef TM_TC_HANDLING_H
2 #define TM_TC_HANDLING_H
3
4 #include "riscv_types.h"
5
6 #define IDLE 0
7 #define READING_CCSDS_HEADER­1
8 #define READING_PACKET_DF 2
9
10 #define TC_HEADER_SIZE 6
11
12 void uart_rx_irq_handler(void);
13 void timer_handler(void);
14
15 uint32_t build_response_tm_17­
_2(uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl);
16 uint32_t build_response_tm_1_­
1 (uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl);
17 uint32_t build_response_tm_1_­
2 (uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl, uint8_t error);
18 uint32_t build_response_tm_1_­
7 (uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl);
19 uint32_t build_response_tm_1_­
8 (uint8_t tm_bytes[], uint16_t tm_seq_count, uint16_t
tc_packet_id, uint16_t tc_packet_seq_ctrl, uint8_t error);
20
21 void sendTM( uint8_t tm_bytes[], uint32_t n );
22
23 #endif /* TM_TC_HANDLING_H */
24 //[Link] de interrupciones UART (uart_rx_irq_handler)
25 //Estados de recepción:
26 //-----------IDLE: Espera un encabezado CCSDS válido que comience con 0x1B.
27 //-----------READING_CCSDS_HEADER­
: Lee el encabezado CCSDS (6 bytes).
28 //-----------READING_PACKET_DF: Lee los datos de la trama y el checksum.
29 //Cálculo de bytes_to_read:
30 //-----------Se basa en el campo packet_length del encabezado CCSDS.
31 //-----------Asegura la lectura completa del paquete, incluyendo los datos y el checksum.
32 //Función tc_fifo_push:
33 //-----------Una vez recibido el paquete completo, lo almacena en un FIFO para su posterior
procesamiento.
34
35 //[Link]ón de tramas TM (build_response_tm_*)
36 //Las funciones crean tramas de telemetría según el tipo/subtipo requerido.
37 //Encabezados CCSDS y PUS:
38 //-----------Se construyen utilizando funciones auxiliares (ccsds_pus_tm_build_p­
acket_id,
etc.).
39 //-----------Se serializan en el array tm_bytes para enviarse posteriormente.
40 //Datos de la aplicación:
41 //-----------Algunas TMs incluyen datos específicos, como el tc_packet_id o códigos de error.
42 //Cálculo del CRC:
43 //-----------Utiliza la función cal_crc_16 para asegurar la integridad de los datos
transmitidos.
44

localhost:57236/65885ee9-a59d-4cb7-a666-00ca68ae6700/ 1/2
10/1/25, 11:36 tm_tc_handling.h

45
46 //3. Envío de TMs (sendTM)
47 //Envía cada byte de la trama TM a través de UART.
48 //Gestiona errores potenciales en la transmisión.
49
50
51

localhost:57236/65885ee9-a59d-4cb7-a666-00ca68ae6700/ 2/2

También podría gustarte