Skip to content
This repository was archived by the owner on Aug 19, 2023. It is now read-only.

Commit 4faa6e8

Browse files
committed
Added Shell class and TerminalShell example
1 parent eb06534 commit 4faa6e8

File tree

13 files changed

+379
-26
lines changed

13 files changed

+379
-26
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
Arduino/libraries/hlink
3+
4+
Arduino/libraries/hlink.c

Arduino/libraries/Nexus_OS/Nexus_OS.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ namespace Nexus {
1212

1313
Event Message::None = Event(false);
1414

15+
const char Commands::help_name[] PROGMEM = "help";
16+
const char Commands::reset_name[] PROGMEM = "reset";
17+
const char Commands::tasks_name[] PROGMEM = "tasks";
18+
1519
}

Arduino/libraries/Nexus_OS/Nexus_OS.h

+9
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,27 @@
44

55
#include <Arduino.h>
66

7+
template<typename T, typename U>
8+
const T pgm_ptr(const U& addr)
9+
{
10+
return (const T)pgm_read_ptr(&addr);
11+
}
12+
713
#include "Nexus_OS/Nexus_Symbol.h"
814
#include "Nexus_OS/Nexus_Message.h"
915
#include "Nexus_OS/Nexus_Task.h"
1016
#include "Nexus_OS/Nexus_Scheduler.h"
1117
#include "Nexus_OS/Nexus_Terminal.h"
18+
#include "Nexus_OS/Nexus_Shell.h"
1219

1320
namespace Nexus {
1421

1522
extern class Scheduler Scheduler;
1623

1724
}
1825

26+
#include "Nexus_OS/Nexus_Commands.h"
27+
1928
/*
2029
2130
9 Bytes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//
2+
// Commands.h
3+
//
4+
5+
#include <Arduino.h>
6+
7+
#ifndef __Nexus_Commands__
8+
#define __Nexus_Commands__
9+
10+
namespace Nexus {
11+
12+
inline Stream& operator <<(Stream& stream, symbol symbol) {
13+
stream.print(symbol._string);
14+
15+
return stream;
16+
}
17+
18+
inline Stream& operator <<(Stream& stream, const void *pointer) {
19+
return stream.print((intptr_t)pointer), stream;
20+
}
21+
22+
inline Stream& operator <<(Stream& stream, Stream& (*func)(Stream&)) {
23+
return func(stream);
24+
}
25+
26+
inline Stream& endl(Stream& stream) {
27+
stream.print('\n');
28+
29+
return stream;
30+
}
31+
32+
struct Column {
33+
symbol sym;
34+
uint8_t width;
35+
};
36+
37+
inline Stream& operator <<(Stream& stream, const Column& column)
38+
{
39+
stream.print(column.sym);
40+
41+
for (int i = 0; i < column.width - column.sym.size(); ++i)
42+
stream.print(' ');
43+
44+
return stream;
45+
}
46+
47+
inline Column column(symbol symbol, uint8_t width)
48+
{
49+
Column column = { symbol, width };
50+
51+
return column;
52+
}
53+
54+
struct Commands {
55+
56+
static const char help_name[] PROGMEM;
57+
static const char reset_name[] PROGMEM;
58+
static const char tasks_name[] PROGMEM;
59+
60+
static Task *help(Task *parent)
61+
{
62+
Stream& stream = parent->getStream();
63+
64+
Shell *shell = static_cast<Shell *>(parent);
65+
66+
for (const Command *command = shell->getCommands(); pgm_ptr<void *>(command->name) != NULL; ++command)
67+
{
68+
const symbol name = pgm_ptr<const __FlashStringHelper *>(command->name);
69+
70+
stream << name << endl;
71+
}
72+
73+
return NULL;
74+
}
75+
76+
static Task *reset(Task *parent)
77+
{
78+
void (*reset)() = 0;
79+
80+
reset();
81+
82+
return NULL;
83+
}
84+
85+
static Task *tasks(Task *parent)
86+
{
87+
Stream& stream = parent->getStream();
88+
89+
for (Task *task = Scheduler.getTasks(); task != NULL; task = task->getNext())
90+
{
91+
// stream.print(task->getName());
92+
93+
// for (int i = 0; i < 16 - task->getName().size(); ++i)
94+
// stream.print(' ');
95+
96+
// stream.println((intptr_t)task);
97+
98+
stream << column(task->getName(), 16) << task << endl;
99+
}
100+
101+
return NULL;
102+
}
103+
104+
};
105+
106+
}
107+
108+
#endif

Arduino/libraries/Nexus_OS/Nexus_OS/Nexus_Scheduler.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace Nexus {
4747
// _tasks = newTask;
4848
// }
4949

50-
Task* getTasks() { return _tasks; }
50+
Task *getTasks() { return _tasks; }
5151

5252
void send(Task& task, const Message& message)
5353
{
@@ -82,7 +82,7 @@ namespace Nexus {
8282
else
8383
_tasks = (Task *)task->_next;
8484

85-
task = prev;
85+
if (prev) task = prev;
8686
}
8787
else prev = task;
8888
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//
2+
// Nexus_Shell.h
3+
//
4+
5+
namespace Nexus {
6+
7+
typedef Task *(*CommandThunk)(Task *parent);
8+
9+
struct Command {
10+
11+
//Command(const char * name, CommandThunk command) : name(name), command(command) { }
12+
13+
const char *name;
14+
CommandThunk command;
15+
16+
};
17+
18+
class Buffer {
19+
20+
public:
21+
22+
Buffer() : _index(0) { }
23+
24+
void push(char c)
25+
{
26+
_buffer[_index++] = c;
27+
}
28+
29+
const char *value()
30+
{
31+
_buffer[_index] = '\0';
32+
33+
return _buffer;
34+
}
35+
36+
void reset()
37+
{
38+
_index = 0;
39+
}
40+
41+
private:
42+
43+
char _buffer[30 + 1];
44+
uint8_t _index;
45+
46+
};
47+
48+
class Shell : public Task {
49+
50+
public:
51+
52+
Shell(const Command *commands) : Task(&TaskHelper<Shell>::run, F("Shell")),
53+
_commands(commands)
54+
{ }
55+
56+
const Command *getCommands() { return _commands; }
57+
58+
void run(const Message& message)
59+
{
60+
KeyEvent keyEvent; Task *task;
61+
62+
task_enter;
63+
64+
getStream().print(F("] "));
65+
66+
for (;;)
67+
{
68+
task_wait();
69+
70+
if (keyEvent = message.get<KeyEvent>())
71+
{
72+
switch (keyEvent.key)
73+
{
74+
break; case KeyEvent::KeyEnter:
75+
{
76+
getStream().print(F("\n"));
77+
78+
task = executeCommand(_buffer.value());
79+
80+
getStream().print(F("] "));
81+
}
82+
break; default:
83+
{
84+
insertCharacter(keyEvent.key);
85+
}
86+
}
87+
}
88+
}
89+
90+
task_exit;
91+
}
92+
93+
void insertCharacter(char c)
94+
{
95+
_buffer.push(c);
96+
97+
getStream().print(c);
98+
}
99+
100+
CommandThunk findCommand(const char *name)
101+
{
102+
for (const Command *command = _commands; pgm_ptr<void *>(command->name) != NULL; ++command)
103+
{
104+
//const char *commandName = (const char *)pgm_read_word(&command->name);
105+
const char *commandName = pgm_ptr<const char *>(command->name);
106+
const symbol commandName2 = pgm_ptr<const __FlashStringHelper *>(command->name);
107+
const CommandThunk thunk = (CommandThunk)pgm_read_word(&command->command);
108+
109+
if (commandName2 == name) return thunk;
110+
//if (strcmp_P(name, commandName) == 0) return thunk;
111+
//if (strcmp_P(name, command->name) == 0) return command->command;
112+
//if (command->name == name) return command->command;
113+
}
114+
115+
return NULL;
116+
}
117+
118+
Task *executeCommand(const char *name)
119+
{
120+
Task *task;
121+
122+
if (CommandThunk thunk = findCommand(name))
123+
{
124+
task = thunk(this);
125+
}
126+
else getStream().println(F("Command not found"));
127+
128+
_buffer.reset();
129+
130+
return NULL;
131+
}
132+
133+
private:
134+
135+
const Command* _commands;
136+
Buffer _buffer;
137+
138+
};
139+
140+
}

Arduino/libraries/Nexus_OS/Nexus_OS/Nexus_Symbol.h

+12-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,23 @@ namespace Nexus {
1717

1818
public:
1919

20+
friend Stream& operator <<(Stream& stream, symbol symbol);
21+
2022
symbol(const __FlashStringHelper *string) :
21-
_string(reinterpret_cast<const char *>(string))
23+
//_string(reinterpret_cast<const char *>(string))
24+
_string(string)
2225
{ }
2326

27+
//operator const char *() const { return _string; }
28+
operator const __FlashStringHelper *() const { return _string; }
29+
30+
uint8_t size() const { return strlen_P((const char *)_string); }
31+
32+
bool operator ==(const char *string) const { return strcmp_P(string, (const char *)_string) == 0; }
33+
2434
private:
2535

26-
const char *_string;
36+
const __FlashStringHelper *_string;
2737

2838
};
2939

Arduino/libraries/Nexus_OS/Nexus_OS/Nexus_Task.h

+9
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,18 @@ namespace Nexus {
9595
Task* getNext() { return static_cast<Task *>(Coro::getNext()); }
9696
Task* getParent() { return static_cast<Task *>(Coro::getNext()); }
9797

98+
symbol getName() { return _name; }
99+
98100
Terminal *getTerminal();
99101
Stream& getStream();
100102

103+
template<typename T1, typename T2>
104+
void println(T1 arg1, T2 arg2) {
105+
getStream().print(arg1);
106+
getStream().print(arg2);
107+
getStream().print('\n');
108+
}
109+
101110
protected:
102111

103112
const symbol _name;

Arduino/libraries/Nexus_OS/examples/Blink/Blink.ino

+1-8
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ class Blink : public Task {
1818

1919
pinMode(13, OUTPUT);
2020

21-
for (i = 0; i < 5; ++i)
21+
for (;;)
2222
{
2323
digitalWrite(13, HIGH);
24-
2524
task_sleep(500);
2625

2726
digitalWrite(13, LOW);
@@ -31,16 +30,10 @@ class Blink : public Task {
3130
task_exit;
3231
}
3332

34-
private:
35-
36-
uint8_t i;
37-
3833
};
3934

4035
void setup()
4136
{
42-
Serial.begin(9600);
43-
4437
Scheduler.addTask(new Blink());
4538
}
4639

0 commit comments

Comments
 (0)