auto-sync
This commit is contained in:
parent
bdec181b62
commit
35d0ece7f3
|
@ -149,6 +149,8 @@ bool isConsoleReady(void) {
|
|||
}
|
||||
#endif /* EFI_PROD_CODE || EFI_EGT */
|
||||
|
||||
bool_t consoleInBinaryMode = false;
|
||||
|
||||
static THD_WORKING_AREA(consoleThreadStack, 2 * UTILITY_THREAD_STACK_SIZE);
|
||||
static msg_t consoleThreadThreadEntryPoint(void *arg) {
|
||||
(void) arg;
|
||||
|
@ -198,6 +200,7 @@ static Logging *logger;
|
|||
|
||||
static void switchToBinaryProtocol(void) {
|
||||
scheduleMsg(logger, "switching to binary protocol");
|
||||
consoleInBinaryMode = true;
|
||||
}
|
||||
|
||||
void startConsole(Logging *sharedLogger, CommandHandler console_line_callback_p) {
|
||||
|
|
|
@ -99,7 +99,6 @@ static efitimems_t previousWriteReportMs = 0;
|
|||
|
||||
ts_channel_s tsChannel;
|
||||
|
||||
char crcReadBuffer[300];
|
||||
extern uint8_t crcWriteBuffer[300];
|
||||
|
||||
static int ts_serial_ready(void) {
|
||||
|
@ -360,7 +359,7 @@ static bool isKnownCommand(char command) {
|
|||
return command == TS_HELLO_COMMAND || command == TS_READ_COMMAND || command == TS_OUTPUT_COMMAND
|
||||
|| command == TS_PAGE_COMMAND || command == TS_BURN_COMMAND || command == TS_SINGLE_WRITE_COMMAND
|
||||
|| command == TS_LEGACY_HELLO_COMMAND || command == TS_CHUNK_WRITE_COMMAND
|
||||
|| command == TS_EXECUTE;
|
||||
|| command == TS_EXECUTE || command == TS_GET_TEXT;
|
||||
}
|
||||
|
||||
static uint8_t firstByte;
|
||||
|
@ -401,20 +400,20 @@ void runBinaryProtocolLoop(ts_channel_s *tsChannel) {
|
|||
|
||||
uint32_t incomingPacketSize = firstByte * 256 + secondByte;
|
||||
|
||||
if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(crcReadBuffer) - CRC_WRAPPING_SIZE)) {
|
||||
if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(tsChannel->crcReadBuffer) - CRC_WRAPPING_SIZE)) {
|
||||
scheduleMsg(tsLogger, "TunerStudio: invalid size: %d", incomingPacketSize);
|
||||
tunerStudioError("ERROR: CRC header size");
|
||||
sendErrorCode(tsChannel);
|
||||
continue;
|
||||
}
|
||||
|
||||
recieved = chnReadTimeout(tsChannel->channel, (uint8_t*)crcReadBuffer, 1, MS2ST(TS_READ_TIMEOUT));
|
||||
recieved = chnReadTimeout(tsChannel->channel, (uint8_t*)tsChannel->crcReadBuffer, 1, MS2ST(TS_READ_TIMEOUT));
|
||||
if (recieved != 1) {
|
||||
tunerStudioError("ERROR: did not receive command");
|
||||
continue;
|
||||
}
|
||||
|
||||
char command = crcReadBuffer[0];
|
||||
char command = tsChannel->crcReadBuffer[0];
|
||||
if (!isKnownCommand(command)) {
|
||||
scheduleMsg(tsLogger, "unexpected command %x", command);
|
||||
sendErrorCode(tsChannel);
|
||||
|
@ -423,7 +422,7 @@ void runBinaryProtocolLoop(ts_channel_s *tsChannel) {
|
|||
|
||||
// scheduleMsg(logger, "TunerStudio: reading %d+4 bytes(s)", incomingPacketSize);
|
||||
|
||||
recieved = chnReadTimeout(tsChannel->channel, (uint8_t * ) (crcReadBuffer + 1),
|
||||
recieved = chnReadTimeout(tsChannel->channel, (uint8_t * ) (tsChannel->crcReadBuffer + 1),
|
||||
incomingPacketSize + CRC_VALUE_SIZE - 1, MS2ST(TS_READ_TIMEOUT));
|
||||
int expectedSize = incomingPacketSize + CRC_VALUE_SIZE - 1;
|
||||
if (recieved != expectedSize) {
|
||||
|
@ -433,17 +432,17 @@ void runBinaryProtocolLoop(ts_channel_s *tsChannel) {
|
|||
continue;
|
||||
}
|
||||
|
||||
uint32_t expectedCrc = *(uint32_t*) (crcReadBuffer + incomingPacketSize);
|
||||
uint32_t expectedCrc = *(uint32_t*) (tsChannel->crcReadBuffer + incomingPacketSize);
|
||||
|
||||
expectedCrc = SWAP_UINT32(expectedCrc);
|
||||
|
||||
uint32_t actualCrc = crc32(crcReadBuffer, incomingPacketSize);
|
||||
uint32_t actualCrc = crc32(tsChannel->crcReadBuffer, incomingPacketSize);
|
||||
if (actualCrc != expectedCrc) {
|
||||
scheduleMsg(tsLogger, "TunerStudio: CRC %x %x %x %x", crcReadBuffer[incomingPacketSize + 0],
|
||||
crcReadBuffer[incomingPacketSize + 1], crcReadBuffer[incomingPacketSize + 2],
|
||||
crcReadBuffer[incomingPacketSize + 3]);
|
||||
scheduleMsg(tsLogger, "TunerStudio: CRC %x %x %x %x", tsChannel->crcReadBuffer[incomingPacketSize + 0],
|
||||
tsChannel->crcReadBuffer[incomingPacketSize + 1], tsChannel->crcReadBuffer[incomingPacketSize + 2],
|
||||
tsChannel->crcReadBuffer[incomingPacketSize + 3]);
|
||||
|
||||
scheduleMsg(tsLogger, "TunerStudio: command %c actual CRC %x/expected %x", crcReadBuffer[0], actualCrc,
|
||||
scheduleMsg(tsLogger, "TunerStudio: command %c actual CRC %x/expected %x", tsChannel->crcReadBuffer[0], actualCrc,
|
||||
expectedCrc);
|
||||
tunerStudioError("ERROR: CRC issue");
|
||||
continue;
|
||||
|
@ -452,7 +451,7 @@ void runBinaryProtocolLoop(ts_channel_s *tsChannel) {
|
|||
// scheduleMsg(logger, "TunerStudio: P00-07 %x %x %x %x %x %x %x %x", crcIoBuffer[0], crcIoBuffer[1],
|
||||
// crcIoBuffer[2], crcIoBuffer[3], crcIoBuffer[4], crcIoBuffer[5], crcIoBuffer[6], crcIoBuffer[7]);
|
||||
|
||||
int success = tunerStudioHandleCrcCommand(tsChannel, crcReadBuffer, incomingPacketSize);
|
||||
int success = tunerStudioHandleCrcCommand(tsChannel, tsChannel->crcReadBuffer, incomingPacketSize);
|
||||
if (!success)
|
||||
print("got unexpected TunerStudio command %x:%c\r\n", command, command);
|
||||
|
||||
|
@ -573,7 +572,7 @@ bool handlePlainCommand(ts_channel_s *tsChannel, uint8_t command) {
|
|||
tsState.errorCounter++;
|
||||
return true;
|
||||
}
|
||||
recieved = chSequentialStreamRead(tsChannel->channel, (uint8_t * )&crcReadBuffer, writeChunkRequest.count);
|
||||
recieved = chSequentialStreamRead(tsChannel->channel, (uint8_t * )&tsChannel->crcReadBuffer, writeChunkRequest.count);
|
||||
if (recieved != writeChunkRequest.count) {
|
||||
scheduleMsg(tsLogger, "ERROR: Not enough for plain chunk write content: %d while expecting %d", recieved, writeChunkRequest.count);
|
||||
tsState.errorCounter++;
|
||||
|
@ -581,7 +580,7 @@ bool handlePlainCommand(ts_channel_s *tsChannel, uint8_t command) {
|
|||
}
|
||||
currentPageId = writeChunkRequest.page;
|
||||
|
||||
handleWriteChunkCommand(tsChannel, TS_PLAIN, writeChunkRequest.offset, writeChunkRequest.count, (uint8_t * )&crcReadBuffer);
|
||||
handleWriteChunkCommand(tsChannel, TS_PLAIN, writeChunkRequest.offset, writeChunkRequest.count, (uint8_t * )&tsChannel->crcReadBuffer);
|
||||
return true;
|
||||
} else if (command == TS_READ_COMMAND) {
|
||||
//scheduleMsg(logger, "Got naked READ PAGE???");
|
||||
|
@ -662,6 +661,13 @@ int tunerStudioHandleCrcCommand(ts_channel_s *tsChannel, char *data, int incomin
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* we use 'blockingFactor = 256' in rusefi.ini
|
||||
* todo: should we just do (256 + CRC_WRAPPING_SIZE) ?
|
||||
*/
|
||||
|
||||
static uint8_t tsCrcWriteBuffer[300];
|
||||
|
||||
void startTunerStudioConnectivity(Logging *sharedLogger) {
|
||||
tsLogger = sharedLogger;
|
||||
|
||||
|
@ -679,7 +685,7 @@ void startTunerStudioConnectivity(Logging *sharedLogger) {
|
|||
addConsoleActionI("set_ts_speed", setTsSpeed);
|
||||
|
||||
tsChannel.channel = getTsSerialDevice();
|
||||
// tsChannel.writeBuffer
|
||||
tsChannel.writeBuffer = tsCrcWriteBuffer;
|
||||
|
||||
chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, tsThreadEntryPoint, NULL);
|
||||
}
|
||||
|
|
|
@ -13,13 +13,6 @@
|
|||
EXTERN_ENGINE;
|
||||
|
||||
extern Logging *tsLogger;
|
||||
/**
|
||||
* we use 'blockingFactor = 256' in rusefi.ini
|
||||
* todo: should we just do (256 + CRC_WRAPPING_SIZE) ?
|
||||
*/
|
||||
|
||||
uint8_t crcWriteBuffer[300];
|
||||
extern char crcReadBuffer[300];
|
||||
|
||||
#if EFI_PROD_CODE || defined(__DOXYGEN__)
|
||||
#include "pin_repository.h"
|
||||
|
@ -78,7 +71,7 @@ void tunerStudioWriteData(ts_channel_s *tsChannel, const uint8_t * buffer, int s
|
|||
*/
|
||||
void tunerStudioWriteCrcPacket(ts_channel_s *tsChannel, const uint8_t command, const void *buf, const uint16_t size) {
|
||||
|
||||
uint8_t *writeBuffer = crcWriteBuffer;
|
||||
uint8_t *writeBuffer = tsChannel->writeBuffer;
|
||||
|
||||
// todo: max size validation
|
||||
*(uint16_t *) writeBuffer = SWAP_UINT16(size + 1); // packet size including command
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef struct {
|
|||
#define TS_PAGE_COMMAND 'P'
|
||||
#define TS_COMMAND_F 'F'
|
||||
#define TS_EXECUTE 'E'
|
||||
#define TS_GET_TEXT 'G'
|
||||
|
||||
#define TS_SINGLE_WRITE_COMMAND 'W'
|
||||
#define TS_CHUNK_WRITE_COMMAND 'C'
|
||||
|
|
|
@ -39,36 +39,11 @@
|
|||
#include "memstreams.h"
|
||||
#include "console_io.h"
|
||||
#include "rfiutil.h"
|
||||
#include "loggingcentral.h"
|
||||
|
||||
// we use this magic constant to make sure it's not just a random non-zero int in memory
|
||||
#define MAGIC_LOGGING_FLAG 45234441
|
||||
|
||||
typedef char log_buf_t[DL_OUTPUT_BUFFER];
|
||||
|
||||
/**
|
||||
* we need to leave a byte for zero terminator, also two bytes for the \r\n in
|
||||
* printWithLength, also couple of bytes just in case
|
||||
*/
|
||||
#define MAX_DL_CAPACITY (DL_OUTPUT_BUFFER - 5)
|
||||
|
||||
static log_buf_t pendingBuffers0 CCM_OPTIONAL;
|
||||
static log_buf_t pendingBuffers1;
|
||||
|
||||
/**
|
||||
* This is the buffer into which all the data providers write
|
||||
*/
|
||||
static char *accumulationBuffer;
|
||||
|
||||
/**
|
||||
* amount of data accumulated so far
|
||||
*/
|
||||
static uint32_t accumulatedSize;
|
||||
|
||||
/**
|
||||
* We copy all the pending data into this buffer once we are ready to push it out
|
||||
*/
|
||||
static char * outputBuffer;
|
||||
|
||||
static MemoryStream intermediateLoggingBuffer;
|
||||
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL;
|
||||
//todo define max-printf-buffer
|
||||
|
@ -224,7 +199,7 @@ static char header[16];
|
|||
/**
|
||||
* this method should invoked on the main thread only
|
||||
*/
|
||||
static void printWithLength(char *line) {
|
||||
void printWithLength(char *line) {
|
||||
/**
|
||||
* this is my way to detect serial port transmission errors
|
||||
* following code is functionally identical to
|
||||
|
@ -315,70 +290,12 @@ void scheduleMsg(Logging *logging, const char *fmt, ...) {
|
|||
}
|
||||
}
|
||||
|
||||
void scheduleLogging(Logging *logging) {
|
||||
// this could be done without locking
|
||||
int newLength = efiStrlen(logging->buffer);
|
||||
|
||||
bool alreadyLocked = lockOutputBuffer();
|
||||
if (accumulatedSize + newLength >= MAX_DL_CAPACITY) {
|
||||
/**
|
||||
* if no one is consuming the data we have to drop it
|
||||
* this happens in case of serial-over-USB, todo: find a better solution?
|
||||
*/
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
resetLogging(logging);
|
||||
return;
|
||||
}
|
||||
// memcpy is faster then strcpy because it is not looking for line terminator
|
||||
memcpy(accumulationBuffer + accumulatedSize, logging->buffer, newLength + 1);
|
||||
accumulatedSize += newLength;
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
resetLogging(logging);
|
||||
}
|
||||
|
||||
uint32_t remainingSize(Logging *logging) {
|
||||
return logging->bufferSize - loggingSize(logging);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method actually sends all the pending data to the communication layer.
|
||||
* This method is invoked by the main thread - that's the only thread which should be sending
|
||||
* actual data to console in order to avoid concurrent access to serial hardware.
|
||||
*/
|
||||
void printPending(void) {
|
||||
lockOutputBuffer();
|
||||
/**
|
||||
* we cannot output under syslock, we simply rotate which buffer is which
|
||||
*/
|
||||
char *temp = outputBuffer;
|
||||
|
||||
int expectedOutputSize = accumulatedSize;
|
||||
outputBuffer = accumulationBuffer;
|
||||
|
||||
accumulationBuffer = temp;
|
||||
accumulatedSize = 0;
|
||||
accumulationBuffer[0] = 0;
|
||||
|
||||
unlockOutputBuffer();
|
||||
|
||||
int actualOutputBuffer = efiStrlen(outputBuffer);
|
||||
efiAssertVoid(actualOutputBuffer == expectedOutputSize, "out constr");
|
||||
|
||||
if (actualOutputBuffer > 0) {
|
||||
printWithLength(outputBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void initIntermediateLoggingBuffer(void) {
|
||||
pendingBuffers0[0] = 0;
|
||||
pendingBuffers1[0] = 0;
|
||||
accumulationBuffer = pendingBuffers0;
|
||||
outputBuffer = pendingBuffers1;
|
||||
accumulatedSize = 0;
|
||||
initLoggingCentral();
|
||||
|
||||
msObjectInit(&intermediateLoggingBuffer, intermediateLoggingBufferData, INTERMEDIATE_LOGGING_BUFFER_SIZE, 0);
|
||||
intermediateLoggingBufferInited = TRUE;
|
||||
|
|
|
@ -44,18 +44,7 @@ public:
|
|||
char DEFAULT_BUFFER[200];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
bool lockOutputBuffer(void);
|
||||
void unlockOutputBuffer(void);
|
||||
|
||||
void initIntermediateLoggingBuffer(void);
|
||||
uint32_t remainingSize(Logging *logging);
|
||||
|
||||
#define loggingSize(logging) ((int) (logging)->linePointer - (int) ((logging)->buffer))
|
||||
|
||||
int isInitialized(Logging *logging);
|
||||
|
||||
|
@ -74,6 +63,20 @@ void appendMsgPostfix(Logging *logging);
|
|||
|
||||
void scheduleMsg(Logging *logging, const char *fmt, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
bool lockOutputBuffer(void);
|
||||
void unlockOutputBuffer(void);
|
||||
|
||||
uint32_t remainingSize(Logging *logging);
|
||||
|
||||
#define loggingSize(logging) ((int) (logging)->linePointer - (int) ((logging)->buffer))
|
||||
|
||||
|
||||
void printMsg(Logging *logging, const char *fmt, ...);
|
||||
void appendPrintf(Logging *logging, const char *fmt, ...);
|
||||
void vappendPrintf(Logging *logging, const char *fmt, va_list arg);
|
||||
|
@ -100,4 +103,6 @@ void printPending(void);
|
|||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void printWithLength(char *line);
|
||||
|
||||
#endif /* DATALOGGING_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file efilib.c
|
||||
* @file efilib.cpp
|
||||
*
|
||||
* We cannot use stdlib because we do not have malloc - so, we have to implement these functions
|
||||
*
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* @file loggingcentral.cpp
|
||||
*
|
||||
* @date Mar 8, 2015
|
||||
* @author Andrey Belomutskiy, (c) 2012-2015
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "efilib.h"
|
||||
|
||||
typedef char log_buf_t[DL_OUTPUT_BUFFER];
|
||||
|
||||
/**
|
||||
* we need to leave a byte for zero terminator, also two bytes for the \r\n in
|
||||
* printWithLength, also couple of bytes just in case
|
||||
*/
|
||||
#define MAX_DL_CAPACITY (DL_OUTPUT_BUFFER - 5)
|
||||
|
||||
/**
|
||||
* This is the buffer into which all the data providers write
|
||||
*/
|
||||
static char *accumulationBuffer;
|
||||
|
||||
static log_buf_t pendingBuffers0 CCM_OPTIONAL;
|
||||
static log_buf_t pendingBuffers1;
|
||||
|
||||
/**
|
||||
* amount of data accumulated so far
|
||||
*/
|
||||
static uint32_t accumulatedSize;
|
||||
|
||||
/**
|
||||
* We copy all the pending data into this buffer once we are ready to push it out
|
||||
*/
|
||||
static char * outputBuffer;
|
||||
|
||||
/**
|
||||
* This method appends the content of this thread-local logger into the global buffer
|
||||
* of logging content
|
||||
*/
|
||||
void scheduleLogging(Logging *logging) {
|
||||
// this could be done without locking
|
||||
int newLength = efiStrlen(logging->buffer);
|
||||
|
||||
bool alreadyLocked = lockOutputBuffer();
|
||||
if (accumulatedSize + newLength >= MAX_DL_CAPACITY) {
|
||||
/**
|
||||
* if no one is consuming the data we have to drop it
|
||||
* this happens in case of serial-over-USB, todo: find a better solution?
|
||||
*/
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
resetLogging(logging);
|
||||
return;
|
||||
}
|
||||
// memcpy is faster then strcpy because it is not looking for line terminator
|
||||
memcpy(accumulationBuffer + accumulatedSize, logging->buffer, newLength + 1);
|
||||
accumulatedSize += newLength;
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
resetLogging(logging);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method actually sends all the pending data to the communication layer.
|
||||
* This method is invoked by the main thread - that's the only thread which should be sending
|
||||
* actual data to console in order to avoid concurrent access to serial hardware.
|
||||
*/
|
||||
void printPending(void) {
|
||||
lockOutputBuffer();
|
||||
/**
|
||||
* we cannot output under syslock, we simply rotate which buffer is which
|
||||
*/
|
||||
char *temp = outputBuffer;
|
||||
|
||||
int expectedOutputSize = accumulatedSize;
|
||||
outputBuffer = accumulationBuffer;
|
||||
|
||||
accumulationBuffer = temp;
|
||||
accumulatedSize = 0;
|
||||
accumulationBuffer[0] = 0;
|
||||
|
||||
unlockOutputBuffer();
|
||||
|
||||
int actualOutputBuffer = efiStrlen(outputBuffer);
|
||||
efiAssertVoid(actualOutputBuffer == expectedOutputSize, "out constr");
|
||||
|
||||
if (actualOutputBuffer > 0) {
|
||||
printWithLength(outputBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void initLoggingCentral(void) {
|
||||
pendingBuffers0[0] = 0;
|
||||
pendingBuffers1[0] = 0;
|
||||
accumulationBuffer = pendingBuffers0;
|
||||
outputBuffer = pendingBuffers1;
|
||||
accumulatedSize = 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @file loggingcentral.h
|
||||
*
|
||||
* @date Mar 8, 2015
|
||||
* @author Andrey Belomutskiy, (c) 2012-2015
|
||||
*/
|
||||
#ifndef UTIL_LOGGINGCENTRAL_H_
|
||||
#define UTIL_LOGGINGCENTRAL_H_
|
||||
|
||||
void initLoggingCentral(void);
|
||||
|
||||
#endif /* UTIL_LOGGINGCENTRAL_H_ */
|
Loading…
Reference in New Issue