Hi Charles, Thank you for your interest in the QSPY sequence diagram generation. Additionally, in the latest code base (v8.1.2), the QSEQ_genTran() function seems to have been removed. I'm not sure what you mean, and I cannot reproduce your problems. The sequence diagram generation feature is tested in every QSPY release, and it works in QSPY 8.1.2. I have attached the sequence diagrams generated by QSPY 8.1.2 from the latest QP/C and QP/C++. Has this feature been permanently removed from the regular...
Hi Charles, Thank you for your interest in the QSPY sequence diagram generation. Additionally, in the latest code base (v8.1.2), the QSEQ_genTran() function seems to have been removed. I'm not sure what you mean, and I cannot reproduce your problems. The sequence diagram generation feature is tested in every QSPY release, and it works in QSPY 8.1.2. I have attached the sequence diagrams generated by QSPY 8.1.2 from the latest QP/C and QP/C++. Has this feature been permanently removed from the regular...
Hi Charles, Thank you for your interest in the QSPY sequence diagram generation. Additionally, in the latest code base (v8.1.2), the QSEQ_genTran() function seems to have been removed. I'm not sure what you mean, and I cannot reproduce your problems. The sequence diagram generation feature is tested in every QSPY release, and it works in QSPY 8.1.2. Has this feature been permanently removed from the regular QP edition and only available in special editions (e.g., SafeQP)? No, the function QSEQ_genTran()...
Hi Lucca, Thank you for the interest in Spexygen. I’d like to ask whether the source of the official QP/C documentation is available... ...particularly the parts related to the Software Requirements Specification (SRS), Software Architecture Specification (SAS), and Software Design Specification (SDS). The documentation of the standard QP and SafeQP editions have been consolidated, and because SafeQP is not open source, the documentation sources are also not published. (Although the documentation...
Hi Philip, The "Boolean methods" you reference are called "guard conditions" or simply "guards" in the state machine lingo. I've made a dedicated video about "guard conditions": see #36 State Machines Part-2: Guard conditions. I've tried various things in QM but haven't quite nailed this. QM provides a very strong support for guard conditions, which are implemented with a higher-level concept of "choice segments". These "choice segments" can fan-out and nest. They can also have the complementary...
Hi Philip, The "Boolean methods" you reference are called "guard conditions" or simply "guards" in the state machine lingo. I've made a dedicated video about "guard conditions": see #36 State Machines Part-2: Guard conditions. I've tried various things in QM but haven't quite nailed this. QM provides a very strong support for guard conditions, which are implemented with a higher-level concept of "choice segments". These "choice segments" can fan-out and nest. They can also have the complementary...
Hi Steve, Thank you for your interest in QPC. The TMS320C28x DSP (a.k.a., C2000) is a real ancient story. It used to be supported in earlier versions of QP, but the support has been dropped due to the non-standard features of the CPU. If you search this forum, there is a recent discussion thread QP and QS to TI C2000 (a.k.a., TMS320C28x or C28x) with some potentially useful information. --MMS
Hi Steve, Thank you for your interest in QPC. The TMS320C28x DSP (a.k.a., C2000) is a real ancient story. It used to be supported in earlier versions of QP, but the support has been dropped due to the non-standard features of the CPU. If you search this forum, there is a recent discussion thread QP and QS to TI C2000 (a.k.a., C28x) with some potentially useful information. --MMS
Hi Lucca, Thank you for the interest in Spexygen. I’d like to ask whether the source of the official QP/C documentation is available... ...particularly the parts related to the Software Requirements Specification (SRS), Software Architecture Specification (SAS), and Software Design Specification (SDS). The documentation of the standard QP and SafeQP editions have been consolidated, and because SafeQP is not open source, the documentation sources are also not published. (Although the documentation...
Hi Lucca, Thank you for the interest in Spexygen. I’d like to ask whether the source of the official QP/C documentation is available... ...particularly the parts related to the Software Requirements Specification (SRS), Software Architecture Specification (SAS), and Software Design Specification (SDS). The documentation of the standard QP and SafeQP editions have been consolidated, and because SafeQP is not open source, the documentation sources are also not published. (Although the documentation...
Hi Philip, The "Boolean methods" you reference are called "guard conditions" or simply "guards" in the state machine lingo. I've made a dedicated video about "guard conditions": see #36 State Machines Part-2: Guard conditions. I've tried various things in QM but haven't quite nailed this. QM provides a very strong support for guard conditions, which are implemented with a higher-level concept of a "choice segment". These "choice segments" can fan-out and nest. They can also have the complementary...
Hi Bernardo, As Matthew Eshleman already suggested, you could dedicate one FreeRTOS thread to encapsulate the "blocking everywhere" approach used in FatFs. This should be probably a "naked" FreeRTOS thread, without an AO on top. Such a "naked" thread can produce QP events (by posting or publishing them to AOs). I'm not recommending using an AO for this because it will have to block (or poll), so its queue could overflow, etc. At the same time, I'm not quite sure how to send information to such a...
Hi Bernardo, As Matthew Eshleman already suggested, you could dedicate one FreeRTOS thread to encapsulate the "blocking everywhere" approach used in FatFs. This should be probably a "naked" FreeRTOS thread, without an AO on top. Such a "naked" thread can produce QP events (by posting or publishing them to AOs). I'm not recommending using an AO for this because it will have to block (or poll), so its queue could overflow, etc. At the same time, I'm not quite sure how to send information to such a...
Hi Charles, The two-pointer feature in QMPool I mentioned in my previous post works differently than you presume. Specifically, the second pointer is used only as the redundant "Duplicate Storage" and not for linking the free blocks. Then in qf_mem.c file, you can see invariants that exploit this redundancy (invariants 342 and 422). A good question is why the Duplicate Storage is not inverted, as usual? There are two reasons for that: First, it is desirable to distinguish between a free block and...
QTimeEvt_noActive() behaves incorrectly in QP/C/C++ 8.1.0
QTimeEvt_noActive() behaves incorrectly in QP/C/C++ 8.1.0
Hi Charles, The two-pointer feature in QMPool I mentioned in my previous post works differently than you presume. Specifically, the second pointer is used only as the redundant "Duplicate Storage" and not for linking the free blocks. Then in qf_mem.c file, you can see invariants that exploit this redundancy (invariants 342 and 422). A good question is why the Duplicate Storage is not inverted, as usual? There are two reasons for that: First, it is desirable to distinguish between a free block and...
Hi Charles, The two-pointer feature in QMPool I mentioned in my previous post works differently than you presume. Specifically, the second pointer is used only as the redundant "Duplicate Storage" and not for linking the free blocks. Then in qf_mem.c file, you can see invariants that exploit this redundancy (invariants 342 and 422). A good question is why the Duplicate Storage is not inverted, as usual? Well, it was inverted initially, but some users reported problems on MSP430 CPU (which is still...
Hi Charles, The two-pointer feature in QMPool I mentioned in my previous post works differently than you presume. Specifically, the second pointer is used only as the redundant "Duplicate Storage" and not for linking the free blocks. Then in qf_mem.c file, you can see invariants that exploit this redundancy (invariants 342 and 422). A good question is why the Duplicate Storage is not inverted, as usual? Well, it was inverted initially, but some users reported problems on MSP430 CPU (which is still...
Hi Charles, The two-pointer feature in QMPool I mentioned in my previous post works differently than you presume. Specifically, the second pointer is used only as the redundant "Duplicate Storage" and not for linking the free blocks. Then in qf_mem.c file, you can see invariants that exploit this redundancy (invariants 342 and 422). The good question is why the Duplicate Storage is not inverted, as usual? Well, it was inverted initially, but some users reported problems on MSP430 CPU (which is still...
Hi Charles, I'm glad that you took a detailed look into the QP 8.1.1 code. As you correctly concluded, the private QEvt.filler_ data member is not actually used anywhere in the code. However, it has been introduced for the following reasons: to void subtle semantic differences between the regular QP and SafeQP editions (this reason is given in the QP/C and QP/C++ online documentation); to make the minimum QEvt size equivalent to 2 pointers (at least on 32-bit CPUs); to avoid subtle semantic differences...
Hi Charles, I'm glad that you took a detailed look into the QP 8.1.1 code. As you correctly concluded, the private QEvt.filler_ data member is not actually used anywhere in the code. However, it has been introduced for the following reasons: to void subtle semantic differences between the regular QP and SafeQP editions (this reason is given in the QP/C and QP/C++ online documentation); to make the minimum QEvt size equivalent to 2 pointers (at least on 32-bit CPUs); to avoid subtle semantic differences...
Hi Charles, I'm glad that you took a detailed look into the QP 8.1.1 code. As you correctly concluded, the private QEvt.filler_ data member is not actually used anywhere in the code. However, it has been introduced for two reasons: - to void subtle semantic differences between the regular QP and SafeQP editions (this reason is given in the QP/C and QP/C++ online documentation); - to make the minimum QEvt size equivalent to 2 pointers (at least on 32-bit CPUs); - to avoid subtle semantic differences...
Hi Andrew, I'm glad to hear that you ported QP/C to rt-thread, but from my experience there are always some little details that might be incorrect even though "the basic AO functions run well". For example, here is a short list of questions to check: are you sure that you correctly use the critical section from rt-thread? are you using the correct event queue mechanism for the AOs? are you correctly translating the AO priority numbering scheme from QP to rt-thread when you start the AO (and create...
Hi Andrew, I'm glad to hear that you ported QP/C to rt-thread, but from my experience there are always some little details that might be incorrect even though "the basic AO functions run well". For example, here is a short list of questions to check: are you sure that you correctly use the critical section from rt-thread? are you using the correct event queue mechanism for the AOs? are you correctly translating the AO priority numbering scheme from QP to rt-thread when you start the AO (and create...
Hi Lucca, I've not used NASA's FRET in any real project and know only what I could read online. But from this, the FRET tool seems to be focused on formalizing the requirement specification by "restricting" natural language to make it more unambiguous, which reminds me of another tool called StrictDoc (see https://github.com/strictdoc-project/strictdoc ). The goals of Spexygen are different. Spexygen does not "restrict" your language, although it certainly enforces consistency of specifications....
Hi Lucca, I've not used NASA's FRET in any real project and know only what I could read online. But from this, the FRET tool seems to be focused on formalizing the requirement specification by "restricting" natural language to make it more unambiguous, which reminds me of another tool called StrictDoc (see https://github.com/strictdoc-project/strictdoc ). The goals of Spexygen are different. Spexygen does not "restrict" your language. Instead, Spexygen centers on one thing and one thing only: traceability,...
Hi Andrew, Yes, the directive $declare {VMod} generates the whole class VMod, which includes all class members: both data members and member functions. State-handler functions are member functions (they need the me instance pointer), so they are included. This is exactly as in C++, where a valid class declaration requires all members. But your problem is really not about the class declaration, but about encapsulation and information hiding. It seems to me that you're trying to go about it in the...
Hi Alex, As you can see in the supplied integration tests (directory qpcpp\examples\qutest\integration_tests) , they all use test-script commands like test, glb_filter, command, and expect. Here is a snippet from qpcpp\examples\qutest\integration_tests\test_qk\test_mpu.py: # preamble def on_reset(): expect_pause() # don't call continue_test() def on_setup(): glb_filter(GRP_SC, GRP_UA) MEM_START = 0 MEM_END = 1 # NULL-pointer dereferencing... test(''' NULL-read -> ASSERT ''') command("MEM_READ", 0x0,...
Hi Ramon, Thank you for the update. Your code could be helpful to other users of the C2000. The changes should apply to the newer QP 8.x. --MMS
Thank you for the update. Your code could be helpful for other users of the C2000. The changes should be applicable to the newer QP 8.x. --MMS
Hi alpu4, As I described earlier, integration tests are different than unit tests. The QS_TEST_PAUSE() macro is part of the QUTest "QP Stub", which supports unit testing, but is specifically not used during integration testing. In integration testing, you use the real kernel, so "QP Stub" is not available. At this stage, you should have already tested the startup sequence and state machine initialization, so there should be no need for QS_TEST_PAUSE(). A good way of thinking about it is that the...
Hi Ramon, The QS_onFlush() callback is entirely under your control, so you can do whatever you deem right in your specific application. If the physical QS output channel (CAN in your case) is not even connected, then most likely the missing QS dictionaries won't make a difference, would they? So, yes, in that case you could implement QS_onFlush() so that it gives up and returns after certain number of attempts. The consequences of not flushing the whole QS trace buffer are that you might overwrite...
Hi alpu4, I'm glad to hear that you were able to use the QUTest harness on real target hardware. That's a very good first step. But at this point, you need to decide what kind of testing you wish to perform. From your description, it seems that you have real interrupts, real peripheral (SPI), etc. To me this looks awfully like integration testing, not unit testing (where you would use the "QP Stub" included in QUTest). The good news is that QUTest is universal and can be used for integration testing....
Hi Harry, You can subclass QP::QTimeEvt and add to it more attributes. However, I don't see how the framework could modify such attributes when the time event is posted. I would just subclass QTimeEvt, add to it a unit8_t ID attribute. The constructor of such time-events could set the ID for each instance and then don't mess with it. Every time such time event shows up in the queue, you look at its ID attribute and dispatch it to the right passive HSM component. (If I remember correctly, all this...
Hi builder, I'm glad to hear that the newer STM32Cube was able to build the project successfully. The errors you saw earlier ("selected processor does not support mrs r0,PRIMASK in Thumb mode") suggests that the STM32Cube selected the wrong CPU type (seems like the obsolete ARM7TDMI or something, which had an earlier Thumb mode). --MMS
Hi builder, I'm glad to hear that the newer STM32Cube was able to build the project successfully. The errors you saw in the earlier ("selected processor does not support mrs r0,PRIMASK in Thumb mode") suggests that the STM32Cube selected the wrong CPU type (seems like the obsolete ARM7TDMI or something, which had an earlier Thumb mode). --MMS
Hi Ramon, The TI C28 (a.k.a. C2000) DSP used to be supported in QP many years ago. The old QP ports and examples, including the manuals, are still available as the "legacy-QDKs" (QP Development Kits): https://sourceforge.net/projects/qpc/files/legacy-QDKs/ (Look for qdkc_tms320c28x-c2000_4.5.03.zip and qdkcpp_tms320c28x-c2000_4.5.03.zip) As you noticed, the C2000 DSP cannot address 8-bit bytes, only 16-bit words. The consequence is that the standard integer type uin8_t is "approximated" and does...
Hi Ramon, The TI C28 (a.k.a. C2000) DSP used to be supported in QP many years ago. The old QP ports and examples, including the manuals, are still available as the "legacy-QDKs" (QP Development Kits): https://sourceforge.net/projects/qpc/files/legacy-QDKs/ (Look for qdkc_tms320c28x-c2000_4.5.03.zip and qdkcpp_tms320c28x-c2000_4.5.03.zip) As you noticed, the C2000 DSP cannot address 8-bit bytes, only 16-bit words. The consequence is that the standard integer type uin8_t is "approximated" and does...
Hi Ramon, The TI C28 (a.k.a. C2000) DSP used to be supported in QP many years ago. The old QP ports and examples, including the manuals, are still available as the "legacy-QDKs" (QP Development Kits): https://sourceforge.net/projects/qpc/files/legacy-QDKs/ (Look for qdkc_tms320c28x-c2000_4.5.03.zip and qdkcpp_tms320c28x-c2000_4.5.03.zip) As you noticed, the C2000 DSP cannot only address 8-bit bytes, only 16-bit words. The consequence is that the standard integer type uin8_t is "approximated" and...
Can I use QM 6.x.x with newest QPC ? Yes, as long as the code generated by this older QM compiles against the newer QP framework. can I just replace the qm folder of the new bundle installation with older qm ? You don't have to replace the QM. You can install the old QM alongside the existing one (of course you have to put it in a different directory, e.g., qm_6.2.3). You can install as many different QM versions as you like simultaneously on your machine. can i create new models which are compatible...
Can I use QM 6.x.x with newest QPC ? Yes, as long as the code generated by this older QM compiles against the newer QP framework. can I just replace the qm folder of the new bundle installation with older qm ? You don't have to replace the QM. You can install the old QM alongside the existing one (of course you have to put it in a different directory, e.g., qm_6.2.3). You can install as many different QM versions as you like simultaneously on your machine. can i create new models which are compatible...
Hi Todd, A QP/C port to ESP-IDF has been contributed at some point and was present up until QP/C version 7.3.3. It has been removed at QP/C version 7.3.4 because it was not tested at Quantum Leaps against any new changes. The problem with ESP32 support is that the Espressif ESP-IDF is/was based on a highly customized version of FreeRTOS, which was not compatible with the baseline FreeRTOS. (The official QP/C port to baseline FreeRTOS still exists and is supported). The Espressif modifications were...
Can I use QM 6.x.x with newest QPC ? Yes, as long as the code generated by this older QM compiles against the newer QP framework. can I just replace the qm folder of the new bundle installation with older qm ? You don't have to replace the QM. You can install the old QM alongside the existing one (of course you have to put it in a different directory, e.g., qm_6.2.3). You can install as many different QM versions as you like simultaneously on your machine. can i create new models which are compatible...
Can I use QM 6.x.x with newest QPC ? Yes, as long as the code generated by this older QM compiles against the newer QP framework. can I just replace the qm folder of the new bundle installation with older qm ? You don't have to replace the QM. You can install the old QM alongside the existing one (of course you have to put it in a different directory, e.g., qm_6.2.3). You can install as many different QM versions as you like simultaneously on your machine. can i create new models which are compatible...
Hi Irshad, Your recent problem with the 4 I/O channels (each having its own state machine) seems to be an ideal candidate for the "Orthogonal Component" state pattern, which was described in the PSiCC2 book several years ago. The standard QP examples directory contains several examples of the "Orthogonal Component" pattern. Among others, there is a "Dining Philosopher Problem" (DPP) version with Orthogonal Components. It is located in the directory: qpc/examples/posix-win32/dpp_comp. --MMS
Hi Irshad, Your recent problem with the 4 I/O channels (each having its own state machine) seems to be an ideal candidate for the "Orthogonal Component" state pattern, which was described in the PSiCC2 book several years ago. The standard QP examples directory contains several examples of the "Orthogonal Component" pattern. Among others, there is a "Dining Philosopher Problem" (DPP) version with Orthogonal Components. It is located in the directory: <qp>/examples/posix-win32/dpp_comp</qp>. --MMS
Hi Peter, If you're looking for ways to improve the existing QP state machine code and the QM tool, I had the following two ideas for a number of years. First, I like the text-to-diagram approach of the UMLet diagramming tool. I've attached an example, where on one side you see a diagram, and on the other its textual representation. UMLet allows you to draw in a standard way with a mouse, but you can also "draw" by editing the text (!). The idea is to adapt the tool to apply the syntax of QP code...
Hi Peter, Speaking of a textual representation of hierarchical state machines (a "state machine domain-specific language (DSL)"), the current QP implementation in C or C++ can be viewed as such a DSL. I have discussed this aspect in my YouTube video about the "Optimal State Machine Implementation". That video compares the QP state machine code to the State Machine Compiler (SMC), which is an example of a specifically invented DSL. My point is that the QP code is at least as succinct, readable, and...
Hi Peter, Speaking of a textual representation of hierarchical state machines (a "state machine domain-specific language (DSL)"), the current QP implementation in C or C++ can be viewed as such a DSL. I have discussed this aspect in my YouTube video about the "Optimal State Machine Implementation". That video compares the QP state machine code to the State Machine Compiler (SMC), which is an example of a specifically invented DSL. My point is that the QP code is at least as succinct, readable, and...
Hi Peter, I don't mind at all. If you believe that such an approach and tool would be useful, by all means, please try it! If you make it and wish to contribute, there is a special GitHub repo called contributed for such things. --MMS
Hi Phillip, As I tried to explain in my previous post, I think that dynamically stopping/starting Active Objects is problematic and most likely unsafe. For that reason, I'm reluctant to add/implement such a feature in the baseline QP (and certainly NOT in SafeQP editions). However, if you believe that such a feature could be useful, please add to the contributed features. There is a special public GitHub repo for such contributions. --MMS
Hi Phillip, As I tried to explain in my previous post, I think that dynamically stopping/starting Active Objects is problematic and most likely unsafe. For that reason, I'm reluctant to add/implement such a feature in the baseline QP (and certainly NOT in SafeQP editions). However, if you believe that such a feature could be useful, please add it as contributed features. There is a special public GitHub repo for such contributions. --MMS
Hi Phillip, As I tried to explain in my previous post, I think that dynamically stopping/starting Active Objects is problematic and most likely unsafe. For that reason I'm reluctant to add/implement such a feature in the baseline QP (and certainly NOT in SafeQP editions). However, if you believe that such a feature could be useful, please add it as contributed features. There is a special public GitHub repo for such contributions. --MMS
Hi Peter, I don't mind at all. If you believe that such an approach and tool would be useful, by all means, please try it! --MMS
Thanks a lot for your interest in the PSiCC2 book. The Windows executable for the "Fly 'n' Shoot" example stopped being distributed because some anti-virus software in the past reported problems with it. Instead, the example in the directory qpc\examples\qwin-gui\game-gui contains the Visual Studio solution game-gui.sln, which you can open, build, run, and debug in the free Visual Studio Community Edition. This is still available in the latest QP distribution: https://github.com/QuantumLeaps/qpc-examples/tree/74edeb4a7fcf9a704b2d605d8393ac39373b0706/qwin-gui/game-gui...
Thanks a lot for your interest in the PSiCC2 book. The Windows executable for the "Fly 'n' Shoot" example stopped being distributed because some anti-virus software in the past reported problems with it. Instead, the example in the directory qpc|qpcpp\examples\qwin-gui\game-gui contains the Visual Studio solution game-gui.sln, which you can open, build, run, and debug in the free Visual Studio Community Edition. --MMS
QM 7.0.1 tab title bug
Fixed in QM 7.0.2. --MMS
Fixed in QTOOLS / QUTest 8.1.1. --MMS
Tests following an unexpected assertion should start cleanly
Fixed in QTOOLS 8.1.1. --MMS
QPC 8.0.4 Nesting 5 levels can make AO become unresponsive
Thank you for the QM model. The problem is reproducible both in versions 8.0.4 and 8.1.0 (and perhaps older). With precisely 6 levels of state nesting (including the top state) an unhandled event causes the state machine to erroneously switch to the "top" state. Once in the "top" state the state machine ignores all events and so it becomes unresponsive. The fix is already made and tested and will be released in QP 8.1.1. --MMS
Thanks a lot for checking this in QP 8.1.0. Could you please attach your QM model? --MMS
Thanks a lot for reporting! Could you please check it in the latest QP 8.1.0? That version has specifically been redesigned for complete code coverage, which includes verifying all assertions. --MMS
The assertion/error handler Q_onError() is always called within a critical section. Therefore, calling portENTER_CRITICAL() inside Q_onError() is probably a mistake. --MMS
Hi Ramon, QP frameworks offer a virtual function QAsm::getStateHandler(), which returns the currently active state of a given state machine. This applies also to Active Objects, which are indirect subclasses of QAsm. Currently, the function QAsm::getStateHandler() is only available in the Spy build configuration (macro Q_SPY defined). The reason is that the returned QStateHandler is just an address of the state-handler function, which makes little sense outside a given state machine. This is fine...
Hi Ramon, QP offer a virtual function QAsm::getStateHandler(), which returns the currently active state of a given state machine. This applies also to Active Objects, which are indirect subclasses of QAsm. Currently, the function QAsm::getStateHandler() is only available in the Spy build configuration (macro Q_SPY defined). The reason is that the returned QStateHandler is just an address of the state-handler function, which makes little sense outside a given state machine. This is fine for QP/Spy,...
Hi Philip, Thank you for the feature request. The issues related to stopping Active Objects have been discussed in the Free Support Forum before. Stopping/terminating an Active Object is not that difficult. The tricky part is to do this cleanly, so that the application can safely continue. My recommendation is still NOT to stop/terminate an AO but instead use its state machine to change its behavior at runtime. If you don't need a particular AO for a while, trigger a transition to some "dormant"...
Yes, you'd need to create a struct or array and pass a pointer to this as the par initialization parameter to QActive::start(). Please note that this could be an automatic variable (on the stack) in the same function that then calls QActive::start() because start() synchronously calls the top-most initial transition. In order to avoid paying a permanent price for the initialization parameters (with stack space or static RAM), most standard examples use the function BSP::start() called from main(),...
Yes, you'd need to create a struct or array and pass a pointer to this as the par initialization parameter to QActive::start(). Please note that this could be an automatic variable (on the stack) in the same function that then calls QActive::start() because start() synchronously calls the top-most initial transition. In order to avoid paying a permanent price for the initialization parmeters (with stack space or static RAM), most standard examples use the function BSP::start() called from main(),...
Hi Harry, Of course, the QActive base class has no idea about your specific initialization parameters. But the whole point is that the par pointer you passed to QActive::start() ends up in your top-most initial transition. This is part of your specific state machine, where you deal with your specific QActive subclass, not with opaque AO pointer. Also, please note that the actual data pointed to by the par pointer can be different for every AO type. The decision how to interpret the data (how to cast...
Tests following an unexpected assertion should start cleanly
In QUTest 8.0.4 target tests following an assertion should not reset the target again
In QUTest 8.0.4 target tests following an assertion should not reset the target again
Fixed in QTools 8.0.4. --MMS
Here is the signature of the QActive::start() overload that I meant in my earlier comment: void QP::QActive::start(QPrioSpec const prioSpec, QEvtPtr *const qSto, std::uint_fast16_t const qLen, void *const stkSto, std::uint_fast16_t const stkSize, void const *const par); Specifically, the last parameter par is void const *const, so it can point to something in ROM without any type casting. I agree that it would be more elegant if it was a const reference. But this API is 20 years old now, and at the...
Here is the signature of the QActive::start() overload that I meant in my earlier comment: void QP::QActive::start(QPrioSpec const prioSpec, QEvtPtr *const qSto, std::uint_fast16_t const qLen, void *const stkSto, std::uint_fast16_t const stkSize, void const *const par); Specifically, the last parameter par is void const *const, so it can point to something in ROM without any type casting. I agree that it would be more elegant if it was a const reference. But this API is 20 years old now, and at the...
Hi Harry, AOs are typically statically allocated, so in C++ the constructors must run even before main(). Therefore, the AO constructor is typically not the best place to initialize some internal variables that depend on some "configuration" (data that is extracted after main() runs). So, a better place to do such initialization is the QActive::start() operation. And here, QP/C++ API specifically provides the last parameter (called "initialization event"), which can be a pointer to anything, not...
Hi Harry, AOs are typically statically allocated, so in C++ the constructors must run even before main(). Therefore, the AO constructor is typically not the best place to initialize some internal variables that depend on some "configuration" (data that is extracted after main() runs). So, a better place to do such initialization is the QActive::start() operation. And here, QP/C++ API specifically provides the last parameter (called "initialization event"), which can be a pointer to anything, not...
Which QSPY version are you using? The newest version (in QTools 8.1.0 as of this writing) has changed the object queries, please see the QTools release notes. It seems that this is precisely where you experience problems. As I said in my previous comment, the older QP (version 7.x) will best work with the matching QSPY/QView also of this vintage (version 7.x). --MMS
Hi Mike, Thank you for your interest in the QView monitoring system and for reporting the problem with lesson-46 and the TivaC board. Of course, your interests go beyond the main subject of lesson-46, which was the software tracing output (by means of a binary transfer protocol). The QView monitoring system requires more than that, because it also requires the input to be handled by the target. The QS software tracing system supports both, and both are configured in lesson-46 (the file bsp.c). However...
In QUTest 8.0.4 target tests following an assertion should not reset the target again
QUTest 8.0.1 leaks host executable in failing tests that also trigger an assertion
Fixed in QTools 8.0.4 (qutest.py 8.0.4). --MMS
QM 7.0.1 tab title bug
The bug (wrong title on the tab and the main QM title bar) when a sub-window is closed and re-opened. It will be fixed in the next QM 7.0.2. --MMS
QM tab text bug
Hi Daniel, Thank you for your interest in the "Modern Embedded Systems Programming" video course. The newer startup code for the TivaC MCU relocates the Vector Table from address 0x0 to 0x100. This is done to allow detecting NULL-pointer dereferencing. The rationale is explained in my blog post: "NULL pointer protection with ARM Cortex-M MPU". The short summary is that the older ARM MCUs (like the TM4C) use address 0x0 for the VT, which overlaps with the NULL-pointer region. Newer MCUs (like STM32)...
Hi Luca, It seems to me that you are using the FreeRTOS port with the MPU, whereas the current official QP port to FreeRTOS does not take the MPU and privilege levels into account. This is relevant because there is probably no protection against one Active Object accessing another Active Object's internal data. So, your "protection" is quite limited... Also, the whole MPU use in FreeRTOS specifically has many flaws, as described in the paper "Good Motive but Bad Design: Why ARM MPU Has Become an...
Hi Luca, It seems to me that you are using the FreeRTOS port with the MPU, whereas the current official QP port to FreeRTOS does not take the MPU and privilege levels into account. This is relevant because there is probably no protection against one Active Object accessing another Active Object's internal data. So, your "protection" is quite limited... Also, the whole MPU use in FreeRTOS specifically has many flaws, as described in the paper "Good Motive but Bad Design: Why ARM MPU Has Become an...
Hi Andrew, Porting QP to an RTOS is not trivial, not because QP is overly complex, but because RTOS mechanisms are surprisingly tricky to use correctly. QP merely exposes the RTOS facilities that event-driven programming paradigm requires. For example, often in publish-subscribe events are subscribed by more than one Active Object (RTOS thread). This requires event multicasting, but if publishing happens in a low-priority Active Object, the RTOS scheduler must be locked (otherwise the AO will be...
Hi Andrew, Porting QP to an RTOS is not trivial, not because QP is overly complex, but because RTOS mechanisms are surprisingly tricky to use correctly. QP merely exposes the RTOS facilities that event-driven programming paradigm requires. For example, often in publish-subscribe events are subscribed by more than one Active Object (RTOS thread). This requires event multicasting, but if publishing happens in a low-power Active Object, the RTOS scheduler must be locked (otherwise the AO will be immediately...
Isn't this an issue of collecting all "votes" from your Orthogonal Components? I mean, you don't care for the order of the OC_READY_EVENTs. In fact, these are all the same events (at least with the same signal), so it's hard to talk about different order or all possible combinations of such events. I would design this as follows: Each Component would post the OC_ON_EVENT to the Container Active Object in the entry action to the "CONTACTOR_ON" state and OC_OFF_EVENT in the entry action to the "CONTACTOR_OFF"...
Isn't this an issue of collecting all "votes" from your Orthogonal Components? I mean, you don't care for the order and all possible combinations of the OC_READY_EVENTs. In fact, these are all the same events (at least with the same signal), so it's hard to talk about different order of such events. I would design this as follows: Each Component would post the OC_ON_EVENT to the Container Active Object in the entry action to the "CONTACTOR_ON" state and OC_OFF_EVENT in the entry action to the "CONTACTOR_OFF"...
Isn't this an issue of collecting all "votes" from your Orthogonal Components? I mean, you don't care for the order and all possible combinations of the OC_READY_EVENTs. In fact, these are all the same events (at least with the same signal), so it's hard to talk about different order of such events. I would design this as follows: Each Component would post the OC_ON_EVENT to the Container Active Object in the entry action to the "CONTACTOR_ON" state and OC_OFF_EVENT in the entry action to the "CONTACTOR_OFF"...
Hi Roman, I've changed the title of this discussion thread to "Designing state machines to handle multiple event sequences" because I believe it reflects better your question. My main concern with the second approach (event storage) is that it requires adding flags or state variables I'm not sure what "event storage" is, but if this is your first diagram then it is not very good. Do you have any recommendations or examples of best practices for handling this type of situation? Yes. Generally, it...
Hi Roman, I've changed the title of this discussion thread to "Designing state machines to handle multiple event sequences" because I believe it reflects better your question. My main concern with the second approach (event storage) is that it requires adding flags or state variables I'm not sure what "event storage" is, but if this is your first diagram then it is not very good. Do you have any recommendations or examples of best practices for handling this type of situation? Yes. Generally, it...