From 69c06b1b828fe44e8660daa8111d606ed6195d3f Mon Sep 17 00:00:00 2001 From: Epagris Date: Tue, 12 Aug 2025 09:20:57 +0200 Subject: [PATCH] - initial --- .clang-format | 245 +++++++++++++++++++++++++++++ .gitmodules | 3 + Inc/flexptp_options.h | 91 +++++++++++ Modules/flexPTP | 1 + Src/cli/cli.c | 355 ++++++++++++++++++++++++++++++++++++++++++ Src/cli/cli.h | 35 +++++ Src/cli/term_colors.h | 18 +++ fragments.txt | 33 ++++ ptp_config.cfg | 5 + 9 files changed, 786 insertions(+) create mode 100644 .clang-format create mode 100644 .gitmodules create mode 100644 Inc/flexptp_options.h create mode 160000 Modules/flexPTP create mode 100644 Src/cli/cli.c create mode 100644 Src/cli/cli.h create mode 100644 Src/cli/term_colors.h create mode 100644 fragments.txt create mode 100644 ptp_config.cfg diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..eb273fd --- /dev/null +++ b/.clang-format @@ -0,0 +1,245 @@ +--- +Language: Cpp +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e405c41 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Modules/flexPTP"] + path = Modules/flexPTP + url = https://github.com/epagris/flexPTP diff --git a/Inc/flexptp_options.h b/Inc/flexptp_options.h new file mode 100644 index 0000000..d2a9289 --- /dev/null +++ b/Inc/flexptp_options.h @@ -0,0 +1,91 @@ +#ifndef FLEXPTP_OPTIONS_H +#define FLEXPTP_OPTIONS_H + +// ------------------------------------------- +// ------ DEFINES FOR FLEXPTP SETTINGS ------- +// ------------------------------------------- + +#define FLEXPTP_LINUX +#define PTP_HLT_INTERFACE +#define PTP_HEARTBEAT_TICKRATE_MS (62) + +#define ANNOUNCE_COLLECTION_WINDOW (2) + +// ------------------------------------------- +// --- DEFINES FOR PORTING IMPLEMENTATION ---- +// ------------------------------------------- + +// Give a printf-like printing implementation MSG(...) +// Give a maskable printing implementation CLILOG(en,...) +// Provide an SPRINTF-implementation SPRINTF(str,n,fmt,...) + +#include + +#define MSG(...) printf(__VA_ARGS__) + +#define CLILOG(en, ...) \ + { \ + if (en) \ + printf(__VA_ARGS__); \ + } + +#define FLEXPTP_SNPRINTF(...) snprintf(__VA_ARGS__) + +// Include hardware port files and fill the defines below to port the PTP stack to a physical hardware: +// - PTP_HW_INIT(increment, addend): function initializing timestamping hardware +// - PTP_MAIN_OSCILLATOR_FREQ_HZ: clock frequency fed into the timestamp unit [Hz] +// - PTP_INCREMENT_NSEC: hardware clock increment [ns] +// - PTP_SET_ADDEND(addend): function writing hardware clock addend register + +#include + +extern char ptp_if_name[]; +#define PTP_HW_INIT() if (!linux_nsd_preinit(ptp_if_name)) { exit(0); } +#define PTP_SET_CLOCK(s, ns) linux_set_time((s), (ns)) +#define PTP_SET_TUNING(tuning_ppb) linux_adjust_clock(tuning_ppb) +#define PTP_HW_GET_TIME(pt) linux_get_time(pt) + +// Include the clock servo (controller) and define the following: +// - PTP_SERVO_INIT(): function initializing clock servo +// - PTP_SERVO_DEINIT(): function deinitializing clock servo +// - PTP_SERVO_RESET(): function reseting clock servo +// - PTP_SERVO_RUN(d): function running the servo, input: master-slave time difference (error), return: clock tuning value in PPB +// + +#include + +#define PTP_SERVO_INIT() kalman_filter_init() +#define PTP_SERVO_DEINIT() kalman_filter_deinit() +#define PTP_SERVO_RESET() kalman_filter_reset() +#define PTP_SERVO_RUN(d, pscd) kalman_filter_run(d, pscd) + +// Optionally add interactive, tokenizing CLI-support +// - CLI_REG_CMD(cmd_hintline,n_cmd,n_min_arg,cb): function for registering CLI-commands +// cmd_hintline: text line printed in the help beginning with the actual command, separated from help text by \t charaters +// n_cmd: number of tokens (words) the command consists of +// n_arg: minimal number of arguments must be passed with the command +// cb: callback function cb(const CliToken_Type *ppArgs, uint8_t argc) +// return: cmd id (can be null, if discarded) + +#include + +#define CLI_REG_CMD(cmd_hintline, n_cmd, n_min_arg, cb) cli_register_command(cmd_hintline, n_cmd, n_min_arg, cb) + +// ------------------------------------------- + +#define PTP_ENABLE_MASTER_OPERATION (1) // Enable or disable master operations + +// Static fields of the Announce message +#define PTP_CLOCK_PRIORITY1 (128) // priority1 (0-255) +#define PTP_CLOCK_PRIORITY2 (128) // priority2 (0-255) +#define PTP_BEST_CLOCK_CLASS (PTP_CC_DEFAULT) // best clock class of this device +#define PTP_WORST_ACCURACY (PTP_CA_UNKNOWN) // worst accuracy of the clock +#define PTP_TIME_SOURCE (PTP_TSRC_INTERNAL_OSCILLATOR) // source of the distributed time + +// ------------------------------------------- + +#include "flexptp/event.h" +extern void flexptp_user_event_cb(PtpUserEventCode uev); +#define PTP_USER_EVENT_CALLBACK flexptp_user_event_cb + +#endif //FLEXPTP_OPTIONS_H diff --git a/Modules/flexPTP b/Modules/flexPTP new file mode 160000 index 0000000..5ef4860 --- /dev/null +++ b/Modules/flexPTP @@ -0,0 +1 @@ +Subproject commit 5ef4860ba7df9b42583b1a0fe0bee54cc66e2202 diff --git a/Src/cli/cli.c b/Src/cli/cli.c new file mode 100644 index 0000000..470fb1c --- /dev/null +++ b/Src/cli/cli.c @@ -0,0 +1,355 @@ +#include "cli.h" + +#include "term_colors.h" + +#include +#include +#include +#include +#include +#include + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +// structure for defining cli commands +struct CliCommand { + CliToken_Type ppTok[MAX_TOKEN_N]; // tokens + uint8_t tokCnt; // number of tokens in command without arguments + uint8_t minArgCnt; // minimal number of parameters + char pHelp[MAX_HELP_LEN]; // help line + char *pHint; // pointer to the hint part of the command (allocated on pHelp) + uint8_t cmdLen; // length of the command string + char *pPadding; // padding between command and hint parts (allocated on pHelp) + fnCliCallback pCB; // processing callback function +}; + +#define CLI_MAX_CMD_CNT (48) // limit on number of separate commands +static struct CliCommand spCliCmds[CLI_MAX_CMD_CNT]; +static uint8_t sCliCmdCnt; +static bool sCmdsTidy = false; +static bool sInitialized = false; // CLI is initialized +static bool sRun = false; + +// --------------------------- + +// register and initialize task +void cli_init() { + // in the beginning there are no registered commands + sCliCmdCnt = 0; + + // CLI became initialized now! + sInitialized = true; +} + +// --------------------------- + +#define CLI_LINEBUF_LENGTH (191) +#define TOK_ARR_LEN (16) + +static void tokenize_cli_line(char *pLine, CliToken_Type ppTok[], uint32_t tokMaxLen, uint32_t tokMaxCnt, uint32_t *pTokCnt) { + uint32_t len = strlen(pLine); + + // copy to prevent modifying original one + static char pLineCpy[CLI_LINEBUF_LENGTH]; + strcpy(pLineCpy, pLine); + + *pTokCnt = 0; + + // prevent processing if input is empty + if (len == 0 || tokMaxCnt == 0) { + return; + } + + // first token + char *pTok = strtok(pLineCpy, " "); + strncpy(&ppTok[0][0], pTok, tokMaxLen); + (*pTokCnt)++; + + // further tokens + while ((*pTokCnt < tokMaxCnt) && (pTok != NULL)) { + pTok = strtok(NULL, " "); + + if (pTok != NULL) { + strncpy(&ppTok[*pTokCnt][0], pTok, tokMaxLen); // store token + (*pTokCnt)++; // increment processed token count + } + } +} + +#define HINT_DELIMITER ('\t') +#define MIN_GAP_IN_SPACES (3) +static uint32_t sHelpPadding = 0; + +static void tidy_format_commands() { + if (sCmdsTidy) { + return; + } + + // get maximal line length + uint32_t i, max_line_length = 0; + for (i = 0; i < sCliCmdCnt; i++) { + // fetch command descriptor + struct CliCommand *pCmd = &spCliCmds[i]; + + // if this command is unprocessed + if (pCmd->pHint == NULL) { + // search for hint text + char *pDelim = strchr(pCmd->pHelp, HINT_DELIMITER); + + if (pDelim == NULL) { + pCmd->cmdLen = strlen(pCmd->pHelp); // the whole line only contains the command, no hint + pCmd->pHint = pCmd->pHelp + pCmd->cmdLen; // make the hint point to the terminating zero + } else { + // calculate the length of the command part + pCmd->cmdLen = pDelim - pCmd->pHelp; + + // split help-line + *pDelim = '\0'; // get command part + pCmd->pHint = pDelim + 1; // get hint part + + // trim hint + while (*(pCmd->pHint) <= ' ') { + pCmd->pHint++; + } + + // allocate padding + pCmd->pPadding = pCmd->pHint + strlen(pCmd->pHint) + 1; + } + } + + // update max line length + max_line_length = MAX(max_line_length, pCmd->cmdLen); + } + + // fill-in paddings + for (i = 0; i < sCliCmdCnt; i++) { + // fetch command descriptor + struct CliCommand *pCmd = &spCliCmds[i]; + + // calculate padding length + uint8_t padLen = max_line_length - pCmd->cmdLen + MIN_GAP_IN_SPACES; + + // fill-in padding + for (uint32_t k = 0; k < padLen; k++) { + pCmd->pPadding[k] = ' '; + } + + // terminating zero + pCmd->pPadding[padLen] = '\0'; + } + + sCmdsTidy = true; + + // refresh help line padding + sHelpPadding = max_line_length - 1 + MIN_GAP_IN_SPACES; +} + +#define CLI_HISTORY_CMD "hist" + +void process_cli_line(char *pLine) { + CliToken_Type ppTok[TOK_ARR_LEN]; + uint32_t tokCnt = 0; + + // trim the input + size_t sz = strlen(pLine); + while ((sz > 0) && (isspace(pLine[sz - 1]))) { + pLine[sz - 1] = '\0'; + sz--; + } + + // tokenize line received from user input + tokenize_cli_line(pLine, ppTok, MAX_TOK_LEN, TOK_ARR_LEN, &tokCnt); + + if (tokCnt == 0) { + return; + } + + int ret = -1; + + // print help + if (!strcmp(ppTok[0], "?") || !strcmp(ppTok[0], "help")) { + // tidy-up help if not formatted yet + tidy_format_commands(); + + // ---- BUILT-IN commands ---- + + // print "?" + printf("\n\n" ANSI_COLOR_BYELLOW "?" ANSI_COLOR_CYAN "%*cPrint this help (%d/%d)" ANSI_COLOR_RESET "\n", sHelpPadding, ' ', sCliCmdCnt, CLI_MAX_CMD_CNT); + + // -------------- + + uint8_t i; + for (i = 0; i < sCliCmdCnt; i++) { + printf(ANSI_COLOR_BYELLOW "%s" ANSI_COLOR_RESET "%s" ANSI_COLOR_CYAN "%s" ANSI_COLOR_RESET "\n", + spCliCmds[i].pHelp, spCliCmds[i].pPadding, spCliCmds[i].pHint); + } + + printf("\n\n"); + + ret = 0; + } else { + // lookup command + uint8_t i, k = 0, matchCnt = 0; + int8_t n = -1; + for (i = 0; i < sCliCmdCnt; i++) { + matchCnt = 0; + + for (k = 0; k < spCliCmds[i].tokCnt && k < tokCnt; k++) { + if (strcmp(ppTok[k], spCliCmds[i].ppTok[k]) != 0) { + break; + } else { + matchCnt++; + if (matchCnt == spCliCmds[i].tokCnt) { + n = i; + break; + } + } + } + + if (n != -1) { + break; + } + } + + // call command callback function + if (n < 0) { + ret = -1; + } else { + struct CliCommand *pCmd = &spCliCmds[n]; + uint8_t argc = tokCnt - pCmd->tokCnt; + + if (argc < pCmd->minArgCnt) { + printf(ANSI_COLOR_BRED "Insufficient parameters, see help! (" ANSI_COLOR_BYELLOW "?" ANSI_COLOR_BRED ")\n" ANSI_COLOR_RESET); + } else { + ret = pCmd->pCB(&ppTok[pCmd->tokCnt], argc); + } + } + } + + if (ret < 0) { + printf(ANSI_COLOR_BRED "Unknown command or bad parameter: '" ANSI_COLOR_RESET "%s" ANSI_COLOR_BRED + "', see help! (" ANSI_COLOR_BYELLOW "?" ANSI_COLOR_BRED ")\n" ANSI_COLOR_RESET, + pLine); + } +} + +// task routine function +void cli_start() { + // CLI is running + sRun = true; + + // notify the world, that CLI is ON! + printf("Type '" ANSI_COLOR_BYELLOW "?" ANSI_COLOR_RESET "' to display help!\n"); + + int len; + char * lineBuf = NULL; + size_t lineLen = 0; + while (sRun) { + struct pollfd pfd = { .fd = STDIN_FILENO, POLLIN, 0, }; + int pret = poll(&pfd, 1, -1); + if (pret > 0) { + getline(&lineBuf, &lineLen, stdin); + process_cli_line(lineBuf); + } + } + free(lineBuf); +} + +int cli_register_command(char *pCmdParsHelp, uint8_t cmdTokCnt, + uint8_t minArgCnt, fnCliCallback pCB) { + // if command storage is full, then return -1; + if (sCliCmdCnt == CLI_MAX_CMD_CNT) { + return -1; + } + + // obtain pointer to first unused command space + struct CliCommand *pCmd = &spCliCmds[sCliCmdCnt]; + + // tokenize the first part of the line (run until cmkTokCnt tokens have been fetched) + uint32_t tokCnt = 0; + tokenize_cli_line(pCmdParsHelp, pCmd->ppTok, MAX_TOK_LEN, + (cmdTokCnt > TOK_ARR_LEN ? TOK_ARR_LEN : cmdTokCnt), &tokCnt); + pCmd->tokCnt = (uint8_t)tokCnt; + + // store minimal argument count parameter + pCmd->minArgCnt = minArgCnt; + + // copy help line + strncpy(pCmd->pHelp, pCmdParsHelp, MAX_HELP_LEN); + + // zero out hint part (tidy() will fill it) + pCmd->pHint = NULL; + + // store callback function pointer + pCmd->pCB = pCB; + + // increase the amount of commands stored + sCliCmdCnt++; + + // clean up if the same command registered before + uint8_t i, t; + int duplicate_idx = -1; + for (i = 0; i < (sCliCmdCnt - 1); i++) { + if (spCliCmds[i].tokCnt == cmdTokCnt) { + for (t = 0; t < cmdTokCnt; t++) { + if (strcmp(spCliCmds[i].ppTok[t], pCmd->ppTok[t])) { + break; + } + } + + if (t == cmdTokCnt) { + duplicate_idx = i; + break; + } + } + } + + if (duplicate_idx > -1) { + cli_remove_command(duplicate_idx); + } + + sCmdsTidy = false; // commands are untidy + + return sCliCmdCnt - 1; +} + +void cli_remove_command(int cmdIdx) { + if (cmdIdx + 1 > sCliCmdCnt || cmdIdx < 0) { + return; + } + + uint8_t i; + for (i = cmdIdx; i < sCliCmdCnt - 1; i++) { + memcpy(&spCliCmds[i], &spCliCmds[i + 1], sizeof(struct CliCommand)); + } + + sCliCmdCnt--; +} + +// removes a bunch of commands, terminated by -1 +void cli_remove_command_array(int *pCmdHandle) { + int *pIter = pCmdHandle; + while (*pIter != -1) { + cli_remove_command(*pIter); + pIter++; + } +} + +void cli_exit() { + sRun = false; +} + +// ----------------------- + +bool get_param_value(const CliToken_Type *ppArgs, uint8_t argc, + const char *pKey, char *pVal) { + size_t i; + for (i = 0; i < argc; i++) { + if (!strncmp(ppArgs[i], pKey, strlen(pKey))) { + strcpy(pVal, ppArgs[i] + strlen(pKey)); + return true; + } + } + return false; +} \ No newline at end of file diff --git a/Src/cli/cli.h b/Src/cli/cli.h new file mode 100644 index 0000000..62214ad --- /dev/null +++ b/Src/cli/cli.h @@ -0,0 +1,35 @@ +#ifndef FLEXPTP_LINUX_CLI_H +#define FLEXPTP_LINUX_CLI_H + +#include +#include +#include + +#define MAX_TOK_LEN (32) // maximal token length +#define TERMINAL_LEAD (">> ") // terminal lead + +typedef char CliToken_Type[MAX_TOK_LEN]; + +#define MAX_TOKEN_N (8) // maximal token count for a single command +#define MAX_HELP_LEN (192) // maximal help line length for a single command + +typedef int (*fnCliCallback)(const CliToken_Type *ppArgs, uint8_t argc); // function prototype for a callbacks + +void cli_init(); // initialize CLI +void cli_start(); // start CLI +void cli_exit(); // exit CLI + +void process_cli_line(char *pLine); // process input line +int cli_register_command(char *pCmdParsHelp, uint8_t cmdTokCnt, uint8_t minArgCnt, fnCliCallback pCB); // register a new command +void cli_remove_command(int cmdIdx); // remove an existing command +void cli_remove_command_array(int *pCmdHandle); // remove a bunch of commands, terminated by -1 + +void cli_print_hist_stk(); // print CLI history stack + +bool get_param_value(const CliToken_Type *ppArgs, uint8_t argc, const char *pKey, char *pVal); // get parameter value from a list of tokens + +#define CMD_FUNCTION(name) int(name)(const CliToken_Type *ppArgs, uint8_t argc) + +#define ONOFF(str) ((!strcmp(str, "on")) ? 1 : ((!strcmp(str, "off")) ? 0 : -1)) + +#endif // FLEXPTP_LINUX_CLI_H diff --git a/Src/cli/term_colors.h b/Src/cli/term_colors.h new file mode 100644 index 0000000..27438a1 --- /dev/null +++ b/Src/cli/term_colors.h @@ -0,0 +1,18 @@ +#ifndef FLEXPTP_LINUX_TERM_COLORS_H +#define FLEXPTP_LINUX_TERM_COLORS_H + +#define ANSI_ITALIC "\x1b[3m" + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_BRED "\x1b[91m" +#define ANSI_COLOR_GREEN "\x1b[32m" +#define ANSI_COLOR_BGREEN "\x1b[92m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_BYELLOW "\x1b[93m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_BMAGENTA "\x1b[95m" +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#endif // FLEXPTP_LINUX_TERM_COLORS_H diff --git a/fragments.txt b/fragments.txt new file mode 100644 index 0000000..8bfd89c --- /dev/null +++ b/fragments.txt @@ -0,0 +1,33 @@ +Some code segments that have not made (yet) into the application... + +// static int argc_; +// static char **argv_; + +// static struct option ptp_opts[] = { +// {"preset", required_argument, 0, 'P'}, +// {"slave_only", no_argument, 0, 's'}, +// {"priority1", required_argument, 0, 'p'}, +// {"priority2", required_argument, 0, 'q'}, +// {"transport_type", required_argument, 0, 'T'}, +// {"transport_specific", required_argument, 0, 'S'}, +// {"delay_mechanism", required_argument, 0, 'D'}, +// {"domain", required_argument, 0, 'd'}, +// {"log", required_argument, 0, 'l'}, +// {"tlv", required_argument, 0, 't'}, +// {"profile_flags", required_argument, 0, 'f'}, +// {"message_period", required_argument, 0, 'm'}, +// {"offset", required_argument, 0, 'o'}, +// {0}}; + +// void process_ptp_options(int argc, char **argv) { +// // get options +// int option_index = 0; +// int c = getopt_long(argc, argv, "i:sP:p:q:T:S:D:d:l:t:f:m:o:", ptp_opts, &option_index); +// switch (c) { +// case 'p': +// strncpy(ptp_if_name, optarg, IFNAMSIZ); +// break; +// default: +// break; +// } +// } \ No newline at end of file diff --git a/ptp_config.cfg b/ptp_config.cfg new file mode 100644 index 0000000..ba3cdf0 --- /dev/null +++ b/ptp_config.cfg @@ -0,0 +1,5 @@ +ptp profile +ptp priority 100 255 +ptp log def on +ptp log bmca on +ptp log info on \ No newline at end of file