forked from achamaikin/CCSModuleSW30Web
151 lines
4.1 KiB
C
Executable File
151 lines
4.1 KiB
C
Executable File
/*
|
|
* debug.c
|
|
*
|
|
* Created on: Apr 16, 2024
|
|
* Author: colorbass
|
|
*/
|
|
|
|
#include "main.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <stdarg.h>
|
|
#include "debug.h"
|
|
#include "board.h"
|
|
#include "usart.h"
|
|
#include <time.h>
|
|
#include <connector.h>
|
|
#include "serial_control.h"
|
|
|
|
// Кольцевой буфер для отладочных сообщений
|
|
#define DEBUG_BUFFER_SIZE 1024
|
|
#define DEBUG_BUFFER_MAX_COUNT 128
|
|
|
|
typedef struct {
|
|
uint8_t buffer[DEBUG_BUFFER_SIZE];
|
|
volatile uint16_t write_index;
|
|
volatile uint16_t read_index;
|
|
volatile uint16_t count;
|
|
} DebugBuffer_t;
|
|
|
|
static DebugBuffer_t debug_buffer = {
|
|
.buffer = {0},
|
|
.write_index = 0,
|
|
.read_index = 0,
|
|
.count = 0
|
|
};
|
|
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
int _write(int fd, char * ptr, int len)
|
|
{
|
|
debug_buffer_add((const uint8_t*)ptr, len);
|
|
return len;
|
|
}
|
|
#endif
|
|
|
|
// Добавляет данные в кольцевой буфер
|
|
void debug_buffer_add(const uint8_t* data, uint16_t len)
|
|
{
|
|
__disable_irq();
|
|
|
|
for (uint16_t i = 0; i < len; i++) {
|
|
// Если буфер полон, перезаписываем старые данные
|
|
if (debug_buffer.count >= DEBUG_BUFFER_SIZE) {
|
|
debug_buffer.read_index = (debug_buffer.read_index + 1) % DEBUG_BUFFER_SIZE;
|
|
debug_buffer.count--;
|
|
}
|
|
|
|
debug_buffer.buffer[debug_buffer.write_index] = data[i];
|
|
debug_buffer.write_index = (debug_buffer.write_index + 1) % DEBUG_BUFFER_SIZE;
|
|
debug_buffer.count++;
|
|
}
|
|
|
|
__enable_irq();
|
|
}
|
|
|
|
// Возвращает количество доступных данных в буфере
|
|
uint16_t debug_buffer_available(void)
|
|
{
|
|
__disable_irq();
|
|
uint16_t count = debug_buffer.count;
|
|
__enable_irq();
|
|
return count;
|
|
}
|
|
|
|
// Отправляет один пакет данных из буфера через SC_SendPacket (не более 250 байт)
|
|
void debug_buffer_send(void)
|
|
{
|
|
__disable_irq();
|
|
|
|
// Если буфер пуст, ничего не делаем
|
|
if (debug_buffer.count == 0) {
|
|
__enable_irq();
|
|
return;
|
|
}
|
|
|
|
// Определяем сколько байт можно отправить (не более 250)
|
|
uint16_t bytes_to_send = debug_buffer.count;
|
|
if (bytes_to_send > DEBUG_BUFFER_MAX_COUNT) {
|
|
bytes_to_send = DEBUG_BUFFER_MAX_COUNT;
|
|
}
|
|
|
|
// Вычисляем сколько байт до конца буфера
|
|
uint16_t bytes_to_end = DEBUG_BUFFER_SIZE - debug_buffer.read_index;
|
|
|
|
// Отправляем только непрерывный блок (до конца буфера или до bytes_to_send)
|
|
if (bytes_to_send > bytes_to_end) {
|
|
bytes_to_send = bytes_to_end;
|
|
}
|
|
|
|
// Отправляем данные напрямую из буфера
|
|
if(bytes_to_send == debug_buffer.count){
|
|
SC_SendPacket(&debug_buffer.buffer[debug_buffer.read_index], bytes_to_send, CMD_GET_LOG);
|
|
}else{
|
|
SC_SendPacket(&debug_buffer.buffer[debug_buffer.read_index], bytes_to_send, CMD_GET_LOG_CONTINUE);
|
|
}
|
|
debug_buffer.read_index = (debug_buffer.read_index + bytes_to_send) % DEBUG_BUFFER_SIZE;
|
|
debug_buffer.count -= bytes_to_send;
|
|
|
|
__enable_irq();
|
|
}
|
|
|
|
#define LOG_BUFFER_SIZE 128
|
|
uint8_t log_buffer[LOG_BUFFER_SIZE];
|
|
|
|
// Кастомный printf с приоритетом лога
|
|
int log_printf(LogLevel_t level, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
int result;
|
|
|
|
// Добавляем приоритет первым байтом
|
|
log_buffer[0] = (uint8_t)level;
|
|
|
|
// Форматируем строку начиная со второго байта
|
|
va_start(args, format);
|
|
result = vsnprintf((char*)&log_buffer[1], LOG_BUFFER_SIZE - 2, format, args);
|
|
va_end(args);
|
|
|
|
// Проверяем, не переполнился ли буфер
|
|
if (result < 0) {
|
|
return result;
|
|
}
|
|
|
|
// Ограничиваем размер, чтобы оставить место для нуль-терминатора
|
|
if (result >= (LOG_BUFFER_SIZE - 2)) {
|
|
result = LOG_BUFFER_SIZE - 2;
|
|
}
|
|
|
|
// Добавляем нуль-терминатор в конец
|
|
log_buffer[result + 1] = '\0';
|
|
|
|
// Отправляем в буфер (приоритет + строка + нуль-терминатор)
|
|
debug_buffer_add(log_buffer, result + 2);
|
|
|
|
return result;
|
|
}
|
|
|