Skip to content

Commit 99cc56b

Browse files
committed
Changed pru interface to support halting and restarting
1 parent 17baad1 commit 99cc56b

5 files changed

+47
-24
lines changed

src/motion-queue.h

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class PRUMotionQueue final : public MotionQueue {
148148
bool Init();
149149

150150
void ClearPRUAbort(unsigned int idx);
151+
void ClearRingBuffer();
151152

152153
HardwareMapping *const hardware_mapping_;
153154
PruHardwareInterface *const pru_interface_;

src/pru-hardware-interface.h

+9
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ class PruHardwareInterface {
4242

4343
// Halt the PRU
4444
virtual bool Shutdown() = 0;
45+
46+
// Halt any program execution. An halted program can be restarted.
47+
virtual void Halt() = 0;
48+
49+
// Restart the execution of the previously halted program.
50+
virtual void Restart() = 0;
51+
4552
};
4653

4754
class UioPrussInterface : public PruHardwareInterface {
@@ -51,6 +58,8 @@ class UioPrussInterface : public PruHardwareInterface {
5158
bool StartExecution() final;
5259
unsigned WaitEvent() final;
5360
bool Shutdown() final;
61+
void Halt() final;
62+
void Restart() final;
5463
};
5564

5665
#endif // BEAGLEG_PRU_HARDWARE_INTERFACE_

src/pru-motion-queue.cc

+13-7
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,12 @@ void PRUMotionQueue::Shutdown(bool flush_queue) {
178178
}
179179

180180
bool PRUMotionQueue::Clear() {
181-
pru_interface_->Shutdown();
182-
return Init();
181+
MotorEnable(false);
182+
pru_interface_->Halt();
183+
ClearRingBuffer();
184+
queue_pos_ = 0;
185+
pru_interface_->Restart();
186+
return true;
183187
}
184188

185189
PRUMotionQueue::~PRUMotionQueue() {}
@@ -192,18 +196,20 @@ PRUMotionQueue::PRUMotionQueue(HardwareMapping *hw, PruHardwareInterface *pru)
192196
assert(success);
193197
}
194198

199+
void PRUMotionQueue::ClearRingBuffer() {
200+
for (int i = 0; i < QUEUE_LEN; ++i) {
201+
pru_data_->ring_buffer[i].state = STATE_EMPTY;
202+
}
203+
}
204+
195205
bool PRUMotionQueue::Init() {
196206
MotorEnable(false); // motors off initially.
197207
if (!pru_interface_->Init()) return false;
198208

199209
if (!pru_interface_->AllocateSharedMem((void **)&pru_data_,
200210
sizeof(*pru_data_)))
201211
return false;
202-
203-
for (int i = 0; i < QUEUE_LEN; ++i) {
204-
pru_data_->ring_buffer[i].state = STATE_EMPTY;
205-
}
212+
ClearRingBuffer();
206213
queue_pos_ = 0;
207-
208214
return pru_interface_->StartExecution();
209215
}

src/pru-motion-queue_test.cc

+16-17
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
#include "pru-hardware-interface.h"
1919
#include "segment-queue.h"
2020

21-
using ::testing::NiceMock;
22-
2321
// PRU-side mock implementation of the ring buffer.
2422
struct MockPRUCommunication {
2523
internal::QueueStatus status;
@@ -30,15 +28,16 @@ class MockPRUInterface : public PruHardwareInterface {
3028
public:
3129
MockPRUInterface() : execution_index_(QUEUE_LEN - 1) {
3230
mmap = NULL;
33-
ON_CALL(*this, Init).WillByDefault([]() { return true; });
34-
ON_CALL(*this, Shutdown).WillByDefault([]() { return true; });
3531
}
3632
~MockPRUInterface() override { free(mmap); }
3733

34+
bool Init() final { return true; }
3835
bool StartExecution() final { return true; }
3936
unsigned WaitEvent() final { return 1; }
40-
MOCK_METHOD(bool, Init, (), ());
41-
MOCK_METHOD(bool, Shutdown, (), ());
37+
bool Shutdown() final { return true; }
38+
39+
MOCK_METHOD(void, Halt, (), (final));
40+
MOCK_METHOD(void, Restart, (), (final));
4241

4342
bool AllocateSharedMem(void **pru_mmap, const size_t size) final {
4443
if (mmap != NULL) return true;
@@ -70,15 +69,15 @@ class MockPRUInterface : public PruHardwareInterface {
7069

7170
TEST(PruMotionQueue, status_init) {
7271
MotorsRegister absolute_pos_loops;
73-
NiceMock<MockPRUInterface> pru_interface;
72+
MockPRUInterface pru_interface;
7473
HardwareMapping hmap = HardwareMapping();
7574
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
7675
EXPECT_EQ(motion_backend.GetPendingElements(NULL), 0);
7776
}
7877

7978
TEST(PruMotionQueue, single_exec) {
8079
MotorsRegister absolute_pos_loops;
81-
NiceMock<MockPRUInterface> pru_interface;
80+
MockPRUInterface pru_interface;
8281
HardwareMapping hmap = HardwareMapping();
8382
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
8483

@@ -91,7 +90,7 @@ TEST(PruMotionQueue, single_exec) {
9190

9291
TEST(PruMotionQueue, full_exec) {
9392
MotorsRegister absolute_pos_loops;
94-
NiceMock<MockPRUInterface> pru_interface;
93+
MockPRUInterface pru_interface;
9594
HardwareMapping hmap = HardwareMapping();
9695
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
9796

@@ -104,7 +103,7 @@ TEST(PruMotionQueue, full_exec) {
104103

105104
TEST(PruMotionQueue, single_exec_some_loops) {
106105
MotorsRegister absolute_pos_loops;
107-
NiceMock<MockPRUInterface> pru_interface;
106+
MockPRUInterface pru_interface;
108107
HardwareMapping hmap = HardwareMapping();
109108
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
110109

@@ -119,7 +118,7 @@ TEST(PruMotionQueue, single_exec_some_loops) {
119118

120119
TEST(PruMotionQueue, one_round_queue) {
121120
MotorsRegister absolute_pos_loops;
122-
NiceMock<MockPRUInterface> pru_interface;
121+
MockPRUInterface pru_interface;
123122
HardwareMapping hmap = HardwareMapping();
124123
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
125124

@@ -141,7 +140,7 @@ TEST(PruMotionQueue, one_round_queue) {
141140
// Check the PRU is reset and no elements are pending.
142141
TEST(PruMotionQueue, clear_queue) {
143142
MotorsRegister absolute_pos_loops;
144-
NiceMock<MockPRUInterface> pru_interface;
143+
MockPRUInterface pru_interface;
145144
HardwareMapping hmap = HardwareMapping();
146145
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
147146

@@ -157,18 +156,18 @@ TEST(PruMotionQueue, clear_queue) {
157156
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&pru_interface));
158157
{
159158
testing::InSequence seq;
160-
EXPECT_CALL(pru_interface, Shutdown())
161-
.Times(1)
162-
.WillRepeatedly(testing::Return(true));
163-
EXPECT_CALL(pru_interface, Init()).Times(1).WillOnce(testing::Return(true));
159+
EXPECT_CALL(pru_interface, Halt())
160+
.Times(1);
161+
EXPECT_CALL(pru_interface, Restart())
162+
.Times(1);
164163
}
165164
EXPECT_TRUE(motion_backend.Clear());
166165
EXPECT_EQ(motion_backend.GetPendingElements(NULL), 0);
167166
}
168167

169168
TEST(PruMotionQueue, exec_index_lt_queue_pos) {
170169
MotorsRegister absolute_pos_loops;
171-
NiceMock<MockPRUInterface> pru_interface;
170+
MockPRUInterface pru_interface;
172171
HardwareMapping hmap = HardwareMapping();
173172
PRUMotionQueue motion_backend(&hmap, (PruHardwareInterface *)&pru_interface);
174173

src/uio-pruss-interface.cc

+8
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ unsigned UioPrussInterface::WaitEvent() {
8484
return num_events;
8585
}
8686

87+
void UioPrussInterface::Halt() {
88+
prussdrv_pru_disable(PRU_NUM);
89+
}
90+
91+
void UioPrussInterface::Restart() {
92+
prussdrv_pru_enable_at(PRU_NUM, 0);
93+
}
94+
8795
bool UioPrussInterface::Shutdown() {
8896
prussdrv_pru_disable(PRU_NUM);
8997
prussdrv_exit();

0 commit comments

Comments
 (0)