Compilation error in QM generated code (expected QP version)
The compilation error indicates an incompatible (too old) QP version for this QM release. The possible options to avoid this problem are: update the QP framework you use in your application to the required QP 8.0.0 or newer; or use an older version of QM, which is compatible with your older QP. Question: which QP version is used in your example? --MMS
Race condition in QActive::postx_ violates margin guarantee, redundant critical section enter/exit causing performance overhead
Race condition in QActive::postx_ violates margin guarantee, redundant critical section enter/exit causing performance overhead
postx_() in FreeRTOS port enters critical section twice in QP 8.1.3
The issue is fixed in QP/C and QP/C++ 8.1.4. --MMS
#Include error with the Blinky tutorial
Thank you for reporting. The QM Tutorial online has been updated and should work now. The model templates that ship with QM 7.0.3 are checked to be correct. The documentation update should be all that's required to fix this issue, but please confirm so that the bug can be closed. --MMS
#Include error with the Blinky tutorial
postx_() in FreeRTOS port enters critical section twice in QP 8.1.3
8.1.3 postx_() in FreeRTOS port enters critical section twice
8.1.3 postx_() in FreeRTOS port enters critical section twice
8.1.3 postx_ enters critical section twice
Hi Mike, I change hist_lidClosed = &Washer_ready... I don't know if this can be a problem,... It looks like a problem to me because this is very confusing and does not really model the reality. Your job is not to "cheat" (to make it "work" in this particular stage of your modeling), but to capture the true essence of the behavior. Also, I'm not sure if I understand your use of state hierarchy. For example, the OPEN transition should be directly from the "lidClosed" to "lidOpen". Your current model...
Hi Mr Samek! I love your video course and book, and have enjoyed learning so much!! About OFF closing the door in my fix, I did notice that was a problem. Using your suggestion of OFF just being an internal transition, in it I thought of explicitly changing me->hist_doorClosed = &ToastOven_off so it will stay off after closing the door. I did what you suggested to experiment but used a washing machine which is similar, and ran into the same thing: In lidOpen:CANCEL, I change hist_lidClosed = &Washer_ready....
Hi Mr Samek! I love your video course and book, and have enjoyed learning so much!! About OFF closing the door in my fix, I did notice that was a problem. Using your suggestion of OFF just being an internal transition, in it I thought of explicitly changing me->hist_doorClosed = &ToastOven_off so it will stay off after closing the door. I did what you suggested to experiment but used a washing machine which is similar, and ran into the same thing: In lidOpen:CANCEL, I change hist_lidClosed = &Washer_ready....
Hi Mr Samek! I love your video course and book, and have enjoyed learning so much!! About OFF closing the door in my fix, I did notice that was a problem. Using your suggestion of OFF just being an internal transition, in it I thought of explicitly changing me->hist_doorClosed = &ToastOven_off so it will stay off after closing the door. I did what you suggested to experiment but used a washing machine which is similar, and ran into the same thing: In lidOpen:CANCEL, I change hist_lidClosed = &Washer_ready....
Hi Mike, Thanks a lot for your interest and attention to detail. Indeed, the details of the "history" example have changed over the years to demonstrate both types of history (shallow and deep, see attached state diagram). And you are right; these changes made the ToasterOven behave in a way that a real appliance should not behave (the oven should never turn on after pressing OFF). You have several options to fix that: Your choice to make the doorOpen:OFF transition go straight to the "off" state...
Hi Mike, Thanks a lot for your interest and attention to detail. Indeed, the details of the "history" example have changed over the years to demonstrate both types of history (shallow and deep, see attached state machine, see attached state diagram). And you are right; these changes made the ToasterOven behave in a way that a real appliance should not behave (the oven should never turn on after pressing OFF). You have several options to fix that: Your choice to make the doorOpen:OFF transition go...
I know this is almost 3 years old but I saw the same problem. It didn't make any sense that if the toaster if off that it should be turned on simply by opening and closing the door. It should stay off. My fix: Signal OFF from the doorOpen state should just transition directly to the off state in doorClosed (not using history). Signal CLOSE in doorOpen transitions to history (placed on doorClosed not heating, and is not shallow).
Hi fellas, Great topic! :D https://doorstop.readthedocs.io/ (not IBM's product; this is 100% FLOSS , git-friendly, actively maintained) Cheers
Hi Mark, As a commercial licensee, please contact Quantum Leaps support (support@state-machine.com) for the QSPY source code. --MMS
We use qspy on a Raspberry Pi and have always built a Linux binary for arm64 for this purpose. Up until qtools version 7.4.1, the complete source code for building qspy was available. Since version 8, it is no longer publicly available. Would it therefore please be possible to publish a linux binary for arm64 in addition to the x86_64 linux binary?
Makes sense. Thanks!
Hi Modo, Your 10-step plan sounds a bit complicated. It seems that you prefer the very traditional code partitioning, so just do that. Specifically, instead of manually "removing the delimit portions that QM controls", just generate the traditional header files (.h/.hpp) with your class declarations ( $declare {} directives). Then simply include those QM-generated headers in your external source files (.cpp). QM doesn't need to "know" about those source files at all, so you can manage them completely...
Hi Modo, Your 10-step plan sounds a bit complicated. It seems that you prefer the very traditional code partitioning, so just do that. Specifically, instead of manually "removing the delimit portions that QM controls", just generate the traditional header files (.h/.hpp) with your class declarations ( $declare {} directives). Then simply include those QM-generated headers in your external source files (.cpp). QM doesn't need to "know" about those source files at all, so you can manage them completely...
Hi Miro, Thank you for the quick response! This answer gave me further insight to the flexibility/functionality of QM. My team and I are looking to see how the development process using outside IDEs (notepad++/vscode) would "feel" To give an example, this would be look for QM using QPCPP. Create an operation (or set of operations) with parameter(s) for a class, but leave the code portion blank. Create an external file to capture functions that belong to said class. In the external file, use the generative...
Hi Modo, QM allows you to organize your code any way you see fit (see QM code engineering philosophy). Consequently, you can implement all/most/some actions and/or guards on your state machines as (member) functions of your state machine class. You can then implement those functions in any number of files: completely outside QM or within QM as regular files or external files. If the implementation files are outside QM, they won't be obviously overwritten when QM re-generates code. If the files are...
solved! Decided to just do it the way suggested by the link I posted. Thanks!
I do enjoy the convenience of the code generation abilities of QM. I'm wondering if it's possible to have QM stub out functions on external files, then on those external files add the code, and upon further generation (maybe adding another function or something) the code written within the function is not overwritten. Thanks!
Hi, thank you so much for the detailed explanation! I have to say, I really liked the “dining philosophers” analogy — I hadn’t even thought about applying the DPP pattern to my scenario, but it actually makes perfect sense here! Definitely a clever way to coordinate access to the shared resource. Thanks a lot for the insight and for pointing me in the right direction! 🙌 Giulio
Hi Giulio, First, let me clarify that if your sensors can permanently overwhelm your communication bandwidth (RS-485 in your case), no software design is going to fix it. Unfortunately, even QP cannot pull off such magic. Now, your problem seems to me two-fold. First, you worry about event pools, meaning that you have a buffering problem. Second, you think about coordinating the sensor components, which is a coordination problem. Regarding coordination, your SensorManager seems to be the ideal candidate....
Hi Giulio, First, let me clarify that if your sensors can permanently overwhelm your communication bandwidth (RS-485 in your case), no software design is going to fix it. Unfortunately, even QP cannot pull off such magic. Now, your problem seems to me two-fold. First, you worry about event pools, meaning that you have a buffering problem. Second, you think about coordinating the sensor components, which is a coordination problem. Regarding coordination, your SensorManager seems to be the ideal candidate....
Hi everyone, I’d like your advice on an architectural issue. I have 40 “sensors” connected over an RS‑485 bus. For each sensor I have an orthogonal state machine inside a dedicated AO (let’s call it SensorManager). I also have a separate AO responsible for managing the RS‑485 serial interface. The problem: Each of the 40 sensor state machines may need to send a Modbus request, which means they would post an event to the AO that handles the serial line. However, I cannot allow all 40 sensors to request...
here is version
Manage External Tools Parser Error C:\\qp\\qpc
Okay, thank you very much! :)
Okay, thank you very much! :)
Hi dillang, Thank you for reporting. Indeed, the poke() command works currently differently in qview than in qutest, but it would be better if they were consistent. This was fixed in QView 8.1.3 just uploaded to PyPi. You can upgrade to this version by typing: pip install qview --upgrade And here is an example of using peek()/poke() # example of a custom command def cust_command(self): string_to_inject = "StringContents" QView.current_obj(QView.OBJ_AP, "my_string_length") QView.poke(0, 2, pack("<H",...
Hi there, I've been using the poke function in qutest and qview applications to inject values into static global variables. It seems like they both need to be called differently between qutest and qview scripts and I was wondering if I had set something up incorrectly or was using them wrong. e.g. in my .c file I have defined static variables: static uint8_t my_string[128]; static uint16_t my_string_length; and I have added both of these to the object dictionary: QS_OBJ_DICTIONARY(my_string); QS_OBJ_DICTIONARY(&my_string_length);...
rt_err_t rt_sched_lock ( rt_sched_lock_level_t * plvl ) Lock the system scheduler. /* Parameters plvl Pointer to the object where lock level stores to Returns rt_err_t RT_EOK on success -RT_EINVAL if plvl is NULL Note This function has both MP version and UP version. */ Hi, Dr Samek, Yes, plvl is a pointer to store local irq level not a given level to lock scheduler.
Also I reviewed the code of rt-thread (scheduler_mp.c for MP mode) and I feel like it doesn't support locking the scheduler to a given priority level. I'm not RT-Thread expert, but my quick glance at the documentation shows that RT-Thread seems to support selective scheduler locking to the specified level. Please take a look at the following thread management functions: rt_err_t rt_sched_lock(rt_sched_lock_level_t * plv) rt_err_t rt_sched_unlock(rt_sched_lock_level_t level) rt_err_t rt_sched_unlock_n_resched(rt_sched_lock_level_t...
Hi, Dr Samek, I reviewed QActive_publish_ part. My understanding of QF_SCHED_LOCK_ and QF_SCHED_UNLOCK_ is that before all message dispatches are completed, the active objects that may receive dispatched events should not be scheduled. void QActive_publish_( ... if (QPSet_notEmpty(&subscrList)) { /* any subscribers? */ /* the highest-prio subscriber */ uint_fast8_t p = QPSet_findMax(&subscrList); QActive *a = QActive_registry_[p]; QF_SCHED_STAT_ QF_SCHED_LOCK_(a->prio); /* lock the scheduler up to...
Wrong assertion in qep_hsm.
Fixed in QP/C/C++ 8.1.2, where ascrutinizedll assertions have been scruitinized and tested (100% MC/DC). --MMS
Horizontal navigation/panning with shift + scroll wheel only works in left direction
Fixed in QM 7.0.2. --MMS
QTimeEvt_noActive() behaves incorrectly in QP/C/C++ 8.1.0
Fixed in QP/C/C++ 8.1.2 --MMS
For context, I am currently trying to convert a Rhapsody Model into a QM model in order to see how painful of a process it is going to be. I understand that it would be in my best interest to develop with a "QM first" paradigm, but at this point in time it's in my best interest to start with a Rhapsody model and try to replicate it in QM. Examples are attached as QM_example and Rhapsody_example. The model is a simple dishwasher example offered by a class from Rhapsody. There's a state called Active,...
QPCPP 8.1.1 build errors with -Wsign-conversion
Fixed in QP/C++ 8.1.2. --MMS
QP 8.1.1, file qsafe.h compilation errors
Fixed in QP/C 8.1.2. --MMS
QM 7.0.1 tab title bug
Fixed in QM 7.0.2. --MMS
Hi Borut, Alignment is part of the type, so you might try to specify the type as __ALIGNED(4) uint8_t. --MMS
Generated by QM wo __ALIGNED(4) ........ typedef struct { // protected: QActive super; // public: QTimeEvt timeEvt; QTimeEvt unlockTmo; uint8_t pos; uint16_t delay[13]; uint8_t bcoIdx; uint8_t m95op; uint16_t m95Token; bool m95Busy; M95Op m95LastOp; uint32_t m95LastAddr; uint32_t m95LastLen; (__ALIGNED(4) uint8_t m95Buf[sizeof(CiaNvData)]; // ← HERE) ????? CiaNvData nv; char settingsPw[32]; bool settings_unlocked; char pendingPw[32]; bool expectConfirm; CiaMode mode; } Cia; How to add __ALIGNED(4)...
Generated by QM wo __ALIGNED(4) ........ typedef struct { // protected: QActive super; // public: QTimeEvt timeEvt; QTimeEvt unlockTmo; uint8_t pos; uint16_t delay[13]; uint8_t bcoIdx; uint8_t m95op; uint16_t m95Token; bool m95Busy; M95Op m95LastOp; uint32_t m95LastAddr; uint32_t m95LastLen; (__ALIGNED(4) uint8_t m95Buf[sizeof(CiaNvData)]; // ← HERE) ????? CiaNvData nv; char settingsPw[32]; bool settings_unlocked; char pendingPw[32]; bool expectConfirm; CiaMode mode; } Cia; How to add __ALIGNED(4)...