I have made a preliminary port for qspy for zephyr and tested it with an NRF52832 board could you check it out if it works on your side? On my side it works, some packets are having errors but I suspect its because of it running at 115200 kbps, since I noticed that the transitions happen really fast (I suspect it could be a problem with the random timing generator (?) )
Attached as a text block is a patch the BSP of the zephyr DPP example, and in addition the Qspy sources must be enabled in the cmakelist.
diff --git a/examples/zephyr/dpp/src/bsp.cpp b/examples/zephyr/dpp/src/bsp.cpp
index 8b8a0b1..5f41518 100644
--- a/examples/zephyr/dpp/src/bsp.cpp
+++ b/examples/zephyr/dpp/src/bsp.cpp
@@ -33,6 +33,8 @@
#include "bsp.hpp"
#include <drivers/gpio.h>
+#include <drivers/uart.h>
+#include <sys/reboot.h>
// add other drivers if necessary...
// The devicetree node identifier for the "led0" alias.
@@ -135,7 +137,7 @@ void BSP::displayPhilStat(uint8_t n, char const *stat) {
else {
ledOff();
}
- printk("Philo[%d]->%s\n", n, stat);
+ //printk("Philo[%d]->%s\n", n, stat);
QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->m_prio) // app-specific record begin
QS_U8(1, n); // Philosopher number
@@ -179,25 +181,63 @@ namespace QP {
// QF callbacks ==============================================================
void QF::onStartup(void) {
k_timer_start(&QF_tick_timer, K_MSEC(1), K_MSEC(1));
- printk("QF::onStartup\n");
+ //printk("QF::onStartup\n");
}
//............................................................................
void QF::onCleanup(void) {
- printk("QF::onCleanup\n");
+ //printk("QF::onCleanup\n");
}
// QS callbacks ==============================================================
#ifdef Q_SPY
+static const struct device *uart_console_dev;
+
//............................................................................
+constexpr size_t qspy_stack_size = 2048;
+K_THREAD_STACK_DEFINE(qspy_stack, qspy_stack_size); /* stack storage */
+k_thread qspy_thread_handler;
+static void qspy_thread(void *p1, void *p2, void *p3){
+ while(1){
+ uint16_t len;
+ uint8_t const *buf = QS::getBlock(&len); // get continguous block of data
+ while (buf != nullptr) { // data available?
+ for(auto i = 0;i!=len;i++)
+ {
+ uart_poll_out(uart_console_dev,buf[i]);
+ }
+ len = 0xFFFFU; // big number to get as many bytes as available
+ buf = QS::getBlock(&len); // try to get more data
+ }
+ unsigned char in_char;
+ const int res = uart_poll_in(uart_console_dev,&in_char);
+ if(res==0)
+ {
+ QS::rxPut(in_char);
+ QS::rxParse();
+ }
+ }
+}
+
bool QS::onStartup(void const *arg) {
- static uint8_t qsTxBuf[2*1024]; // buffer for QS transmit channel
+ static uint8_t qsTxBuf[4*2048]; // buffer for QS transmit channel
static uint8_t qsRxBuf[100]; // buffer for QS receive channel
initBuf (qsTxBuf, sizeof(qsTxBuf));
rxInitBuf(qsRxBuf, sizeof(qsRxBuf));
-
- //TBD...
-
+ uart_console_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
+ //TODO assert if nullptr
+ k_thread_create(&qspy_thread_handler,
+ qspy_stack,
+ qspy_stack_size,
+ &qspy_thread,
+ nullptr, // p1
+ nullptr, // p2
+ nullptr, // p3
+ 14, // Zephyr priority */
+ K_ESSENTIAL, // thread options */
+ K_NO_WAIT); // start immediately */
+
+ //TODO assert if could not create thread
return true; // return success
}
//............................................................................
@@ -205,17 +245,25 @@ void QS::onCleanup(void) {
}
//............................................................................
QSTimeCtr QS::onGetTime(void) { // NOTE: invoked with interrupts DISABLED
- //TBD...
- return 0U;
+ return k_uptime_get_32();
}
//............................................................................
void QS::onFlush(void) {
- //TBD...
+ uint16_t len = 0xFFFFU; // big number to get as many bytes as available
+ uint8_t const *buf = QS::getBlock(&len); // get continguous block of data
+ while (buf != nullptr) { // data available?
+ for(auto i = 0;i!=len;i++)
+ {
+ uart_poll_out(uart_console_dev,buf[i]);
+ }
+ len = 0xFFFFU; // big number to get as many bytes as available
+ buf = QS::getBlock(&len); // try to get more data
+ }
}
//............................................................................
//! callback function to reset the target (to be implemented in the BSP)
void QS::onReset(void) {
- //???sys_reboot();
+ sys_reboot(SYS_REBOOT_COLD);
}
//............................................................................
//! callback function to execute a user command (to be implemented in BSP)