- initial
This commit is contained in:
commit
69c06b1b82
245
.clang-format
Normal file
245
.clang-format
Normal file
@ -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
|
||||||
|
...
|
||||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Modules/flexPTP"]
|
||||||
|
path = Modules/flexPTP
|
||||||
|
url = https://github.com/epagris/flexPTP
|
91
Inc/flexptp_options.h
Normal file
91
Inc/flexptp_options.h
Normal file
@ -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 <stdio.h>
|
||||||
|
|
||||||
|
#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 <flexptp/port/example_netstack_drivers/nsd_linux.h>
|
||||||
|
|
||||||
|
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 <flexptp/servo/kalman_filter.h>
|
||||||
|
|
||||||
|
#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 <cli/cli.h>
|
||||||
|
|
||||||
|
#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
|
1
Modules/flexPTP
Submodule
1
Modules/flexPTP
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 5ef4860ba7df9b42583b1a0fe0bee54cc66e2202
|
355
Src/cli/cli.c
Normal file
355
Src/cli/cli.c
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
#include "cli.h"
|
||||||
|
|
||||||
|
#include "term_colors.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
35
Src/cli/cli.h
Normal file
35
Src/cli/cli.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef FLEXPTP_LINUX_CLI_H
|
||||||
|
#define FLEXPTP_LINUX_CLI_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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
|
18
Src/cli/term_colors.h
Normal file
18
Src/cli/term_colors.h
Normal file
@ -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
|
33
fragments.txt
Normal file
33
fragments.txt
Normal file
@ -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;
|
||||||
|
// }
|
||||||
|
// }
|
5
ptp_config.cfg
Normal file
5
ptp_config.cfg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
ptp profile
|
||||||
|
ptp priority 100 255
|
||||||
|
ptp log def on
|
||||||
|
ptp log bmca on
|
||||||
|
ptp log info on
|
Loading…
x
Reference in New Issue
Block a user