diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 0000000..fa6cc9f --- /dev/null +++ b/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/LICENSES/GPL-3.0-or-later.txt b/LICENSES/GPL-3.0-or-later.txt new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSES/GPL-3.0-or-later.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSES/LICENSE-LMFlash.txt b/LICENSES/LICENSE-LMFlash.txt new file mode 100644 index 0000000..462e404 --- /dev/null +++ b/LICENSES/LICENSE-LMFlash.txt @@ -0,0 +1,86 @@ +License Agreement + +Important - This is a legally binding agreement. Read it carefully. After you read the following terms, you will be asked whether you are authorized to commit your company to abide by the following terms. THIS AGREEMENT IS DISPLAYED FOR YOU TO READ PRIOR TO DOWNLOADING OR USING THE "LICENSED MATERIALS". + +DO NOT DOWNLOAD OR INSTALL the software programs unless you agree on behalf of yourself and your company to be bound by the terms of this License Agreement. + +DO NOT CLICK "I AGREE" UNLESS : + +1. YOU ARE AUTHORIZED TO AGREE TO THE TERMS OF THIS LICENSE ON BEHALF OF YOURSELF AND YOUR COMPANY; AND + +2. YOU INTEND TO ENTER THIS LEGALLY BINDING AGREEMENT ON BEHALF OF YOURSELF AND YOUR COMPANY. + +Important - Read carefully: This software license agreement ("Agreement") is a legal agreement between you (either an individual or entity) and Texas Instruments Incorporated ("TI"). The "Licensed Materials" subject to this Agreement include the software programs TI has granted you access to download and any "on-line" or electronic documentation associated with these programs, or any portion thereof, and may also include hardware, reference designs and associated documentation. The Licensed Materials are specifically designed and licensed for use solely and exclusively with microprocessor/microcontroller devices manufactured by or for TI ("TI Devices"). By installing, copying or otherwise using the Licensed Materials you agree to abide by the provisions set forth herein. This Agreement is displayed for you to read prior to using the Licensed Materials. If you choose not to accept or agree with these provisions,do not download or install the Licensed Materials . + +1. Delivery. TI may deliver the Licensed Materials, or portions thereof, to you electronically. + +2. License Grant and Use Restrictions. + +a. Limited Source Code License. Subject to the terms of this Agreement, and commencing as of the Effective Date and continuing for the term of this Agreement, TI hereby grants to you a limited, free, non-transferable, non-exclusive, non-assignable, non-sub-licensable license to make copies, prepare derivative works, display internally and use internally the Licensed Materials provided to you in source code for the sole purposes of designing and developing object and executable versions of such Licensed Materials or any derivative thereof, that execute solely and exclusively on TI Devices used in Customer Product(s), and maintaining and supporting such Licensed Materials, or any derivative thereof, and Customer Product(s). "Customer Product" means a final product distributed by or for you that consists of both hardware, including one or more TI Devices, and software components, including only executable versions of the Licensed Materials that execute solely and exclusively on or with such TI Devices and not on devices manufactured by or for an entity other than TI. + +b. Production and Distribution License. Subject to the terms of this Agreement, and commencing as of the Effective Date and continuing for the term of this Agreement, TI hereby grants to you a free, non-exclusive, non-transferable, non-assignable, worldwide license to: + +(i). Use object code versions of the Licensed Materials, or any derivative thereof, to make copies, display internally, evaluate, test, distribute internally and use internally for the sole purposes of designing and developing Customer Product(s), and maintaining and supporting the Licensed Materials and Customer Product(s); + +(ii). Make copies, use, sell, offer to sell, and otherwise distribute object code and executable versions of the Licensed Materials, or any derivative thereof, for use in or with Customer Product(s), provided that such Licensed Materials are embedded in or only used with Customer Product(s), and provided further that such Licensed Materials execute solely and exclusively on a TI Device and not on any device manufactured by or for an entity other than TI. + +c. Demonstration License. Subject to the terms of this Agreement, and commencing as of the Effective Date and continuing for the term of this Agreement, TI grants to you a free, non-transferable, non-exclusive, non-assignable, non-sub-licensable worldwide license to demonstrate to third parties the Licensed Materials as they are used in Customer Products executing solely and exclusively on TI Devices, provided that such Licensed Materials are demonstrated in object or executable versions only. + +d. Reference Design Use License. Subject to the terms of this Agreement, and commencing as of the Effective Date and continuing for the term of this Agreement, TI hereby grants to you a free, non-transferable, non-exclusive, non-assignable, non-sub-licensable worldwide license to: + +(i). use the Licensed Materials to design, develop, manufacture or have manufactured, sell, offer to sell, or otherwise distribute Customer Product(s) or product designs, including portions or derivatives of the Licensed Materials as they are incorporated in or used with Customer Product(s), provided such Customer Products or product designs utilize a TI Device. + +e. Contractors and Suppliers. The licenses granted to you hereunder shall include your on-site and off-site suppliers and independent contractors, while such suppliers and independent contractors are performing work for or providing services to you, provided that such suppliers and independent contractors have executed work-for-hire agreements with you containing terms and conditions not inconsistent with the terms and conditions set forth is this Agreement and provided further that such contractors may provide work product to only you under such work-for-hire agreements. + +f. No Other License. Notwithstanding anything to the contrary, nothing in this Agreement shall be construed as a license to any intellectual property rights of TI other than those rights embodied in the Licensed Materials provided to you by TI. EXCEPT AS PROVIDED HEREIN, NO OTHER LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY OTHER TI INTELLECTUAL PROPERTY RIGHTS IS GRANTED HEREIN. + +g. Restrictions. You shall maintain the source code versions of the Licensed Materials under password control protection and shall not disclose such source code versions of the Licensed Materials, or any derivative thereof, to any person other than your employees and contractors whose job performance requires access. You shall not use the Licensed Materials with a processing device manufactured by or for an entity other than TI, and you agree that any such unauthorized use of the Licensed Materials is a material breach of this Agreement. Except as expressly provided in this Agreement, you shall not copy, publish, disclose, display, provide, transfer or make available the Licensed Materials to any third party and you shall not sublicense, transfer, or assign the Licensed Materials or your rights under this Agreement to any third party. You shall not mortgage, pledge or encumber the Licensed Materials in any way. You shall not (i) incorporate, combine, or distribute the Licensed Materials, or any derivative thereof, with any Public Software, or (ii) use Public Software in the development of any derivatives of the Licensed Materials, each in such a way that would cause the Licensed Materials, or any derivative thereof, to be subject to all or part of the license obligations or other intellectual property related terms with respect to such Public Software, including but not limited to, the obligations that the Licensed Materials, or any derivative thereof, incorporated into, combined, or distributed with such Public Software (x) be disclosed or distributed in source code form, be licensed for the purpose of making derivatives of such software, or be redistributed free of charge, contrary to the terms and conditions of this Agreement, (y) be used with devices other than TI Devices, or (z) be otherwise used or distributed in a manner contrary to the terms and conditions of this Agreement. As used in this Section 2(g), "Public Software" means any software that contains, or is derived in whole or in part from, any software distributed as open source software, including but not limited to software licensed under the following or similar models: (A) GNU's General Public License (GPL) or Lesser/Library GPL (LGPL), (B) the Artistic License (e.g., PERL), (C) the Mozilla Public License, (D) the Netscape Public License, (E) the Sun Community Source License (SCSL), (F) the Sun Industry Standards Source License (SISL), (G) the Apache Server license, (H) QT Free Edition License, (I) IBM Public License, and (J) BitKeeper. + +h. Termination. This Agreement is effective until terminated. You may terminate this Agreement at any time by written notice to TI. Without prejudice to any other rights, if you fail to comply with the terms of this Agreement, TI may terminate your right to use the Licensed Materials upon written notice to you. Upon termination of this Agreement, you will destroy any and all copies of the Licensed Materials in your possession, custody or control and provide to TI a written statement signed by your authorized representative certifying such destruction. The following sections will survive any expiration or termination of this Agreement: 2(h) (Termination), 3 (Licensed Materials Ownership), 6 (Warranties and Limitations), 7 (Indemnification Disclaimer), 10 (Export Control), 11 (Governing Law and Severability), 12 (PRC Provisions), and 13 (Entire Agreement). The obligations set forth in Section 5 (Confidential Information) will survive any expiration or termination of this Agreement for three (3) years after such expiration or termination. + +3. Licensed Materials Ownership. The Licensed Materials are licensed, not sold to you, and can only be used in accordance with the terms of this Agreement. Subject to the licenses granted to you pursuant to this Agreement, TI and TI's licensors own and shall continue to own all right, title, and interest in and to the Licensed Materials, including all copies thereof. The parties agree that all fixes, modifications and improvements to the Licensed Materials conceived of or made by TI that are based, either in whole or in part, on your feedback, suggestions or recommendations are the exclusive property of TI and all right, title and interest in and to such fixes, modifications or improvements to the Licensed Materials will vest solely in TI. Moreover, you acknowledge and agree that when your independently developed software or hardware components are combined, in whole or in part, with the Licensed Materials, your right to use the Licensed Materials embodied in such resulting combined work shall remain subject to the terms and conditions of this Agreement. + +4. Intellectual Property Rights. + +a. The Licensed Materials contain copyrighted material, trade secrets and other proprietary information of TI and TI's licensors and are protected by copyright laws, international copyright treaties, and trade secret laws, as well as other intellectual property laws. To protect TI's and TI's licensors' rights in the Licensed Materials, you agree, except as specifically permitted by statute by a provision that cannot be waived by contract, not to "unlock", decompile, reverse engineer, disassemble or otherwise translate any portions of the Licensed Materials to a human-perceivable form nor to permit any person or entity to do so. You shall not remove, alter, cover, or obscure any confidentiality, trade secret, proprietary, or copyright notices, trade-marks, proprietary, patent, or other identifying marks or designs from any component of the Licensed Materials and you shall reproduce and include in all copies of the Licensed Materials the copyright notice(s) and proprietary legend(s) of TI and TI's licensors as they appear in the Licensed Materials. TI reserves all rights not specifically granted under this Agreement. + +b. Third parties may claim to own patents, copyrights, or other intellectual property rights that cover the implementation of certain Licensed Materials. Certain Licensed Materials may also be based on industry recognized standards, including but not limited to specifically the ISO MPEG and ITU standards, and software programs published by industry recognized standards bodies and certain third parties claim to own patents, copyrights, and other intellectual property rights that cover implementation of those standards. You acknowledge and agree that this Agreement does not convey a license to any such third party patents, copyrights, and other intellectual property rights and that you are solely responsible for any patent, copyright, or other intellectual property right claims that relate to your use and distribution of the Licensed Materials, and your use and distribution of your products that include or incorporate the Licensed Materials. + +5. Confidential Information. You acknowledge and agree that the Licensed Materials contain trade secrets and other confidential information of TI and TI's licensors. You agree to use the Licensed Materials solely within the scope of the licenses set forth herein, to maintain the Licensed Materials in strict confidence, to use at least the same procedures and degree of care that you use to prevent disclosure of your own confidential information of like importance but in no instance less than reasonable care, and to prevent disclosure of the Licensed Materials to any third party, except as may be necessary and required in connection with your rights and obligations hereunder. You agree to obtain executed confidentiality agreements with your employees and contractors having access to the Licensed Materials and to diligently take steps to enforce such agreements in this respect. TI agrees that the employment agreements used in the normal course of your business shall satisfy the requirements of this section. TI may disclose your contact information to TI's applicable licensors. + +6. Warranties and Limitations. YOU ACKNOWLEDGE AND AGREE THAT THE LICENSED MATERIALS MAY NOT BE INTENDED FOR PRODUCTION APPLICATIONS AND MAY CONTAIN IRREGULARITIES AND DEFECTS NOT FOUND IN PRODUCTION SOFTWARE. FURTHERMORE, YOU ACKNOWLEDGE AND AGREE THAT THE LICENSED MATERIALS HAVE NOT BEEN TESTED OR CERTIFIED BY ANY GOVERNMENT AGENCY OR INDUSTRY REGULATORY ORGANIZATION OR ANY OTHER THIRD PARTY ORGANIZATION. YOU AGREE THAT PRIOR TO USING, INCORPORATING OR DISTRIBUTING THE LICENSED MATERIALS IN OR WITH ANY COMMERCIAL PRODUCT THAT YOU WILL THOROUGHLY TEST THE PRODUCT AND THE FUNCTIONALITY OF THE LICENSED MATERIALS IN OR WITH THAT PRODUCT AND BE SOLELY RESPONSIBLE FOR ANY PROBLEMS OR FAILURES. + +THE LICENSED MATERIALS AND ANY REALTED DOCUMENTATION ARE PROVIDED "AS IS" AND WITH ALL FAULTS. TI MAKES NO WARRANTY OR REPRESENTATION, WHETHER EXPRESS, IMPLIED OR STATUTORY, REGARDING THE LICENSED MATERIALS, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE. TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADE SECRETS OR OTHER INTELLECTUAL PROPERTY RIGHTS. YOU AGREE TO USE YOUR INDEPENDENT JUDGMENT IN DEVELOPING YOUR PRODUCTS. NOTHING CONTAINED IN THIS AGREEMENT WILL BE CONSTRUED AS A WARRANTY OR REPRESENTATION BY TI TO MAINTAIN PRODUCTION OF ANY TI SEMICONDUCTOR DEVICE OR OTHER HARDWARE OR SOFTWARE WITH WHICH THE LICENSED MATERIALS MAY BE USED. + +IN NO EVENT SHALL TI, OR ANY APPLICABLE LICENSOR, BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED, ON ANY THEORY OF LIABILITY, IN CONNECTION WITH OR ARISING OUT OF THIS AGREEMENT OR THE USE OF THE LICENSED MATERIALS, REGARDLESS OF WHETHER TI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF REMOVAL OR REINSTALLATION, OUTSIDE COMPUTER TIME, LABOR COSTS, LOSS OF DATA, LOSS OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF YOUR USE OF THE LICENSED MATERIALS EXCEED FIVE HUNDRED U.S. DOLLARS (US$500). THE EXISTENCE OF MORE THAN ONE CLAIM WILL NOT ENLARGE OR EXTEND THESE LIMITS. + +Because some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages or limitation on how long an implied warranty lasts, the above limitations or exclusions may not apply to you. + +7. Indemnification Disclaimer. YOU ACKNOWLEDGE AND AGREE THAT TI SHALL NOT BE LIABLE FOR AND SHALL NOT DEFEND OR INDEMNIFY YOU AGAINST ANY THIRD PARTY INFRINGEMENT CLAIM THAT RELATES TO OR IS BASED ON YOUR MANUFACTURE, USE, OR DISTRIBUTION OF THE LICENSED MATERIALS OR YOUR MANUFACTURE, USE, OFFER FOR SALE, SALE, IMPORTATION OR DISTRIBUTION OF YOUR PRODUCTS THAT INCLUDE OR INCORPORATE THE LICENSED MATERIALS. + +You will defend and indemnify TI in the event of claim, liability or costs (including reasonable attorney's fees related to Your use or any sub-licensee's use of the Licensed Materials) relating in any way to Your violation of the terms of the License Grants set forth in Section 2, or any other violation of other terms and conditions of this Agreement. + +8. No Technical Support. TI and TI's licensors are under no obligation to install, maintain or support the Licensed Materials. + +9. Notices. All notices to TI hereunder shall be delivered to Texas Instruments Incorporated, AEC Software Operations, 12203 Southwest Freeway, Mail Station 701, Stafford, Texas 77477, Attention: Administrator, AEC Software Operations, with a copy to Texas Instruments Incorporated, 12203 Southwest Freeway, Mail Station 725, Stafford, Texas 77477, Attention: Legal Department. All notices shall be deemed served when received by TI. + +10. Export Control. You hereby acknowledge that the Licensed Materials are subject to export control under the U.S. Commerce Department's Export Administration Regulations ("EAR"). You further hereby acknowledge and agree that unless prior authorization is obtained from the U.S. Commerce Department, neither you nor your customers will export, re-export, or release, directly or indirectly, any technology, software, or software source code (as defined in Part 772 of the EAR), received from TI, or export, directly or indirectly, any direct product of such technology, software, or software source code (as defined in Part 734 of the EAR), to any destination or country to which the export, re-export, or release of the technology, software, or software source code, or direct product is prohibited by the EAR. You agree that none of the Licensed Materials may be downloaded or otherwise exported or reexported (i) into (or to a national or resident of) Cuba, Iran, North Korea, Sudan and Syria or any other country the U.S. has embargoed goods; or (ii) to anyone on the U.S. Treasury Department's List of Specially Designated Nationals or the U.S. Commerce Department's Denied Persons List or Entity List. You represent and warrant that you are not located in, under the control of, or a national or resident of any such country or on any such list and you will not use or transfer the Licensed Materials for use in any sensitive nuclear, chemical or biological weapons, or missile technology end-uses unless authorized by the U.S. Government by regulation or specific license or for a military end-use in, or by any military entity of Albania, Armenia, Azerbaijan, Belarus, Cambodia, China, Georgia, Iran, Iraq, Kazakhstan, Kyrgyzstan, Laos, Libya, Macau, Moldova, Mongolia, Russia, Tajikistan, Turkmenistan, Ukraine, Uzbekistan, and Vietnam. Any software export classification made by TI shall be for TI's internal use only and shall not be construed as a representation or warranty regarding the proper export classification for such software or whether an export license or other documentation is required for the exportation of such software. + +11. Governing Law and Severability. This Agreement will be governed by and interpreted in accordance with the laws of the State of Texas, without reference to conflict of laws principles. If for any reason a court of competent jurisdiction finds any provision of the Agreement to be unenforceable, that provision will be enforced to the maximum extent possible to effectuate the intent of the parties, and the remainder of the Agreement shall continue in full force and effect. This Agreement shall not be governed by the United Nations Convention on Contracts for the International Sale of Goods, or by the Uniform Computer Information Transactions Act (UCITA), as it may be enacted in the State of Texas. The parties agree that non-exclusive jurisdiction for any dispute arising out of or relating to this Agreement lies within the courts located in the State of Texas. Notwithstanding the foregoing, any judgment may be enforced in any United States or foreign court, and either party may seek injunctive relief in any United States or foreign court. + +12. PRC Provisions. If you are located in the People's Republic of China ("PRC") or if the Licensed Materials will be sent to the PRC, the following provisions shall apply and shall supersede any other provisions in this Agreement concerning the same subject matter as the following provisions: + +a. Registration Requirements. You shall be solely responsible for performing all acts and obtaining all approvals that may be required in connection with this Agreement by the government of the PRC, including but not limited to registering pursuant to, and otherwise complying with, the PRC Measures on the Administration of Software Products, Management Regulations on Technology Import-Export, and Technology Import and Export Contract Registration Management Rules. Upon receipt of such approvals from the government authorities, you shall forward evidence of all such approvals to TI for its records. In the event that you fail to obtain any such approval or registration, you shall be solely responsible for any and all losses, damages or costs resulting therefrom, and shall indemnify TI for all such losses, damages or costs. + +b. Governing Language. This Agreement is written and executed in the English language. If a translation of this Agreement is required for any purpose, including but not limited to registration of the Agreement pursuant to any governmental laws, regulations or rules, you shall be solely responsible for creating such translation. Any translation of this Agreement into a language other than English is intended solely in order to comply with such laws or for reference purposes, and the English language version shall be authoritative and controlling. + +c. Export Control. + +(i). Diversions of Technology. You hereby agree that unless prior authorization is obtained from the U.S. Department of Commerce, neither you nor your subsidiaries or affiliates shall knowingly export, re-export, or release, directly or indirectly, any technology, software, or software source code (as defined in Part 772 of the Export Administration Regulations of the U.S. Department of Commerce ("EAR")), received from TI or any of its affiliated companies, or export, directly or indirectly, any direct product of such technology, software, or software source code (as defined in Part 734 of the EAR), to any destination or country to which the export, re-export, or release of the technology, software, software source code, or direct product is prohibited by the EAR. + +(ii). Assurance of Compliance. You understand and acknowledge that products, technology (regardless of the form in which it is provided), software or software source code, received from TI or any of its affiliates under this Agreement may be under export control of the United States or other countries. You shall comply with the United States and other applicable non-U.S. laws and regulations governing the export, re-export and release of any products, technology, software, or software source code received under this Agreement from TI or its affiliates. You shall not undertake any action that is prohibited by the EAR. Without limiting the generality of the foregoing, you specifically agree that you shall not transfer or release products, technology, software, or software source code of TI or its affiliates to, or for use by, military end users or for use in military, missile, nuclear, biological, or chemical weapons end uses. + +(iii). Licenses. Each party shall secure at its own expense, such licenses and export and import documents as are necessary for each respective party to fulfill its obligations under this Agreement. If such licenses or government approvals cannot be obtained, TI may terminate this Agreement, or shall otherwise be excused from the performance of any obligations it may have under this Agreement for which the licenses or government approvals are required. + +13. Entire Agreement. This is the entire Agreement between you and TI, and absent a signed and effective software license agreement related to the subject matter of this Agreement, this Agreement supersedes any prior agreement between the parties related to the subject matter of this Agreement. Notwithstanding the foregoing, any signed and effective software license agreement relating to the subject matter hereof will supersede the terms of this Agreement. No amendment or modification of this Agreement will be effective unless in writing and signed by a duly authorized representative of TI. You hereby warrant and represent that you have obtained all authorizations and other applicable consents required empowering you to enter into this Agreement. + diff --git a/LICENSES/LICENSE-MIT.txt b/LICENSES/LICENSE-MIT.txt new file mode 100644 index 0000000..8aa2645 --- /dev/null +++ b/LICENSES/LICENSE-MIT.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSES/LICENSE-Python.txt b/LICENSES/LICENSE-Python.txt new file mode 100644 index 0000000..52ddaab --- /dev/null +++ b/LICENSES/LICENSE-Python.txt @@ -0,0 +1,603 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization +created specifically to own Python-related Intellectual Property. +Zope Corporation was a sponsoring member of the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation; +All Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + + +Additional Conditions for this Windows binary build +--------------------------------------------------- + +This program is linked with and uses Microsoft Distributable Code, +copyrighted by Microsoft Corporation. The Microsoft Distributable Code +is embedded in each .exe, .dll and .pyd file as a result of running +the code through a linker. + +If you further distribute programs that include the Microsoft +Distributable Code, you must comply with the restrictions on +distribution specified by Microsoft. In particular, you must require +distributors and external end users to agree to terms that protect the +Microsoft Distributable Code at least as much as Microsoft's own +requirements for the Distributable Code. See Microsoft's documentation +(included in its developer tools and on its website at microsoft.com) +for specific details. + +Redistribution of the Windows binary build of the Python interpreter +complies with this agreement, provided that you do not: + +- alter any copyright, trademark or patent notice in Microsoft's +Distributable Code; + +- use Microsoft's trademarks in your programs' names or in a way that +suggests your programs come from or are endorsed by Microsoft; + +- distribute Microsoft's Distributable Code to run on a platform other +than Microsoft operating systems, run-time technologies or application +platforms; or + +- include Microsoft Distributable Code in malicious, deceptive or +unlawful programs. + +These restrictions apply only to the Microsoft Distributable Code as +defined above, not to Python itself or any programs running on the +Python interpreter. The redistribution of the Python interpreter and +libraries is governed by the Python Software License included with this +file, or by other licenses as marked. + + + +-------------------------------------------------------------------------- + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2010 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, jseward@bzip.org +bzip2/libbzip2 version 1.0.6 of 6 September 2010 + +-------------------------------------------------------------------------- + + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a double license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState +Corporation and other parties. The following terms apply to all files +associated with the software unless explicitly disclaimed in +individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState +Corporation, Apple Inc. and other parties. The following terms apply to +all files associated with the software unless explicitly disclaimed in +individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +Copyright (c) 1993-1999 Ioi Kim Lam. +Copyright (c) 2000-2001 Tix Project Group. +Copyright (c) 2004 ActiveState + +This software is copyrighted by the above entities +and other parties. The following terms apply to all files associated +with the software unless explicitly disclaimed in individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +---------------------------------------------------------------------- + +Parts of this software are based on the Tcl/Tk software copyrighted by +the Regents of the University of California, Sun Microsystems, Inc., +and other parties. The original license terms of the Tcl/Tk software +distribution is included in the file docs/license.tcltk. + +Parts of this software are based on the HTML Library software +copyrighted by Sun Microsystems, Inc. The original license terms of +the HTML Library software distribution is included in the file +docs/license.html_lib. + diff --git a/LICENSE.txt b/LICENSES/LICENSE.txt similarity index 97% rename from LICENSE.txt rename to LICENSES/LICENSE.txt index 344804e..bf8cd07 100644 --- a/LICENSE.txt +++ b/LICENSES/LICENSE.txt @@ -1,26 +1,26 @@ -QTools Collection -================= -Most tools included in this collection are distributed under the -terms of the GNU General Public License (GPL) as published by the -Free Software Foundation, either version 2 of the License, or (at -your option) any later version. The text of GPL version 2 is -included in the file qtools/open-source/GPLv2.txt. - -Some of the tools are distributed under the terms of the MIT open -source license. The complete text of the MIT license is included -in the comments. - -The Python package is distributed under the terms of the PYTHON -LICENSE AGREEMENT, included in the file PYTHON_LICENSE.txt in the -qtools/open-source subdirectory. - -The LMFlash utility for Windows is is distributed under the terms -of the LMFlash license, included in the file LMFlash_LICENSE.rtf -in the qtools/open-source subdirectory. Specifically, the LMFlash -utility is distributed according to Section 2a "Demonstration License". - - -Contact Information: -==================== -- https://www.state-machine.com -- mailto:info@state-machine.com +QTools Collection +================= +Most tools included in this collection are distributed under the +terms of the GNU General Public License (GPL) as published by the +Free Software Foundation, either version 2 of the License, or (at +your option) any later version. The text of GPL version 2 is +included in the file qtools/open-source/GPLv2.txt. + +Some of the tools are distributed under the terms of the MIT open +source license. The complete text of the MIT license is included +in the comments. + +The Python package is distributed under the terms of the PYTHON +LICENSE AGREEMENT, included in the file PYTHON_LICENSE.txt in the +qtools/open-source subdirectory. + +The LMFlash utility for Windows is is distributed under the terms +of the LMFlash license, included in the file LMFlash_LICENSE.rtf +in the qtools/open-source subdirectory. Specifically, the LMFlash +utility is distributed according to Section 2a "Demonstration License". + + +Contact Information: +==================== +- https://www.state-machine.com +- mailto:info@state-machine.com diff --git a/LICENSES/LicenseRef-QL-commercial.txt b/LICENSES/LicenseRef-QL-commercial.txt new file mode 100644 index 0000000..b08f3ad --- /dev/null +++ b/LICENSES/LicenseRef-QL-commercial.txt @@ -0,0 +1,96 @@ +Quantum Leaps Commercial Licenses + +Copyright (C) 2005 Quantum Leaps, LLC + +Quantum Leaps commercial licenses are traditinal closed-source, paid-for +licenses designed for licensees interested in retaining the proprietary +status of their code. + +The Quantum Leaps commercial licenses expressly supersede the GPL open source +license. This means that when you license the QP/C or QP/C++ Real-Time +Embedded Frameworks under a Quantum Leaps commercial license, you specifically +do not use the software under the open source license and therefore you are +not subject to any of its terms. + +Quantum Leaps commercial licensing options are described below: + + +Single Product License +---------------------- +Single Product License allows a given company (“Licensee”) to embed the +specified type(s) of the QP Real-Time Embedded Framework(s) into one end- +product of the Licensee (Single Product). Licensee can distribute/sell an +unlimited number of units of the Single Product (royalty-free licensing), +for the life of the Single Product. A different Single Product license is +required for each different end product (i.e. model) even if the end-product +is in the same family as a previously licensed end product. This license +is specific to the Licensee and the name and model of the Signle Product, +which needs to be defined in the license. The general rule we apply is: + +If you consider it a separate product…so do we! + +Volume discounts are offered if several Single Products are licensed at once +with one license agreement. + + +Product Line License +-------------------- +Product Line License allows a given company (“Licensee”) to embed the +specified type(s) of the QP Real-Time Embedded Framework(s) into any number +of end-products within a family of related products (Product Line). Licensee +can distribute/sell an unlimited number of units of each of those products +(royalty-free licensing), for the life of the end-products within the +Product Line. Product Line License applies to all end-products that do +similar functions within the same Product Line. + + +Any-Product License +------------------- +Any-Product License allows a given company (“Licensee”) to embed the +specified type(s) of the QP Real-Time Embedded Framework(s) into any end- +product of that company. The Licensee can distribute/sell an unlimited number +of the products containing the licensed QP framework type(s) (royalty-free +licensing). + + +Site License +------------ +Site-License allows a given company (“Licensee”) to embed the specified +type(s) of the QP Real-Time Embedded Framework(s) into any end-customer +product, as long as the products are designed at a given physical location +(Site), which must be defined in the license. This license gives the +Licensee also limited sublicensing rights for its clients and is specifically +designed for development contractors and consultants, who develop embedded +software for other companies. + + +OEM License +----------- +OEM License allows a given company (“Licensee”) to embed the specified +type(s) of the QP Real-Time Embedded Framework(s) in any product of that +company (Original Equipment Manufacturer) and gives limited sublicensing +rights to system integrators, subsystem vendors, subcontractors, and other +affiliates. OEM licenses are customizable to match exactly the specific +licensing needs of a given Licensee. + + +Education License +----------------- +Education License allows a given accredited educational institution +(“Licensee”) to use and embed the specified type(s) of the QP Real-Time +Embedded Framework(s) in any project completed at that educational +institution. To be eligible for this license, the institution must be +focused mainly on teaching students. The Education Licenses are free +and will be granted liberally upon request. + + +**** +NOTE: Please use the contact information below to find the current prices +of the Quantum Leaps commercial licenses and to request the license +agreements and price quotes. +**** + +Contact Information: +==================== +- https://www.state-machine.com/licensing +- mailto:info@state-machine.com diff --git a/LICENSES/doc/make.url b/LICENSES/doc/make.url new file mode 100644 index 0000000..78de560 --- /dev/null +++ b/LICENSES/doc/make.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.gnu.org/software/make/manual/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qm.url b/LICENSES/doc/qm.url new file mode 100644 index 0000000..ae52b02 --- /dev/null +++ b/LICENSES/doc/qm.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qm/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qpc.url b/LICENSES/doc/qpc.url new file mode 100644 index 0000000..d889e95 --- /dev/null +++ b/LICENSES/doc/qpc.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qpc/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qpcpp.url b/LICENSES/doc/qpcpp.url new file mode 100644 index 0000000..0124230 --- /dev/null +++ b/LICENSES/doc/qpcpp.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qpcpp/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qpn.url b/LICENSES/doc/qpn.url new file mode 100644 index 0000000..5abb4d0 --- /dev/null +++ b/LICENSES/doc/qpn.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qpn/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools.url b/LICENSES/doc/qtools.url new file mode 100644 index 0000000..49dbe91 --- /dev/null +++ b/LICENSES/doc/qtools.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools_qcalc.url b/LICENSES/doc/qtools_qcalc.url new file mode 100644 index 0000000..00acab6 --- /dev/null +++ b/LICENSES/doc/qtools_qcalc.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/qcalc.html +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools_qclean.url b/LICENSES/doc/qtools_qclean.url new file mode 100644 index 0000000..fbcd0a1 --- /dev/null +++ b/LICENSES/doc/qtools_qclean.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/qclean.html +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools_qfsgen.url b/LICENSES/doc/qtools_qfsgen.url new file mode 100644 index 0000000..3b109f7 --- /dev/null +++ b/LICENSES/doc/qtools_qfsgen.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/qfsgen.html +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools_qpspy.url b/LICENSES/doc/qtools_qpspy.url new file mode 100644 index 0000000..0c85c99 --- /dev/null +++ b/LICENSES/doc/qtools_qpspy.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/qpspy.html +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools_qutest.url b/LICENSES/doc/qtools_qutest.url new file mode 100644 index 0000000..84281a9 --- /dev/null +++ b/LICENSES/doc/qtools_qutest.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/qutest.html +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/qtools_qwin.url b/LICENSES/doc/qtools_qwin.url new file mode 100644 index 0000000..f78708c --- /dev/null +++ b/LICENSES/doc/qtools_qwin.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=https://www.state-machine.com/qtools/qwin.html +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 diff --git a/LICENSES/doc/tcl_tk_8.6.url b/LICENSES/doc/tcl_tk_8.6.url new file mode 100644 index 0000000..3b74b5a --- /dev/null +++ b/LICENSES/doc/tcl_tk_8.6.url @@ -0,0 +1,6 @@ +[InternetShortcut] +URL=http://www.tcl.tk/man/tcl8.6/ +IDList= +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/README.md b/README.md index cd15b0a..c535f23 100644 --- a/README.md +++ b/README.md @@ -128,23 +128,28 @@ installation directory of QTools. --------------------------------------------------------------------------- # Licensing +The various Licenses for distributed components are located in the +LICENSES/ sub-directory of this QTools distribution. + Most tools included in this collection are distributed under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. The text of GPL version 2 is included in the -file GPLv2.txt in the licenses/ subdirectory of the QTools distribution. +file GPL-2.0-or-later.txt in the LICENSES/ sub-directory. Some of the tools are distributed under the terms of the MIT open source -license. The complete text of the MIT license is included in the comments. +license. The complete text of the MIT license is included in the comments +and also in the file LICENSE-MIT.txt in the LICENSES/ sub-directory. + The Python package is distributed under the terms of the PYTHON LICENSE -AGREEMENT, included in the file PYTHON_LICENSE.txt in the licenses/ -subdirectory of the QTools distribution. +AGREEMENT, included in the file LICENSE-Python.txt in the LICENSES/ +sub-directory. The LMFlash utility for Windows is is distributed under the terms of the -LMFlash license, included in the file LMFlash_LICENSE.rtf in the licenses/ -subdirectory of the QTools distribution. Specifically, the LMFlash utility -is distributed according to Section 2a "Demonstration License". +LMFlash license, included in the file LICENSE-LMFlash.txt in the LICENSES/ +sub-directory. Specifically, the LMFlash utility is distributed according +to Section 2a "Demonstration License". --------------------------------------------------------------------------- diff --git a/bin/qspy b/bin/qspy deleted file mode 100644 index d2c3184..0000000 Binary files a/bin/qspy and /dev/null differ diff --git a/doxygen/Doxyfile b/doxygen/Doxyfile deleted file mode 100644 index 00517e3..0000000 --- a/doxygen/Doxyfile +++ /dev/null @@ -1,266 +0,0 @@ -# Doxyfile 1.9.2 - -@INCLUDE = ../../ql-doxygen/Doxyfile-QL - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = QTools -PROJECT_NUMBER = 6.9.5 -PROJECT_BRIEF = "Collection of Host-Based Tools" -PROJECT_LOGO = images/logo_ql.png -OUTPUT_DIRECTORY = -CREATE_SUBDIRS = NO -ALLOW_UNICODE_NAMES = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -JAVADOC_BANNER = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -PYTHON_DOCSTRING = YES -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 4 -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -OPTIMIZE_FOR_FORTRAN = NO -OPTIMIZE_OUTPUT_VHDL = NO -OPTIMIZE_OUTPUT_SLICE = NO -EXTENSION_MAPPING = lnt=Objective-C -MARKDOWN_SUPPORT = YES -TOC_INCLUDE_HEADINGS = 4 -AUTOLINK_SUPPORT = YES -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -IDL_PROPERTY_SUPPORT = YES -DISTRIBUTE_GROUP_DOC = NO -GROUP_NESTED_COMPOUNDS = NO -SUBGROUPING = YES -INLINE_GROUPED_CLASSES = YES -INLINE_SIMPLE_STRUCTS = YES -TYPEDEF_HIDES_STRUCT = YES -LOOKUP_CACHE_SIZE = 0 -NUM_PROC_THREADS = 1 -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_PRIV_VIRTUAL = NO -EXTRACT_PACKAGE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -RESOLVE_UNNAMED_PARAMS = YES -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = YES -HIDE_COMPOUND_REFERENCE= NO -SHOW_HEADERFILE = YES -SHOW_INCLUDE_FILES = YES -SHOW_GROUPED_MEMB_INC = NO -FORCE_LOCAL_INCLUDES = NO -INLINE_INFO = YES -SORT_MEMBER_DOCS = NO -SORT_BRIEF_DOCS = NO -SORT_MEMBERS_CTORS_1ST = NO -SORT_GROUP_NAMES = NO -SORT_BY_SCOPE_NAME = NO -STRICT_PROTO_MATCHING = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_FILES = YES -SHOW_NAMESPACES = YES -FILE_VERSION_FILTER = -LAYOUT_FILE = -CITE_BIB_FILES = -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_IF_INCOMPLETE_DOC = YES -WARN_NO_PARAMDOC = NO -WARN_AS_ERROR = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = main.dox \ - gs.dox \ - qpspy.dox \ - qs.dox \ - qspy.dox \ - qutest.dox \ - qutest_tut.dox \ - qutest_ref.dox \ - qview.dox \ - qwin.dox \ - qcalc.dox \ - qclean.dox \ - qfsgen.dox \ - history.dox \ - modules.dox \ - macros.h \ - ../qspy/include/qs_copy.h \ - ../qspy/include/qspy.h \ - ../qutest/qutest_dsl.py \ - ../qview/qview.py \ - ../qwin/qwin_gui.h \ - ../qwin/qwin_gui.c \ - ../../ql-doxygen/help.dox -INPUT_ENCODING = UTF-8 -FILE_PATTERNS = *.dox \ - *.h \ - *.c \ - *.hpp \ - *.cpp \ - *.py -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = _*Dialog -EXAMPLE_PATH = snippets -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = images \ - ../../ql-doxygen/images -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -FILTER_SOURCE_PATTERNS = -USE_MDFILE_AS_MAINPAGE = -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -SOURCE_TOOLTIPS = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -CLANG_ASSISTED_PARSING = NO -CLANG_ADD_INC_PATHS = YES -CLANG_OPTIONS = -CLANG_DATABASE_PATH = -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = ../html -HTML_FILE_EXTENSION = .html -HTML_HEADER = ../../ql-doxygen/header-awesome.html -HTML_FOOTER = ../../ql-doxygen/footer-awesome.html -HTML_STYLESHEET = -HTML_EXTRA_STYLESHEET = ../../ql-doxygen/doxygen-awesome.css \ - ../../ql-doxygen/ql-awesome.css -HTML_EXTRA_FILES = ../../ql-doxygen/doxygen-awesome-darkmode-toggle.js \ - ../../ql-doxygen/preview.js -HTML_COLORSTYLE_HUE = 209 -HTML_COLORSTYLE_SAT = 255 -HTML_COLORSTYLE_GAMMA = 113 -HTML_TIMESTAMP = NO -HTML_DYNAMIC_MENUS = YES -HTML_DYNAMIC_SECTIONS = NO -HTML_INDEX_NUM_ENTRIES = 100 -GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_BUNDLE_ID = com.state-machine.doc -DOCSET_PUBLISHER_ID = com.state-machine.doc -DOCSET_PUBLISHER_NAME = QuantumLeaps -GENERATE_HTMLHELP = NO -CHM_FILE = ../qtools.chm -HHC_LOCATION = -GENERATE_CHI = NO -CHM_INDEX_ENCODING = -BINARY_TOC = YES -TOC_EXPAND = NO -GENERATE_QHP = NO -QCH_FILE = -QHP_NAMESPACE = com.state-machine.qp -QHP_VIRTUAL_FOLDER = doc -QHP_CUST_FILTER_NAME = -QHP_CUST_FILTER_ATTRS = -QHP_SECT_FILTER_ATTRS = -QHG_LOCATION = -GENERATE_ECLIPSEHELP = NO -ECLIPSE_DOC_ID = com.state-machine.qp -DISABLE_INDEX = YES -GENERATE_TREEVIEW = YES -FULL_SIDEBAR = NO -ENUM_VALUES_PER_LINE = 4 -TREEVIEW_WIDTH = 300 -EXT_LINKS_IN_WINDOW = NO -HTML_FORMULA_FORMAT = png -FORMULA_FONTSIZE = 10 -FORMULA_TRANSPARENT = YES -FORMULA_MACROFILE = -USE_MATHJAX = NO -MATHJAX_VERSION = MathJax_2 -MATHJAX_FORMAT = HTML-CSS -MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 -MATHJAX_EXTENSIONS = -MATHJAX_CODEFILE = -SEARCHENGINE = YES -SERVER_BASED_SEARCH = NO -EXTERNAL_SEARCH = NO -SEARCHENGINE_URL = -SEARCHDATA_FILE = searchdata.xml -EXTERNAL_SEARCH_ID = QTOOLS -EXTRA_SEARCH_MAPPINGS = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = Q_SPY \ - Q_UTEST -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES diff --git a/doxygen/Doxyfile-CHM b/doxygen/Doxyfile-CHM deleted file mode 100644 index 2908995..0000000 --- a/doxygen/Doxyfile-CHM +++ /dev/null @@ -1,14 +0,0 @@ -# Doxyfile 1.9.2 - -@INCLUDE = Doxyfile - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- -HTML_OUTPUT = tmp -HTML_HEADER = ../../ql-doxygen/header.html -HTML_FOOTER = ../../ql-doxygen/footer.html -HTML_EXTRA_STYLESHEET = ../../ql-doxygen/ql.css \ - ../../ql-doxygen/preview.js -HTML_EXTRA_FILES = -GENERATE_HTMLHELP = YES diff --git a/doxygen/gs.dox b/doxygen/gs.dox deleted file mode 100644 index 40edcec..0000000 --- a/doxygen/gs.dox +++ /dev/null @@ -1,90 +0,0 @@ -/*! @page gs Getting Started - -@tableofcontents -@section gs_obtain Downloading & Installing QTools™ -@tableofcontents - -

The most recommended way of obtaining QTools™ is by downloading the QP-bundle™, which includes QTools™ as well as all QP frameworks and also the QM™ modeling tool. The main advantage of obtaining QTools™ bundled together like that is that you get all components, tools and examples ready to go. - -@note -QP-bundle™ is the most recommended way of downloading and installing QTools™.@n -It is also highly recommended that you keep checking the QP-bundle™ download page for newer releases. - - -Alternatively, you can download QTools™ separately as described below. - - - -@section install_win32 Installing QTools™ on Windows -On Windows, you simply unzip the `qtools-windows_.zip` archive to the installation folder of your choice (`C:\qp\qtools` is the recommended default). After the installation, you still need to: - -- add the `\bin` and `\MinGW\bin` directories to the global `PATH` on your system, where `` denotes the directory where you have installed QTools (e.g., `C:\qp\qtools\bin;C:\qp\qtools\MinGW\bin`). - -@note -Adding `\bin` and `\MinGW\bin` directories to your `PATH` will enable you to invoke all QTools utilities (like @ref qspy "QSpy" or @ref qclean "QClean") by simply typing `qspy` or `qclean` at the command prompt, regardless of your current directory. This will come handy, because typically you will not invoke `qspy` or `qclean` from the `\bin` directory. - -- define the `QTOOLS` environment variable, for example: - -@verbatim -set QTOOLS=C:\qp\qtools -@endverbatim - -@note -Defining the `QTOOLS` environment variable is required to run @ref qutest "QUTest Unit Testing" and @ref qview "QView Visualization and Monitoring" utilities. - - - -@section install_posix Installing QTools™ on POSIX (Linux/MacOS) -On POSIX (Linux/MacOS), you simply unzip the `qtools-posix_.zip` archive to the installation folder of your choice (`~/qp/qtools` is the recommended default). After the installation, you still need to: - -- add the `/bin` directory to the global `PATH` on your system, where `` denotes the directory where you have installed QTools (e.g., `~/qp/qtools`). - -@note -Adding `/bin` to your `PATH` will enable you to invoke all QTools utilities (like @ref qspy "QSpy" or @ref qclean "QClean") by simply typing `qspy` or `qclean` at the command prompt, regardless of your current directory. This will come handy, because typically you will not invoke `qspy` or `qclean` from the `/bin` directory. - -- define the `QTOOLS` environment variable, for example: - -@verbatim -export QTOOLS=~/qp/qtools -@endverbatim - -@note -Defining the `QTOOLS` environment variable is required to run @ref qutest "QUTest Unit Testing" and @ref qview "QView Visualization and Monitoring" utilities. - - - -@section files Directories and Files -The following annotated directory tree in the standard QTools™ distribution lists the top-level directories and files: - -

    -
  • qtools
  • -
      -
    • bin — binaries (executables and libraries)
    • -
        -
      • `qspy.exe` — @ref qspy "QSPY executable"
      • -
      • `qclean.exe` — @ref qclean
      • -
      • `qfsgen.exe` — @ref qfsgen
      • -
      • ~ ~ ~
      • -
      • `make.exe` — make utility
      • -
      • `rm.exe` — rm (remove) utility
      • -
      • `python.bat` — Batch file to call Python
      • -
      -
    • qspy — @ref qspy "QSPY tool" for software tracing and testing
    • -
        -
      • include — QSPY includes
      • -
      • source — QSPY sources
      • -
      • posix — QSPY port to POSIX (Linux, macOS)
      • -
      • py — Python support (@ref qutest "QUTest")
      • -
      • win32 — QSPY port to Windows
      • -
      -
    •  
    • -
    • The following directories are present in QTools for Windows only
    • -
    • qwin — @ref qwin
    • -
    • MinGW — GNU C/C++ toolset for Windows (32-bit)
    • -
    • gnu_arm-none-eabi — GNU ARM-EABI toolset for Windows
    • -
    • Python38 — Python 3.8 for Windows
    • -
    -
- -@next{qpspy} -*/ diff --git a/doxygen/history.dox b/doxygen/history.dox deleted file mode 100644 index 77d1c3c..0000000 --- a/doxygen/history.dox +++ /dev/null @@ -1,599 +0,0 @@ -/** -@page history Revision History - -@section qtools_6_9_4 Version 6.9.4, 2021-08-31 - - -__Updated GNU-ARM Toolchain for Windows__ - -The GNU-ARM toolchain in QTools for Windows has been updated to the latest Version 10.3-2021.10 released on October 21, 2021. - - - - -@section qtools_6_9_3 Version 6.9.3, 2021-04-09 - -__Changes in QSpy__ -- Moved function `QSPY_printInfo()` to `qspy.c`, to enable the direct QSPY output to the console. Please see also discussion thread [QSPY to console in win32-qv and posix-qv ports](https://sourceforge.net/p/qpc/discussion/668726/thread/92e56e9480) - - -__Changes in QUTest__ -- Corrected the @ref qutest_command "DEBUG mode", where the Enter key now correctly skips a test. -- Added new command include() and provided examples of its use. -- Improved error reporting from test scripts. Specifically, the content of the Python stack has been expanded to encompass all the relevant calls. - - -__Changes in QView__ -- Modified the Python implementation to run correctly after [installing with pip](https://pypi.org/project/qview/). - - -__Changes in QWin__ -- Modified the example code to correctly handle regular buttons alongside the "owner-drawn" buttons. - - -__Changes in QCalc__ -- Modified the Python implementation to run correctly after [installing with pip](https://pypi.org/project/qcalc/). - - -__Updated Python for Windows__ -- The Python interpreter in QTools for Windows has been updated to Python 3.9.4. - - - -@section qtools_6_9_2 Version 6.9.2, 2021-01-18 - -__Changes in QUTest and QView__ - -The UDP socket binding (for connection to QSPY host application) has been changed from "localhost" to "0.0.0.0". This is to improve access to QSPY running on remote hosts. This fixes the following bug: - -- [bug#283 QUTest 6.9.1. broken](https://sourceforge.net/p/qpc/bugs/283/) - - -__Changes in QView__ - -Changed the "Local Filter" dialog box to show "QS_id=..." instead of "AO-prio=..." for QS-IDs above 64. - - -__Added QCalc__ - -A new version of the popular QCalc Programmer's Calculator has been added again. This version is based on Python (whereas the previous was based on Tcl/Tk). The new version is console based and, among other enhancements, adds support for 64-bit range. - - -__Updated GNU-ARM Toolchain for Windows__ - -The GNU-ARM toolchain in QTools for Windows has been updated to the latest Version 10-2020-q4-major released on December 11, 2020. - - -__Updated Python for Windows__ - -The Python interpreter in QTools for Windows has been updated to Python 3.9. - - -@section qtools_6_9_1 Version 6.9.1, 2020-09-28 - -The main purpose of this release is to adjust @ref qutest and @ref qview to the new @ref qs_local "QS Local Filter" design implemented in [QP/C](https://www.state-machine.com/qpc) and [QP/C++](https://www.state-machine.com/qpcpp) 6.9.1. Specifically, the loc_filter() and ao_filter() functions in @ref qutest_script "QUTest scripts" and in @ref qview_script "QView scripts" have been re-designed. Additionally, the @ref qview_loc "QView Local Filter menu" have been adjusted accordingly. - -@note -The change in the loc_filter() command has implications for the existing @ref qutest_script "QUTest scripts". Specifically, the parameters of loc_filter() are no longer object names but rather "QS-IDs" (see the documentation to loc_filter()). - -__Changes in QSPY__ - -The @ref qspy "QSPY host application" has been updated to handle the redesigned local-filters and the new predefined #QS_QF_NEW_ATTEMPT trace record. Also the default version compatibility with the @ref qs "QS target-resident component" (the `-v` @ref qspy_command "command-line option") has been increased from 6.2 to 6.6. - -Additionally, the QS_U64() and QS_I64() data elements have been made available for all types of CPUs, whereas previously they were available only on 64-bit CPUs (see also [feature#181](https://sourceforge.net/p/qpc/feature-requests/181)). - -Additionally, QSPY now can format @ref qs_app "application-specific data elements" in hexadecimal. Here are a few examples of QS trace records in the Target and the generated QSPY output: - -@code{c} -QS_U8(QS_HEX_FMT, 0xABU); // --> 0xAB -QS_U16(QS_HEX_FMT, 0xDEADU); // --> 0xDEAD -QS_U32(QS_HEX_FMT, 0xDEADBEEFU); // --> 0xDEADBEEF -QS_U64(QS_HEX_FMT, 0xDEADBEEF12345678LL); // --> 0xDEADBEEF12345678 -@endcode - - -__Implemented Feature Requests__ - -- [feature#181 "use of QS_U64() on 32 bit machine"](https://sourceforge.net/p/qpc/feature-requests/181) - - -@section qtools_6_9_0 Version 6.9.0, 2020-08-21 - -This release brings the new @ref qview component, which replaces QSpyView written originally in Tcl/Tk. The new @ref qview "QView" is written in **Python** (3.3.+) and brings much commonality with the @ref qutest, which has also been re-structured and improved. - -@note -Starting with this version, both @ref qview and @ref qutest require **Python3** (3.3+) and are **no longer compatible** with Python2. The support for Tcl/Tk has been dropped entirely in QTools. - - -__Changes in Directory Structure__ - -The new new @ref qview "QView" and the updated @ref qutest "QUTest" components are now located directly under the `qtools` folder and are no longer in the `qtools\qspy` folder. Here is the new `qtools` directory structure: - -@code{py} -qtools/ -+---bin/ -+---gnu_arm-none-eabi/ -+---matlab/ -+---mingw32/ -+---Python38/ -+---qclean/ -+---qspy/ -+---qutest/ # <== new qutest location -+---qview/ # <== new qview location -+---qwin/ -+---Unity/ -@endcode - -@note -The changes in the QTools directory structure have impact on the QUTest testing, because the Makefiles (or any other build tools you might be using) need to be adjusted to the new location of the `qutest.py` script. - - -__Changes in QSPY:__ - -- The @ref qspy "QSPY host utility" has been extended with @ref qspy_seq "Sequence Diagram Output". -This new feature replaces the previous support for MscGen and is no longer reliant on any such external tools. - -- QSPY now recognizes the new QS trace record #QS_QF_RUN - -@note -The #QS_QF_RUN record is now generated in @ref qutest "QUTest", which requires adjustments in the existing @ref qutest_script "test scripts". Specifically, the test scripts that provide their own on_reset() callback must now also call expect_run(). - - -__Bug Fixes:__ - -- [bug#153 QSPY Creating corrupt MscGen files](https://sourceforge.net/p/qpc/bugs/153/) - - -@section qtools_6_8_2 Version 6.8.2, 2020-07-17 - -- Changed the QS trace record name QS_QF_ACTIVE_POST_FIFO to ::QS_QF_ACTIVE_POST and QS_QF_EQUEUE_POST_FIFO to ::QS_QF_EQUEUE_POST. This refactoring now better matches the QP/C/C++ API QACTIVE_POST() and QEQueue_post(). -- Fixed errors in the Doxygen documentation, such as: missing documentation for parameters, wrong parameter names, unresolved references, etc. -- Applied new, clearer styling to the Doxygen documentation. - - -@section qtools_6_8_1 Version 6.8.1, 2020-04-04 - -__Bug Fixes:__ -- [bug#263 QSPY handles incorrectly empty strings ](https://sourceforge.net/p/qpc/bugs/263/) - -Also, improved some comments in QUTest scripting documentation (qutest.py). - - - -@section qtools_6_8_0 Version 6.8.0, 2020-03-21 -- Adapted QSPY host application to the changes in QP/C/C++ 6.8.0 -- Added color to the qutest.py Python script console output. Specifically, the failed test scripts are shown in RED while passing test scripts are shown in GREEN. - - - -@section qtools_6_7_0 Version 6.7.0, 2019-12-30 -This QTools release changes the build process for the QSPY, QCLEAN, and QFSGEN utilities on Windows. Specifically, these programs are now built using Visual Studio 2019 instead of the MinGW compiler for Windows. Also, the source code of all Quantum Leaps utilities has been reviewed and all "unsafe" calls to standard C library have been replaced with their "safe" counterparts (e.g., strcpy()->strcpy_s(), strcat()->strcat_s(),fprintf()->fprintf_s(), etc.) All these changes were made to avoid the malware warnings that were issued by some anti-virus software against executables built with MinGW. - -This release also replaces the MinGW toolchain (8.2.0) with the latest mingw32 (9.2.0) installed with MSYS2 (see also https://sourceforge.net/p/qpc/discussion/668726/thread/06b89ba2d5/ ). - -Finally, this release updates the QWIN Prototyping Toolkit (`qtools\qwin` directory) to work with the latest Visual Studio 2019 and specifically with the Resource Editor now available in VS 2019. The qwin-demo project has been updated to build with the Visual Studio 2019. - - - -@section qtools_6_6_0 Version 6.6.0, 2019-08-30 -The main purpose of this release is the change in distribution of the QTools collection, which is now bundled together with the QP frameworks (QP/C, QP/C++ and QP-nano) as well as QM into "QP-bundle". This "QP-bundle" provides a single, streamlined and simplified download and installation of all QP frameworks and all the accompanying tools. - -Also this release brings significant changes to QTools for Windows. Specifically, the location of the MinGW compiler and Tcl/Tk have been moved to separate directories (as opposed to being co-located in the `qtools/bin` directory). This facilitates easier upgrades of these 3-rd party tools, and indeed, they have been upgraded in this QTools/Windows release as follows: - -- MinGW-32-bit **8.2.0** -- Tcl/Tk **8.6** - -@note -The directory re-organization means that the MinGW compiler is no longer available in the `qtools/bin` directory and therefore the QTools installer for Windows adds to the PATH both `qtools/bin` and `qtools/MinGW/bin` directories. - -Also, this release makes the following changes to the @ref qspy "QSPY host application": - -- The @ref qspy_command "command-line" defaults have been changed such that `qspy` is equivalent to the former `qspy -u -t`. In other words, QSPY by default opens the UDP port and opens the TCP/IP port for Target connection. -- The QSPY host application now supports a new QP-compatibility version 6.6.0, in which the @ref qs_app "Application-Specific QS Trace Records" start at offset 100 instead of 70. This is only activated with the `-v 660` @ref qspy_command "command-line" option, but is in preparation for the future changes in QP/C and QP/C++ frameworks (the upcoming QP/C/C++ 6.6.0). - - - -@section qtools_6_5_1 Version 6.5.1, 2019-06-08 -This release adds the **debug mode** to the @ref qutest_script "QUTest scripting" (in Python). Specifically, you can now provide a special value `DEBUG` to the `qutest.py` Python script launcher, in which case `qutest.py` will start in the **debug mode**, in which it will **not** launch the host executable and will **not** reset the Target. Instead, `qutest.py` will wait for the Target reset and other responses from the Target. - -Additionally, this release improves the @ref install_win32 "QTools installation on Windows". Specifically the Windows installer now installs Python and has been re-designed to automatically setup the `QTOOLS` environment variable and to add `%QTOOLS%\bin;%QTOOLS%\python` to the PATH. The uninstaller reverses these changes. - - - -@section qtools_6_4_0 Version 6.4.0, 2019-02-10 -This release speeds up the QSPY host application by tweaking the timing constants in the TCP and UDP communication interfaces. The resulting QSPY 6.4.0 runs QUTest tests significantly faster (at least twice as fast) as before. - - - -@section qtools_6_3_8 Version 6.3.8, 2018-12-31 -The main purpose of this release is the update of the GNU-ARM toolchain (included in QTools for Windows) to the latest GCC 8. Specifically, this QTools release switches to the official [GNU-ARM Embedded Toolchain for Arm Cortex-M and Cortex-R processors maintained by ARM Ltd.](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm). - -@note -For consistency with the [GNU-ARM Embedded Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm), the toolchain is now located in the directory `qtools\gnu_arm-none-eabi` and contains tools with the prefix **arm-none-eabi-**. This is *different* than the GNU-ARM toolchain used previously (which was located in `qtools\gnu_arm-eabi` and used the tools prefix **arm-eabi-**). This change requires adjusting the existing `Makefiles` and other build commands for the GNU-ARM toolchain, which has been done in the matching QP/C/C++/nano release 6.3.8. - - -Additionally, this release makes further improvements to the "qutest.py" Python interface. Specifically, the skip() command can now be used anywhere in the test scripts to skip the commands. (Previously, the skip() command could only be legitimately used right before the test() command). - - - -@section qtools_6_3_7 Version 6.3.7, 2018-11-19 -This release brings a completely re-designed and simplified Python interface for @ref qutest "QUTest unit testing harness". Specifically, this release adds a new scripting engine called simply @ref qutest_script "qutest.py", which replaces the previous "qspypy". - -@note -The new scripting interface @ref qutest_script "qutest.py" is now the primary supported QUTest scripting interface. The older interfaces, such as TCL ("qutest.tcl") and "qspypy" are still provided in this release, but they are considered *obsolete* and are **not recommended** for writing new test scripts. - - -The new @ref qutest_script "qutest.py Python interface" is a simple single-threaded application that no longer requires PyTest or other such external Python packages, as did "qspypy" previously. The new Python interface is now also compatible with both Python 2 (2.7+) and Python 3 (3.4+), which means that virtually any contemporary Python version without extensions can be used for running QUTest Python scripts. - -@note -The new Python interface "qutest.py" implements a **different** (simpler) structure of @ref qutest_script "QUTest test scripts" than "qspypy" before. Examples of the new Python @ref qutest_tut "test scripts" are provided in the matching QP/C/C++ release 6.3.7. - - -Additionally, this release fixes the problem in the @ref "QSPY host utility" to correctly format signed integers (I8, I16, I32), which didn't work correctly on 64-bit Linux platforms. Also, the QSPY utility on Windows now uses the newer Windows socket library "ws2_32", which replaced the old "wsock32". - -Finally, the QTools release for Windows updates the provided MinGW GNU-C/C++ compiler to version 6.3.0. - - - -@section qtools_6_3_6 Version 6.3.6, 2018-10-03 -The main purpose of this release is to improve the @ref qutest "QUTest" support. Specifically, this release adds a feature of querying and reporting the status of the @ref current_obj() "current objects", such as the current State-Machine (SM), Active-Object (AO), current Memory-Pool(MP), current Event-Queue (EQ), and current Time-Event (TE). The feature impacts the following facilities: - -- the @ref qspy "QSPY host utility" now processes new #QS_QUERY_DATA packet -- the QUTest **Tcl** scripting implements new command command `query_curr()` -- the QUTest **Python** scripting implements new command command `qutest.query_curr()` - -@note -This feature requires matching QP/C/C++ 6.3.6. - - -Also, the following bugs related to Python scripting have been fixed in the @ref qtools_qspypy "qspypy 6.3.6" included in this release: - -- [bug#224 QUTest/Python implementation of qutest.expect() is incomplete](https://sourceforge.net/p/qpc/bugs/224). This improved `qutest.expect()` implementation more closely matches the behavior of the `expect()` directive from Tcl scripting. The modified `qutest.expect()` compares correctly the `%timestamp` fields (as opposed to ignoring them) and also handles special character sequences '?', '*', and [chars] (like the Tcl `string match` command). - -- [bug#225 QUTest/Python ignores the Target-info configuration](https://sourceforge.net/p/qpc/bugs/225). - -- [bug#223 QUTest/Python hangs when attaching to QSPY fails](https://sourceforge.net/p/qpc/bugs/223). - - -@note -If you already have the previous version of @ref qtools_qspypy "qspypy", you need to re-install it by means of the following command:@n -@n -`pip install %%QTOOLS%\qspy` - - -Finally, this release of QTools collection contains the [Unity unit testing harness (framework)](https://github.com/ThrowTheSwitch/Unity). - - - -@section qtools_6_3_4 Version 6.3.4, 2018-08-16 -This release adds the official support for writing QUTest test scripts in Python. -Also, this release fixes some minor typos in error messages generated by QSpy. - - - -@section qtools_6_3_1 Version 6.3.1, 2018-05-24 -This minor release corrects the QSPY utility. Specifically, the @ref qs_app "application-specific output" from the macros QS_FUN(), QS_OBJ() and QS_SIG() contained extra space (' ') before the function/object/signal name. This extra space has been now removed. - -@note -The change might impact existing QUTest test scripts, which parse the QS_FUN(), QS_OBJ() or QS_SIG() output. - -@note -The corrected QS_FUN(), QS_OBJ() and QS_SIG() output (without the extra space) is assumed in the QUTest examples that ship in QP/C/C++ 6.3.1. - - - -@section qtools_6_3_0 Version 6.3.0, 2018-05-10 -This release simplifies the usage of the QUTest (qutest.tcl) and QSpyView (qspyview.tcl) utilities by reducing the number of parameters required by these scripts. Specifically, the "local_port" parameter might be now omitted and still every instance of qutest.tcl / qspyview.tcl will be given a unique local UDP port. Additionally, the "port" parameter has been combined with the "host" parameter in the form host[:port]. - -Here is the new usage of qutest.tcl script: -@code -tclsh qutest.tcl [test-scripts] [host_exe] [host[:port]] [local_port] -@endcode - -Here is the new usage of qspyview.tcl script: -@code -wish qspyview.tcl [extension_script] [host[:port]] [local_port] -@endcode - -For example, to attach to QSPY running on the host 192.168.1.100 and port 7705, you now can launch these scripts as follows: - -@code -tclsh qutest.tcl *.tcl test_fixture.exe 192.168.1.100:7705 -wish qspyview.tcl dpp.tcl 192.168.1.100:7705 -@endcode - -Modified files: -- qspy.tcl -- qspyview.tcl -- qutest.tcl - -Also, this release adds the LMFlash utility to QTools for Windows for flash programming of TM4C MCUs. - -@note -The changes should be transparent for most existing QSpyView and QUTest projects (this include all examples shipped in QP/C and QP/C++). However, projects that run QSPY at non-default UDP ports might need to be adjusted. - - - -@section qtools_6_2_0 Version 6.2.0, 2018-03-13 -This release updates QSPY host utility as well as the `qutest.tcl` and `qspyview.tcl` scripts for the following new QS records introduced in QP/C/C++ 6.2.0: - -- #QS_QF_ACTIVE_DEFER (replaces QS_QF_ACTIVE_ADD) -- #QS_QF_ACTIVE_RECALL (replaces QS_QF_ACTIVE_REMOVE) -- #QS_QF_ACTIVE_RECALL_ATTEMPT (replaces QS_QF_EQUEUE_INIT) -- QS_QF_RESERVED2 (replaces QS_QF_MPOOL_INIT) -- #QS_QF_NEW_REF (replaces QS_QF_TIMEEVT_CTR) -- #QS_MUTEX_LOCK (replaces QS_QF_RESERVED1) -- #QS_MUTEX_UNLOCK (replaces QS_QF_RESERVED0) - -The global filter settings in the `qutest.tcl` and `qspyview.tcl` scripts have been updated to the augmented and re-organized QS trace records. - -Additionally, new commands post() and publish() have been added to the QUTest "testing DSL" (`qutest.tcl` script). Examples of use of these new commands are provided in QP/C/C++ directory `\examples\qutest\defer\`. - - - -@section qtools_6_1_1 Version 6.1.1, 2018-02-06 -This release fixes the following bug in QSPY: - -- [bug#202 QSPY 6.1.0 fails to report target communication errors](https://sourceforge.net/p/qpc/bugs/202) - -Additionally, this release simplifies the format of the external dictionary files, so that they can be potentially generated from .map files or .elf files. The new format no longer requires storing the number of entries in the dictionary and the entries don't need to be sorted by the key-value. The new dictionary format allows also to add comments and empty lines between the dictionary blocks. - -Additionally, the QSPY for POSIX (Linux, MacOS, etc.) corrects the problem with reading input from a file (-f[bin_file] command-line option). - -Finally, this release increases the QCLEAN maximum size limit to 10MB per file. - - - -@section qtools_6_1_0 Version 6.1.0, 2018-01-20 -This release improves the @ref qspy_command "QSPY command-line" option processing by allowing option parameters to be separated by spaces from the option letter (including the optional parameters). For example, the following command-line would not work in the previous version, but will work now: - -qspy -t 6602 - -At the same time, the option parameters can follow immediately the option letter, so the following command line will work as well (backwards compatiblity): - -qspy -t6602 - -This release also improves the handling of external dictionary files in @ref qspy "QSPY host application". Specifically, the `-d` @ref qspy_command "command-line option" has been extended to allow no parameter, in which case external dictionary file is opened automatically as soon as QSPY receives the target reset or target information. When `-d ` option is used, the provided dictionary file is used right away, but the dictioray information might get discarded when the target information does not match the configuration and time-stamp obtained from the dictionary file. - - - -@section qtools_6_0_3 Version 6.0.3, 2017-12-12 -Fixed compilation and linkage on MacOS for qspy, qclean, qfsgen - -Fixed [bug#180 qspyview.tcl for peek is not in sync with the qs_rx parsing of peek](https://sourceforge.net/p/qpc/bugs/180/). - -Used unsigned integer math in qcalc.tcl - -In QTools for Windows, updated the GNU-ARM toolchain to the latest available GCC 7.2.0 adapted from SysProgs Prebuilt GNU toolchain for arm-eabi: - -http://gnutoolchains.com/arm-eabi/ - - - -@section qtools_5_9_3 Version 5.9.3, 2017-07-04 -Fixed bug#175 "QS_QF_ACTIVE_GET & QS_QF_EQUEUE_GET Record Mislabeled in -QSPY Output" (https://sourceforge.net/p/qpc/bugs/175/ ) - -Added bin/qcalc.tcl to the GIT repository (so that it shows up on GitHub). - - - -@section qtools_5_9_1 Version 5.9.1, 2017-05-19 -Added the GNU-ARM (EABI) toolset to the QTools Collection for Windows in the -directory `qtools/gnu_arm-eabi`. The addition of the GNU-ARM toolset matches the -changes made to Makefiles in QP/C/C++/nano 5.9.2. - -To reduce the size of the QTools for Windows download, the self-extracting -archive `qtools_win32_.exe` has been prepared with the 7-Zip utility. - - - -@section qtools_5_9_0 Version 5.9.0, 2017-05-19 -This release adds the @ref qutest "QUTest" (pronounced 'cutest') Unit Testing support to QP/Spy software tracing. Specifically, this release adds a new head-less (console-based) QSPY front-end that, which runs unit tests. - -This release also adapts the @ref qspy "QSPY" host utility to support @ref qutest "QUTest" unit testing. Several new commands have been added and the structure of the -code has been expanded. - -Also, the @ref qspyview "QSpyView" Visualization extension has been moved to the tcl\ sub-directory (the Tcl script tcl\qspyview.tcl). - -The other Quantum Leaps utilities, like @ref qclean "QClean", @ref qfsgen "QFSGen", and QCalc have been updated and greatly improved. - -Finally, all utilities in the QTools collection have been documented in the new QTools Manual available online at: -https://www.state-machine.com/qtools - - - -@section qtools_5_7_0 Version 5.7.0, 2016-09-08 -Corrected QSPY software tracing host application to properly display floating point numbers in user-defined trace records (QS_F32() and QS_F64() macros). The problem was with incompatibility between Microsoft VC++ and GCC floating-point format specifications. In the GCC software build (which produces the QSPY executable in the qtools/bin directory), the MS-VC++ floating point format resulted in all zeros (e.g., 0.0000e+000). - - - -@section qtools_5_6_4 Version 5.6.4, 2016-05-04 -Added QWIN GUI to the collection (sub-directory qwin_gui). - -Updated the QSPY software tracing host application for the QS trace record name changes introduced in QP 5.6.2. - - - -@section qtools_5_5_0 Version 5.5.0, 2015-08-21 -Extended the QSPY software tracing host application for **bi-directional** -communication with embedded targets (output and *input* into the -target). Added a @ref qspy_udp "UDP socket" to QSPY, as an extensibility mechanism for -adding external unit testing, GUIs and other "front-ends" to control the embedded targets. - -Provided new QSpyView Tcl/Tk extension of the QSPY host application for -control testing, and visualization of the real-time tracing data from -embedded targets at real-time. QSpyView enables developers to rapidly -build both GUI-based and "headless" scripts for their specific -applications (see https://www.state-machine.com/qpc/arm-cm_dpp_ek-tm4c123gxl.html) - - - -@section qtools_5_3_1 Version 5.3.1, 2014-04-21 -Corrected the version representation from hex to decimal, to match the change in the QP framework. The version representation missmatch caused problems in parsing newly modified trace records, when the qspy.c implementation was inserted directly into the projects. - - - -@section qtools_5_3_0 Version 5.3.0, 2014-03-31 -Added new trace records to QSPY host application: QS_QEP_TRAN_HIST, QS_QEP_TRAN_EP, and QS_QEP_TRAN_XP. Changed labels for standard records from Q_ENTRY, Q_EXIT, Q_INIT to ENTRY, EXIT, INIT. - - - -@section qtools_5_1_1 Version 5.1.1, 2013-10-15 -Fixed the bug in the QSPY host application, which didn't handle -correctly object/functions/signal names longer than 32 characters. The -name limit has been raised to 64 characters and this version also -correctly truncates the names at the limit without printing any garbage -characters. - - - -@section qtools_5_1_0a Version 5.1.0a, 2013-09-18 -Modified QSPY utility to support changes in QP 5.1.x: - --improved handling of target resets by adding an empty QS record - before the QS_QP_RESET record. The empty record provides the frame - delimiter in case the last record in incomplete, so that the - following QS_QP_RESET record can be recognized. - --improved hanlding of internal object/function/signal dictionaries - so that symbolic information is displayd for all occurrences of an - object/function/signal, for which a dictionary record was received. - - - -@section qtools_5_0_0a Version 5.0.0a, 2013-09-08 -Modified QSPY utility to support changes in QP 5.0.x: - --modified the standard trace records QS_QF_TICK, and QS_QF_TIMEEVT_* - to contain the tick-rate number. - --added trace records QS_TEST_RUN and QS_TEST_FAIL for unit testing. - --added version compatibility level 5.0, whereas specifying version - -v 4.5 runs qspy in the compatibility mode with QP 4.5.x. - --added Find And Replace Text (FART) utility for Windows - - - -@section qtools_4_5_02 Version 4.5.02, 2012-07-21 -Re-designed the QSPY interface to support more flexible parsing -of the trace records in desktop-based simulations (such as Windows -or Qt). Users can provide a custom parsing callback function to -QSPY_config(). Also added QS_RESET() macro to reset the internal -dictionaries (and other cleanup in the future) when the target -resets. - - - -@section qtools_4_5_01 Version 4.5.01, 2012-06-25 -Added the QS_USR_DICTIONARY() entry for storing dictionaries of -the user trace records. Replaced all remaining sprintf() calls -with snprintf(). - - - -@section qtools_4_5_00 Version 4.5.00, 2012-05-26 -Re-designed the implementation of the QSPY host application, so -that it can be convenienty included as part of the QP library. -This allows direct QS tracing output to the screen for QP applications -running on the desktop. The QSPY application has been converted from -C++ to plain C for easier integration with QP/C. - - - -@section qtools_4_3_00 Version 4.3.00, 2011-11-03 -This QSPY version mataches the changes to the critical section -macros made in QP 4.3.00. The QS record names QS_QF_INT_LOCK and -QS_QF_INT_UNLOCK have been replaced with QS_QF_CRIT_ENTRY and -QS_QF_CRIT_EXIT, respectively. - - - -@section qtools_4_2_04 Version 4.2.04, 2011-09-27 -This QSPY version fixes the bug of incorrect reporting function -or object pointers for which the dictionary records are not -provided and which are repeated in one format line (bug #3405904). -For example, trace record AO.FIFO would report (incorrectly) as -follows: - -0014004078 AO.FIFO: Sndr=200009B4 Obj=200009B4 -Evt(Sig=00000009,Obj=200009B4, Pool= 0, Ref= 0) -Queue(nFree= 5, nMin= 5) - -The Sndr= and Obj= are reported to be the same, but they were not. - - - -@section qtools_4_2_01 Version 4.2.01, 2011-08-01 -This QSPY version adds generation of sequence diagrams as -files to be processed by MscGen (www.mcternan.me.uk/mscgen/). -This version adds the option -g to generate .msc -file. - -Also, this version of QSPY for Windows allows COM ports -larger than COM9. - - - -@section qtools_4_2_00 Version 4.2.00, 2011-07-13 -This QSPY version matches the changes made to QS target code in -QP/C/C++ 4.2.xx. These changes include sending the additinal byte -of sender priority in trace records: - -- QS_QF_ACTIVE_POST_FIFO, -- QS_QF_ACTIVE_POST_LIFO, - -Additional changes include sending the poolID and refCtr of events -in two bytes instead of just one byte. The changes affect the -following trace records: - -- QS_QF_ACTIVE_POST_FIFO, -- QS_QF_ACTIVE_POST_LIFO, -- QS_QF_ACTIVE_GET, -- QS_QF_EQUEUE_GET, -- QS_QF_ACTIVE_GET_LAST, -- QS_QF_EQUEUE_GET_LAST, -- QS_QF_EQUEUE_POST_FIFO, -- QS_QF_EQUEUE_POST_LIFO, -- QS_QF_PUBLISH, -- QS_QF_GC_ATTEMPT, and -- QS_QF_GC. - -Also, for compatibility with the QP 4.2.xx, this version changes -the defaults as follows: - -signal size (-S) from 1 byte to 2 bytes, and - -baud rate (-b) from 38400 to 115200 - -This version adds the following trace record: - -QS_QF_TIMEEVT_CTR - -The version also adds compatiblity with 64-bit targets (such -as 64-bit linux). This version can accept 8-byte pointers (both -object pointers and function pointers) as well as 64-bit -integers sent in user-defined trace records. - -This version also adds the hex format for uint32_t integers -sent in the user-defined trace records. - -Finally, this version adds command-line option -v to specify -the corresponding QP version running on the target. The default -version is -v4.2, but by specifying version -v4.1 or -v4.0 will -switch QSPY into the backwards-compatibility mode with the -earlier versions of QP. - - - -@section qtools_4_1_06 Version 4.1.06, 2011-02-09 -This is the intial standalone release of the QSPY host application. -QSPY is still available in the QP/C and QP/C++ distributions, but -other rapid prototyping platforms (such as mbed or Arduino) do not -use the standard QP distributions and have no easy access to the -QSPY tool. For these users, this pre-compiled standalone release -is more convenient. - -*/ diff --git a/doxygen/images/FigQSPY.01.jpg b/doxygen/images/FigQSPY.01.jpg deleted file mode 100644 index 9e1cb76..0000000 Binary files a/doxygen/images/FigQSPY.01.jpg and /dev/null differ diff --git a/doxygen/images/FigQSPY.02.jpg b/doxygen/images/FigQSPY.02.jpg deleted file mode 100644 index 9cf7e34..0000000 Binary files a/doxygen/images/FigQSPY.02.jpg and /dev/null differ diff --git a/doxygen/images/FigQSPY.03.jpg b/doxygen/images/FigQSPY.03.jpg deleted file mode 100644 index 3a2d837..0000000 Binary files a/doxygen/images/FigQSPY.03.jpg and /dev/null differ diff --git a/doxygen/images/FigQSPY.04.jpg b/doxygen/images/FigQSPY.04.jpg deleted file mode 100644 index 9c2a86d..0000000 Binary files a/doxygen/images/FigQSPY.04.jpg and /dev/null differ diff --git a/doxygen/images/FigQSPY.05.jpg b/doxygen/images/FigQSPY.05.jpg deleted file mode 100644 index 5c1ddb5..0000000 Binary files a/doxygen/images/FigQSPY.05.jpg and /dev/null differ diff --git a/doxygen/images/TDDbook-cover.jpg b/doxygen/images/TDDbook-cover.jpg deleted file mode 100644 index 22e42f8..0000000 Binary files a/doxygen/images/TDDbook-cover.jpg and /dev/null differ diff --git a/doxygen/images/blinky_state_off.png b/doxygen/images/blinky_state_off.png deleted file mode 100644 index 7d34c64..0000000 Binary files a/doxygen/images/blinky_state_off.png and /dev/null differ diff --git a/doxygen/images/header_logo_ql.png b/doxygen/images/header_logo_ql.png deleted file mode 100644 index 987822a..0000000 Binary files a/doxygen/images/header_logo_ql.png and /dev/null differ diff --git a/doxygen/images/help_using.jpg b/doxygen/images/help_using.jpg deleted file mode 100644 index cfbdae9..0000000 Binary files a/doxygen/images/help_using.jpg and /dev/null differ diff --git a/doxygen/images/laptop.jpg b/doxygen/images/laptop.jpg deleted file mode 100644 index 147c61c..0000000 Binary files a/doxygen/images/laptop.jpg and /dev/null differ diff --git a/doxygen/images/ledbar5.gif b/doxygen/images/ledbar5.gif deleted file mode 100644 index e2e4c4d..0000000 Binary files a/doxygen/images/ledbar5.gif and /dev/null differ diff --git a/doxygen/images/ledbar5.psd b/doxygen/images/ledbar5.psd deleted file mode 100644 index 71e06f1..0000000 Binary files a/doxygen/images/ledbar5.psd and /dev/null differ diff --git a/doxygen/images/ledbar5_big.gif b/doxygen/images/ledbar5_big.gif deleted file mode 100644 index a591769..0000000 Binary files a/doxygen/images/ledbar5_big.gif and /dev/null differ diff --git a/doxygen/images/logo_python27-python3.gif b/doxygen/images/logo_python27-python3.gif deleted file mode 100644 index f39e509..0000000 Binary files a/doxygen/images/logo_python27-python3.gif and /dev/null differ diff --git a/doxygen/images/logo_python27-python3.jpg b/doxygen/images/logo_python27-python3.jpg deleted file mode 100644 index 2a5b96a..0000000 Binary files a/doxygen/images/logo_python27-python3.jpg and /dev/null differ diff --git a/doxygen/images/logo_ql.png b/doxygen/images/logo_ql.png deleted file mode 100644 index dab80d0..0000000 Binary files a/doxygen/images/logo_ql.png and /dev/null differ diff --git a/doxygen/images/logo_ql_TM.jpg b/doxygen/images/logo_ql_TM.jpg deleted file mode 100644 index 9963117..0000000 Binary files a/doxygen/images/logo_ql_TM.jpg and /dev/null differ diff --git a/doxygen/images/logo_qp.gif b/doxygen/images/logo_qp.gif deleted file mode 100644 index 885a685..0000000 Binary files a/doxygen/images/logo_qp.gif and /dev/null differ diff --git a/doxygen/images/logo_qspy.gif b/doxygen/images/logo_qspy.gif deleted file mode 100644 index 050e26a..0000000 Binary files a/doxygen/images/logo_qspy.gif and /dev/null differ diff --git a/doxygen/images/logo_qspy.png b/doxygen/images/logo_qspy.png deleted file mode 100644 index cc0297a..0000000 Binary files a/doxygen/images/logo_qspy.png and /dev/null differ diff --git a/doxygen/images/logo_qspy128.gif b/doxygen/images/logo_qspy128.gif deleted file mode 100644 index e2035bd..0000000 Binary files a/doxygen/images/logo_qspy128.gif and /dev/null differ diff --git a/doxygen/images/logo_qwin256.jpg b/doxygen/images/logo_qwin256.jpg deleted file mode 100644 index 9a67951..0000000 Binary files a/doxygen/images/logo_qwin256.jpg and /dev/null differ diff --git a/doxygen/images/mscgen_dpp.gif b/doxygen/images/mscgen_dpp.gif deleted file mode 100644 index 8ea355b..0000000 Binary files a/doxygen/images/mscgen_dpp.gif and /dev/null differ diff --git a/doxygen/images/mscgen_dpp.png b/doxygen/images/mscgen_dpp.png deleted file mode 100644 index 7fa5af4..0000000 Binary files a/doxygen/images/mscgen_dpp.png and /dev/null differ diff --git a/doxygen/images/platforms.png b/doxygen/images/platforms.png deleted file mode 100644 index 8ef044f..0000000 Binary files a/doxygen/images/platforms.png and /dev/null differ diff --git a/doxygen/images/qcalc.png b/doxygen/images/qcalc.png deleted file mode 100644 index 9e7e243..0000000 Binary files a/doxygen/images/qcalc.png and /dev/null differ diff --git a/doxygen/images/qcalc_lnk.png b/doxygen/images/qcalc_lnk.png deleted file mode 100644 index ed529cb..0000000 Binary files a/doxygen/images/qcalc_lnk.png and /dev/null differ diff --git a/doxygen/images/qclean.png b/doxygen/images/qclean.png deleted file mode 100644 index 0ec9dee..0000000 Binary files a/doxygen/images/qclean.png and /dev/null differ diff --git a/doxygen/images/qclean_dirty.png b/doxygen/images/qclean_dirty.png deleted file mode 100644 index dfee514..0000000 Binary files a/doxygen/images/qclean_dirty.png and /dev/null differ diff --git a/doxygen/images/qclean_posix.png b/doxygen/images/qclean_posix.png deleted file mode 100644 index 49accba..0000000 Binary files a/doxygen/images/qclean_posix.png and /dev/null differ diff --git a/doxygen/images/qclean_run.png b/doxygen/images/qclean_run.png deleted file mode 100644 index ad356e7..0000000 Binary files a/doxygen/images/qclean_run.png and /dev/null differ diff --git a/doxygen/images/qfsgen_run.png b/doxygen/images/qfsgen_run.png deleted file mode 100644 index e344909..0000000 Binary files a/doxygen/images/qfsgen_run.png and /dev/null differ diff --git a/doxygen/images/qhsmtst_qm.png b/doxygen/images/qhsmtst_qm.png deleted file mode 100644 index bcdeae5..0000000 Binary files a/doxygen/images/qhsmtst_qm.png and /dev/null differ diff --git a/doxygen/images/qpspy0.gif b/doxygen/images/qpspy0.gif deleted file mode 100644 index e63f518..0000000 Binary files a/doxygen/images/qpspy0.gif and /dev/null differ diff --git a/doxygen/images/qpspy1.gif b/doxygen/images/qpspy1.gif deleted file mode 100644 index 0c3ac40..0000000 Binary files a/doxygen/images/qpspy1.gif and /dev/null differ diff --git a/doxygen/images/qpspy_exa.gif b/doxygen/images/qpspy_exa.gif deleted file mode 100644 index 788129c..0000000 Binary files a/doxygen/images/qpspy_exa.gif and /dev/null differ diff --git a/doxygen/images/qpspy_exa.png b/doxygen/images/qpspy_exa.png deleted file mode 100644 index 4e99472..0000000 Binary files a/doxygen/images/qpspy_exa.png and /dev/null differ diff --git a/doxygen/images/qspy.png b/doxygen/images/qspy.png deleted file mode 100644 index 9bcbb84..0000000 Binary files a/doxygen/images/qspy.png and /dev/null differ diff --git a/doxygen/images/qspy1.gif b/doxygen/images/qspy1.gif deleted file mode 100644 index 8d7be51..0000000 Binary files a/doxygen/images/qspy1.gif and /dev/null differ diff --git a/doxygen/images/qspy10.gif b/doxygen/images/qspy10.gif deleted file mode 100644 index f3253aa..0000000 Binary files a/doxygen/images/qspy10.gif and /dev/null differ diff --git a/doxygen/images/qspy11.gif b/doxygen/images/qspy11.gif deleted file mode 100644 index f6ea007..0000000 Binary files a/doxygen/images/qspy11.gif and /dev/null differ diff --git a/doxygen/images/qspy12.gif b/doxygen/images/qspy12.gif deleted file mode 100644 index 15d945f..0000000 Binary files a/doxygen/images/qspy12.gif and /dev/null differ diff --git a/doxygen/images/qspy2.gif b/doxygen/images/qspy2.gif deleted file mode 100644 index 82a1907..0000000 Binary files a/doxygen/images/qspy2.gif and /dev/null differ diff --git a/doxygen/images/qspy3.gif b/doxygen/images/qspy3.gif deleted file mode 100644 index 0ee5eff..0000000 Binary files a/doxygen/images/qspy3.gif and /dev/null differ diff --git a/doxygen/images/qspy4.gif b/doxygen/images/qspy4.gif deleted file mode 100644 index e3ae673..0000000 Binary files a/doxygen/images/qspy4.gif and /dev/null differ diff --git a/doxygen/images/qspy5.gif b/doxygen/images/qspy5.gif deleted file mode 100644 index 7e5874f..0000000 Binary files a/doxygen/images/qspy5.gif and /dev/null differ diff --git a/doxygen/images/qspy6.gif b/doxygen/images/qspy6.gif deleted file mode 100644 index 7d7132d..0000000 Binary files a/doxygen/images/qspy6.gif and /dev/null differ diff --git a/doxygen/images/qspy8.gif b/doxygen/images/qspy8.gif deleted file mode 100644 index e74e334..0000000 Binary files a/doxygen/images/qspy8.gif and /dev/null differ diff --git a/doxygen/images/qspy9.gif b/doxygen/images/qspy9.gif deleted file mode 100644 index bdb9a82..0000000 Binary files a/doxygen/images/qspy9.gif and /dev/null differ diff --git a/doxygen/images/qspy_app.gif b/doxygen/images/qspy_app.gif deleted file mode 100644 index a3b89b6..0000000 Binary files a/doxygen/images/qspy_app.gif and /dev/null differ diff --git a/doxygen/images/qspy_banner.jpg b/doxygen/images/qspy_banner.jpg deleted file mode 100644 index 0db821f..0000000 Binary files a/doxygen/images/qspy_banner.jpg and /dev/null differ diff --git a/doxygen/images/qspy_cat.png b/doxygen/images/qspy_cat.png deleted file mode 100644 index 403d6a2..0000000 Binary files a/doxygen/images/qspy_cat.png and /dev/null differ diff --git a/doxygen/images/qspy_comm.gif b/doxygen/images/qspy_comm.gif deleted file mode 100644 index fa471fc..0000000 Binary files a/doxygen/images/qspy_comm.gif and /dev/null differ diff --git a/doxygen/images/qspy_dir.gif b/doxygen/images/qspy_dir.gif deleted file mode 100644 index eb17468..0000000 Binary files a/doxygen/images/qspy_dir.gif and /dev/null differ diff --git a/doxygen/images/qspy_dpp.png b/doxygen/images/qspy_dpp.png deleted file mode 100644 index a744f84..0000000 Binary files a/doxygen/images/qspy_dpp.png and /dev/null differ diff --git a/doxygen/images/qspy_embed.gif b/doxygen/images/qspy_embed.gif deleted file mode 100644 index 13d9912..0000000 Binary files a/doxygen/images/qspy_embed.gif and /dev/null differ diff --git a/doxygen/images/qspy_help.gif b/doxygen/images/qspy_help.gif deleted file mode 100644 index f5cb304..0000000 Binary files a/doxygen/images/qspy_help.gif and /dev/null differ diff --git a/doxygen/images/qspy_qutest.gif b/doxygen/images/qspy_qutest.gif deleted file mode 100644 index 5ed45db..0000000 Binary files a/doxygen/images/qspy_qutest.gif and /dev/null differ diff --git a/doxygen/images/qspy_qview.gif b/doxygen/images/qspy_qview.gif deleted file mode 100644 index 9380b6e..0000000 Binary files a/doxygen/images/qspy_qview.gif and /dev/null differ diff --git a/doxygen/images/qspy_screen.gif b/doxygen/images/qspy_screen.gif deleted file mode 100644 index 38d155c..0000000 Binary files a/doxygen/images/qspy_screen.gif and /dev/null differ diff --git a/doxygen/images/qspy_screen.png b/doxygen/images/qspy_screen.png deleted file mode 100644 index 96e1b9f..0000000 Binary files a/doxygen/images/qspy_screen.png and /dev/null differ diff --git a/doxygen/images/qspy_udp.gif b/doxygen/images/qspy_udp.gif deleted file mode 100644 index 8e92ccc..0000000 Binary files a/doxygen/images/qspy_udp.gif and /dev/null differ diff --git a/doxygen/images/qtools_banner.jpg b/doxygen/images/qtools_banner.jpg deleted file mode 100644 index c640936..0000000 Binary files a/doxygen/images/qtools_banner.jpg and /dev/null differ diff --git a/doxygen/images/qtools_env1.png b/doxygen/images/qtools_env1.png deleted file mode 100644 index 595d764..0000000 Binary files a/doxygen/images/qtools_env1.png and /dev/null differ diff --git a/doxygen/images/qtools_install.jpg b/doxygen/images/qtools_install.jpg deleted file mode 100644 index 9dd8a5b..0000000 Binary files a/doxygen/images/qtools_install.jpg and /dev/null differ diff --git a/doxygen/images/qutest-colors.png b/doxygen/images/qutest-colors.png deleted file mode 100644 index fad3d08..0000000 Binary files a/doxygen/images/qutest-colors.png and /dev/null differ diff --git a/doxygen/images/qutest_banner.jpg b/doxygen/images/qutest_banner.jpg deleted file mode 100644 index 5ec2981..0000000 Binary files a/doxygen/images/qutest_banner.jpg and /dev/null differ diff --git a/doxygen/images/qutest_blinky_qm.png b/doxygen/images/qutest_blinky_qm.png deleted file mode 100644 index f8ff0b3..0000000 Binary files a/doxygen/images/qutest_blinky_qm.png and /dev/null differ diff --git a/doxygen/images/qutest_complex.gif b/doxygen/images/qutest_complex.gif deleted file mode 100644 index 88c65db..0000000 Binary files a/doxygen/images/qutest_complex.gif and /dev/null differ diff --git a/doxygen/images/qutest_ex.gif b/doxygen/images/qutest_ex.gif deleted file mode 100644 index ab69f03..0000000 Binary files a/doxygen/images/qutest_ex.gif and /dev/null differ diff --git a/doxygen/images/qutest_ex.png b/doxygen/images/qutest_ex.png deleted file mode 100644 index a7524fe..0000000 Binary files a/doxygen/images/qutest_ex.png and /dev/null differ diff --git a/doxygen/images/qutest_host.gif b/doxygen/images/qutest_host.gif deleted file mode 100644 index 93b5945..0000000 Binary files a/doxygen/images/qutest_host.gif and /dev/null differ diff --git a/doxygen/images/qutest_mock.gif b/doxygen/images/qutest_mock.gif deleted file mode 100644 index 1235684..0000000 Binary files a/doxygen/images/qutest_mock.gif and /dev/null differ diff --git a/doxygen/images/qutest_noreset.gif b/doxygen/images/qutest_noreset.gif deleted file mode 100644 index 2fc0362..0000000 Binary files a/doxygen/images/qutest_noreset.gif and /dev/null differ diff --git a/doxygen/images/qutest_pause.gif b/doxygen/images/qutest_pause.gif deleted file mode 100644 index c5249a8..0000000 Binary files a/doxygen/images/qutest_pause.gif and /dev/null differ diff --git a/doxygen/images/qutest_reset.gif b/doxygen/images/qutest_reset.gif deleted file mode 100644 index 232ec7d..0000000 Binary files a/doxygen/images/qutest_reset.gif and /dev/null differ diff --git a/doxygen/images/qutest_rtc.gif b/doxygen/images/qutest_rtc.gif deleted file mode 100644 index 3650dbe..0000000 Binary files a/doxygen/images/qutest_rtc.gif and /dev/null differ diff --git a/doxygen/images/qutest_simple.gif b/doxygen/images/qutest_simple.gif deleted file mode 100644 index d5d1879..0000000 Binary files a/doxygen/images/qutest_simple.gif and /dev/null differ diff --git a/doxygen/images/qutest_targ.gif b/doxygen/images/qutest_targ.gif deleted file mode 100644 index 8cec03f..0000000 Binary files a/doxygen/images/qutest_targ.gif and /dev/null differ diff --git a/doxygen/images/qview.gif b/doxygen/images/qview.gif deleted file mode 100644 index 1f6b781..0000000 Binary files a/doxygen/images/qview.gif and /dev/null differ diff --git a/doxygen/images/qview.jpg b/doxygen/images/qview.jpg deleted file mode 100644 index 7935a37..0000000 Binary files a/doxygen/images/qview.jpg and /dev/null differ diff --git a/doxygen/images/qview.png b/doxygen/images/qview.png deleted file mode 100644 index 60c437d..0000000 Binary files a/doxygen/images/qview.png and /dev/null differ diff --git a/doxygen/images/qview1.png b/doxygen/images/qview1.png deleted file mode 100644 index b1a3b06..0000000 Binary files a/doxygen/images/qview1.png and /dev/null differ diff --git a/doxygen/images/qview_ao.png b/doxygen/images/qview_ao.png deleted file mode 100644 index a51c468..0000000 Binary files a/doxygen/images/qview_ao.png and /dev/null differ diff --git a/doxygen/images/qview_attach.gif b/doxygen/images/qview_attach.gif deleted file mode 100644 index 094a5c8..0000000 Binary files a/doxygen/images/qview_attach.gif and /dev/null differ diff --git a/doxygen/images/qview_banner.jpg b/doxygen/images/qview_banner.jpg deleted file mode 100644 index 02076c1..0000000 Binary files a/doxygen/images/qview_banner.jpg and /dev/null differ diff --git a/doxygen/images/qview_before.gif b/doxygen/images/qview_before.gif deleted file mode 100644 index 857acaf..0000000 Binary files a/doxygen/images/qview_before.gif and /dev/null differ diff --git a/doxygen/images/qview_canv_dpp.gif b/doxygen/images/qview_canv_dpp.gif deleted file mode 100644 index 547f430..0000000 Binary files a/doxygen/images/qview_canv_dpp.gif and /dev/null differ diff --git a/doxygen/images/qview_canvas.gif b/doxygen/images/qview_canvas.gif deleted file mode 100644 index 4216769..0000000 Binary files a/doxygen/images/qview_canvas.gif and /dev/null differ diff --git a/doxygen/images/qview_canvas.png b/doxygen/images/qview_canvas.png deleted file mode 100644 index a93a8fe..0000000 Binary files a/doxygen/images/qview_canvas.png and /dev/null differ diff --git a/doxygen/images/qview_cmd.gif b/doxygen/images/qview_cmd.gif deleted file mode 100644 index 35fc6b3..0000000 Binary files a/doxygen/images/qview_cmd.gif and /dev/null differ diff --git a/doxygen/images/qview_cmd.png b/doxygen/images/qview_cmd.png deleted file mode 100644 index 96cebe0..0000000 Binary files a/doxygen/images/qview_cmd.png and /dev/null differ diff --git a/doxygen/images/qview_cmd_dlg.gif b/doxygen/images/qview_cmd_dlg.gif deleted file mode 100644 index c31d47c..0000000 Binary files a/doxygen/images/qview_cmd_dlg.gif and /dev/null differ diff --git a/doxygen/images/qview_cmd_peek.gif b/doxygen/images/qview_cmd_peek.gif deleted file mode 100644 index 4410dde..0000000 Binary files a/doxygen/images/qview_cmd_peek.gif and /dev/null differ diff --git a/doxygen/images/qview_cmd_poke.gif b/doxygen/images/qview_cmd_poke.gif deleted file mode 100644 index 90b13ac..0000000 Binary files a/doxygen/images/qview_cmd_poke.gif and /dev/null differ diff --git a/doxygen/images/qview_commands.gif b/doxygen/images/qview_commands.gif deleted file mode 100644 index cf0c7e4..0000000 Binary files a/doxygen/images/qview_commands.gif and /dev/null differ diff --git a/doxygen/images/qview_commands.png b/doxygen/images/qview_commands.png deleted file mode 100644 index e875fb3..0000000 Binary files a/doxygen/images/qview_commands.png and /dev/null differ diff --git a/doxygen/images/qview_curr.gif b/doxygen/images/qview_curr.gif deleted file mode 100644 index 93ba7bd..0000000 Binary files a/doxygen/images/qview_curr.gif and /dev/null differ diff --git a/doxygen/images/qview_curr_dlg.gif b/doxygen/images/qview_curr_dlg.gif deleted file mode 100644 index 4fe44c9..0000000 Binary files a/doxygen/images/qview_curr_dlg.gif and /dev/null differ diff --git a/doxygen/images/qview_cust.gif b/doxygen/images/qview_cust.gif deleted file mode 100644 index 1eaeb47..0000000 Binary files a/doxygen/images/qview_cust.gif and /dev/null differ diff --git a/doxygen/images/qview_custom.gif b/doxygen/images/qview_custom.gif deleted file mode 100644 index 1261b0e..0000000 Binary files a/doxygen/images/qview_custom.gif and /dev/null differ diff --git a/doxygen/images/qview_dpp-fedora.gif b/doxygen/images/qview_dpp-fedora.gif deleted file mode 100644 index cb8a1f1..0000000 Binary files a/doxygen/images/qview_dpp-fedora.gif and /dev/null differ diff --git a/doxygen/images/qview_event.gif b/doxygen/images/qview_event.gif deleted file mode 100644 index 3b7760e..0000000 Binary files a/doxygen/images/qview_event.gif and /dev/null differ diff --git a/doxygen/images/qview_event.png b/doxygen/images/qview_event.png deleted file mode 100644 index ca62be6..0000000 Binary files a/doxygen/images/qview_event.png and /dev/null differ diff --git a/doxygen/images/qview_events.gif b/doxygen/images/qview_events.gif deleted file mode 100644 index db29dc3..0000000 Binary files a/doxygen/images/qview_events.gif and /dev/null differ diff --git a/doxygen/images/qview_evt_dlg.gif b/doxygen/images/qview_evt_dlg.gif deleted file mode 100644 index fb7d9eb..0000000 Binary files a/doxygen/images/qview_evt_dlg.gif and /dev/null differ diff --git a/doxygen/images/qview_ex.gif b/doxygen/images/qview_ex.gif deleted file mode 100644 index 2cb54dc..0000000 Binary files a/doxygen/images/qview_ex.gif and /dev/null differ diff --git a/doxygen/images/qview_ex.png b/doxygen/images/qview_ex.png deleted file mode 100644 index 5440aac..0000000 Binary files a/doxygen/images/qview_ex.png and /dev/null differ diff --git a/doxygen/images/qview_file.gif b/doxygen/images/qview_file.gif deleted file mode 100644 index e9598d5..0000000 Binary files a/doxygen/images/qview_file.gif and /dev/null differ diff --git a/doxygen/images/qview_filters.gif b/doxygen/images/qview_filters.gif deleted file mode 100644 index fa98c6f..0000000 Binary files a/doxygen/images/qview_filters.gif and /dev/null differ diff --git a/doxygen/images/qview_glob.gif b/doxygen/images/qview_glob.gif deleted file mode 100644 index 2420636..0000000 Binary files a/doxygen/images/qview_glob.gif and /dev/null differ diff --git a/doxygen/images/qview_glob_dlg.gif b/doxygen/images/qview_glob_dlg.gif deleted file mode 100644 index 925c7b5..0000000 Binary files a/doxygen/images/qview_glob_dlg.gif and /dev/null differ diff --git a/doxygen/images/qview_global.gif b/doxygen/images/qview_global.gif deleted file mode 100644 index 6490d64..0000000 Binary files a/doxygen/images/qview_global.gif and /dev/null differ diff --git a/doxygen/images/qview_help.gif b/doxygen/images/qview_help.gif deleted file mode 100644 index 1f237e6..0000000 Binary files a/doxygen/images/qview_help.gif and /dev/null differ diff --git a/doxygen/images/qview_known.gif b/doxygen/images/qview_known.gif deleted file mode 100644 index 9dd1fc8..0000000 Binary files a/doxygen/images/qview_known.gif and /dev/null differ diff --git a/doxygen/images/qview_loc.gif b/doxygen/images/qview_loc.gif deleted file mode 100644 index 8351cd3..0000000 Binary files a/doxygen/images/qview_loc.gif and /dev/null differ diff --git a/doxygen/images/qview_loc_dlg.gif b/doxygen/images/qview_loc_dlg.gif deleted file mode 100644 index 2a6796b..0000000 Binary files a/doxygen/images/qview_loc_dlg.gif and /dev/null differ diff --git a/doxygen/images/qview_local.png b/doxygen/images/qview_local.png deleted file mode 100644 index 63ae24b..0000000 Binary files a/doxygen/images/qview_local.png and /dev/null differ diff --git a/doxygen/images/qview_menu.gif b/doxygen/images/qview_menu.gif deleted file mode 100644 index 79f0c53..0000000 Binary files a/doxygen/images/qview_menu.gif and /dev/null differ diff --git a/doxygen/images/qview_no_text.gif b/doxygen/images/qview_no_text.gif deleted file mode 100644 index b339569..0000000 Binary files a/doxygen/images/qview_no_text.gif and /dev/null differ diff --git a/doxygen/images/qview_peek.png b/doxygen/images/qview_peek.png deleted file mode 100644 index fdbc82e..0000000 Binary files a/doxygen/images/qview_peek.png and /dev/null differ diff --git a/doxygen/images/qview_poke.png b/doxygen/images/qview_poke.png deleted file mode 100644 index 75c1da9..0000000 Binary files a/doxygen/images/qview_poke.png and /dev/null differ diff --git a/doxygen/images/qview_screen.png b/doxygen/images/qview_screen.png deleted file mode 100644 index 15db68c..0000000 Binary files a/doxygen/images/qview_screen.png and /dev/null differ diff --git a/doxygen/images/qview_shortcut.gif b/doxygen/images/qview_shortcut.gif deleted file mode 100644 index 0606eff..0000000 Binary files a/doxygen/images/qview_shortcut.gif and /dev/null differ diff --git a/doxygen/images/qview_unknonw.gif b/doxygen/images/qview_unknonw.gif deleted file mode 100644 index 770abb5..0000000 Binary files a/doxygen/images/qview_unknonw.gif and /dev/null differ diff --git a/doxygen/images/qview_unknown.gif b/doxygen/images/qview_unknown.gif deleted file mode 100644 index b7a61f4..0000000 Binary files a/doxygen/images/qview_unknown.gif and /dev/null differ diff --git a/doxygen/images/qview_view.gif b/doxygen/images/qview_view.gif deleted file mode 100644 index 86df474..0000000 Binary files a/doxygen/images/qview_view.gif and /dev/null differ diff --git a/doxygen/images/qwin.png b/doxygen/images/qwin.png deleted file mode 100644 index 47e2697..0000000 Binary files a/doxygen/images/qwin.png and /dev/null differ diff --git a/doxygen/images/qwin_ani.gif b/doxygen/images/qwin_ani.gif deleted file mode 100644 index 68d7265..0000000 Binary files a/doxygen/images/qwin_ani.gif and /dev/null differ diff --git a/doxygen/images/seq_defer.gif b/doxygen/images/seq_defer.gif deleted file mode 100644 index 2141a7a..0000000 Binary files a/doxygen/images/seq_defer.gif and /dev/null differ diff --git a/doxygen/images/seq_dpp.gif b/doxygen/images/seq_dpp.gif deleted file mode 100644 index cadbe5f..0000000 Binary files a/doxygen/images/seq_dpp.gif and /dev/null differ diff --git a/doxygen/images/session.png b/doxygen/images/session.png deleted file mode 100644 index a8cab6a..0000000 Binary files a/doxygen/images/session.png and /dev/null differ diff --git a/doxygen/images/sprintf_qspy.png b/doxygen/images/sprintf_qspy.png deleted file mode 100644 index 73659b2..0000000 Binary files a/doxygen/images/sprintf_qspy.png and /dev/null differ diff --git a/doxygen/images/sprintf_qutest.png b/doxygen/images/sprintf_qutest.png deleted file mode 100644 index ad74604..0000000 Binary files a/doxygen/images/sprintf_qutest.png and /dev/null differ diff --git a/doxygen/images/svg.svg b/doxygen/images/svg.svg deleted file mode 100644 index 21c97e3..0000000 --- a/doxygen/images/svg.svg +++ /dev/null @@ -1,9 +0,0 @@ -1Штамп чертежаИзм.Лист№Докум.Подп.ДатаРазраб.Пров.Т.Контр.Н.Контр.Утв.Лит.МассаМасштабЛистЛистов1КопировалФормат A0Вид 1 diff --git a/doxygen/images/test_blinky.png b/doxygen/images/test_blinky.png deleted file mode 100644 index 4cfd611..0000000 Binary files a/doxygen/images/test_blinky.png and /dev/null differ diff --git a/doxygen/images/test_dpp.png b/doxygen/images/test_dpp.png deleted file mode 100644 index a6e3585..0000000 Binary files a/doxygen/images/test_dpp.png and /dev/null differ diff --git a/doxygen/images/test_dpp_linux.png b/doxygen/images/test_dpp_linux.png deleted file mode 100644 index e098350..0000000 Binary files a/doxygen/images/test_dpp_linux.png and /dev/null differ diff --git a/doxygen/images/test_dpp_win.png b/doxygen/images/test_dpp_win.png deleted file mode 100644 index 4aa76e6..0000000 Binary files a/doxygen/images/test_dpp_win.png and /dev/null differ diff --git a/doxygen/images/test_flash.png b/doxygen/images/test_flash.png deleted file mode 100644 index 53d918f..0000000 Binary files a/doxygen/images/test_flash.png and /dev/null differ diff --git a/doxygen/images/test_leddriver.png b/doxygen/images/test_leddriver.png deleted file mode 100644 index b598b1d..0000000 Binary files a/doxygen/images/test_leddriver.png and /dev/null differ diff --git a/doxygen/images/test_philo.png b/doxygen/images/test_philo.png deleted file mode 100644 index cd24a03..0000000 Binary files a/doxygen/images/test_philo.png and /dev/null differ diff --git a/doxygen/images/test_qhsm.png b/doxygen/images/test_qhsm.png deleted file mode 100644 index 6c7315a..0000000 Binary files a/doxygen/images/test_qhsm.png and /dev/null differ diff --git a/doxygen/images/test_sprintf.png b/doxygen/images/test_sprintf.png deleted file mode 100644 index df6a4f4..0000000 Binary files a/doxygen/images/test_sprintf.png and /dev/null differ diff --git a/doxygen/images/tracing.png b/doxygen/images/tracing.png deleted file mode 100644 index 0f00102..0000000 Binary files a/doxygen/images/tracing.png and /dev/null differ diff --git a/doxygen/images/under_construction.jpg b/doxygen/images/under_construction.jpg deleted file mode 100644 index ba733f0..0000000 Binary files a/doxygen/images/under_construction.jpg and /dev/null differ diff --git a/doxygen/images/unity_basic_qutest.png b/doxygen/images/unity_basic_qutest.png deleted file mode 100644 index 9237b19..0000000 Binary files a/doxygen/images/unity_basic_qutest.png and /dev/null differ diff --git a/doxygen/images/unity_basic_unity.png b/doxygen/images/unity_basic_unity.png deleted file mode 100644 index 1228670..0000000 Binary files a/doxygen/images/unity_basic_unity.png and /dev/null differ diff --git a/doxygen/images/unity_mock_qutest.png b/doxygen/images/unity_mock_qutest.png deleted file mode 100644 index dd2c621..0000000 Binary files a/doxygen/images/unity_mock_qutest.png and /dev/null differ diff --git a/doxygen/images/unity_mock_unity.png b/doxygen/images/unity_mock_unity.png deleted file mode 100644 index ad04d20..0000000 Binary files a/doxygen/images/unity_mock_unity.png and /dev/null differ diff --git a/doxygen/img/AN_Q_SPY_Software_Tracing.jpg b/doxygen/img/AN_Q_SPY_Software_Tracing.jpg deleted file mode 100644 index 4ab1648..0000000 Binary files a/doxygen/img/AN_Q_SPY_Software_Tracing.jpg and /dev/null differ diff --git a/doxygen/img/board.png b/doxygen/img/board.png deleted file mode 100644 index ea9d183..0000000 Binary files a/doxygen/img/board.png and /dev/null differ diff --git a/doxygen/img/bug.gif b/doxygen/img/bug.gif deleted file mode 100644 index e508704..0000000 Binary files a/doxygen/img/bug.gif and /dev/null differ diff --git a/doxygen/img/bug.png b/doxygen/img/bug.png deleted file mode 100644 index ced6db5..0000000 Binary files a/doxygen/img/bug.png and /dev/null differ diff --git a/doxygen/img/checkboxoff.png b/doxygen/img/checkboxoff.png deleted file mode 100644 index a68a321..0000000 Binary files a/doxygen/img/checkboxoff.png and /dev/null differ diff --git a/doxygen/img/checkboxon.png b/doxygen/img/checkboxon.png deleted file mode 100644 index be666df..0000000 Binary files a/doxygen/img/checkboxon.png and /dev/null differ diff --git a/doxygen/img/extern.png b/doxygen/img/extern.png deleted file mode 100644 index acf260f..0000000 Binary files a/doxygen/img/extern.png and /dev/null differ diff --git a/doxygen/img/file.png b/doxygen/img/file.png deleted file mode 100644 index d2ce7dd..0000000 Binary files a/doxygen/img/file.png and /dev/null differ diff --git a/doxygen/img/file_c.png b/doxygen/img/file_c.png deleted file mode 100644 index 15aaa86..0000000 Binary files a/doxygen/img/file_c.png and /dev/null differ diff --git a/doxygen/img/file_cpp.png b/doxygen/img/file_cpp.png deleted file mode 100644 index a324196..0000000 Binary files a/doxygen/img/file_cpp.png and /dev/null differ diff --git a/doxygen/img/file_doc.png b/doxygen/img/file_doc.png deleted file mode 100644 index 803bd08..0000000 Binary files a/doxygen/img/file_doc.png and /dev/null differ diff --git a/doxygen/img/file_h.png b/doxygen/img/file_h.png deleted file mode 100644 index 6fe57c8..0000000 Binary files a/doxygen/img/file_h.png and /dev/null differ diff --git a/doxygen/img/file_mak.png b/doxygen/img/file_mak.png deleted file mode 100644 index 2fe5cc4..0000000 Binary files a/doxygen/img/file_mak.png and /dev/null differ diff --git a/doxygen/img/file_pdf.png b/doxygen/img/file_pdf.png deleted file mode 100644 index 44d3acd..0000000 Binary files a/doxygen/img/file_pdf.png and /dev/null differ diff --git a/doxygen/img/file_py.png b/doxygen/img/file_py.png deleted file mode 100644 index 6e01e7f..0000000 Binary files a/doxygen/img/file_py.png and /dev/null differ diff --git a/doxygen/img/file_qm.png b/doxygen/img/file_qm.png deleted file mode 100644 index d1e90ae..0000000 Binary files a/doxygen/img/file_qm.png and /dev/null differ diff --git a/doxygen/img/file_qmp.png b/doxygen/img/file_qmp.png deleted file mode 100644 index 5cffd8f..0000000 Binary files a/doxygen/img/file_qmp.png and /dev/null differ diff --git a/doxygen/img/file_tcl.png b/doxygen/img/file_tcl.png deleted file mode 100644 index 8f5e337..0000000 Binary files a/doxygen/img/file_tcl.png and /dev/null differ diff --git a/doxygen/img/file_wish.png b/doxygen/img/file_wish.png deleted file mode 100644 index 54630ce..0000000 Binary files a/doxygen/img/file_wish.png and /dev/null differ diff --git a/doxygen/img/folder.png b/doxygen/img/folder.png deleted file mode 100644 index 78ad6cd..0000000 Binary files a/doxygen/img/folder.png and /dev/null differ diff --git a/doxygen/img/forbidden.png b/doxygen/img/forbidden.png deleted file mode 100644 index c00505d..0000000 Binary files a/doxygen/img/forbidden.png and /dev/null differ diff --git a/doxygen/img/github-corner.png b/doxygen/img/github-corner.png deleted file mode 100644 index 4ce398e..0000000 Binary files a/doxygen/img/github-corner.png and /dev/null differ diff --git a/doxygen/img/github-qt.png b/doxygen/img/github-qt.png deleted file mode 100644 index 7618c55..0000000 Binary files a/doxygen/img/github-qt.png and /dev/null differ diff --git a/doxygen/img/header_bg.png b/doxygen/img/header_bg.png deleted file mode 100644 index 6d266d9..0000000 Binary files a/doxygen/img/header_bg.png and /dev/null differ diff --git a/doxygen/img/help_dark.png b/doxygen/img/help_dark.png deleted file mode 100644 index 9d73f0c..0000000 Binary files a/doxygen/img/help_dark.png and /dev/null differ diff --git a/doxygen/img/help_light.png b/doxygen/img/help_light.png deleted file mode 100644 index 121fcb1..0000000 Binary files a/doxygen/img/help_light.png and /dev/null differ diff --git a/doxygen/img/img.htm b/doxygen/img/img.htm deleted file mode 100644 index ce901d9..0000000 --- a/doxygen/img/img.htm +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -QP built-in images - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doxygen/img/key_down.png b/doxygen/img/key_down.png deleted file mode 100644 index 3d28614..0000000 Binary files a/doxygen/img/key_down.png and /dev/null differ diff --git a/doxygen/img/key_ret.png b/doxygen/img/key_ret.png deleted file mode 100644 index fba9065..0000000 Binary files a/doxygen/img/key_ret.png and /dev/null differ diff --git a/doxygen/img/key_up.png b/doxygen/img/key_up.png deleted file mode 100644 index 6666a4c..0000000 Binary files a/doxygen/img/key_up.png and /dev/null differ diff --git a/doxygen/img/logo_github.png b/doxygen/img/logo_github.png deleted file mode 100644 index 99b3839..0000000 Binary files a/doxygen/img/logo_github.png and /dev/null differ diff --git a/doxygen/img/logo_linux48.png b/doxygen/img/logo_linux48.png deleted file mode 100644 index b71bb3d..0000000 Binary files a/doxygen/img/logo_linux48.png and /dev/null differ diff --git a/doxygen/img/logo_macos48.png b/doxygen/img/logo_macos48.png deleted file mode 100644 index 5f9440d..0000000 Binary files a/doxygen/img/logo_macos48.png and /dev/null differ diff --git a/doxygen/img/logo_python3.gif b/doxygen/img/logo_python3.gif deleted file mode 100644 index c5c9a01..0000000 Binary files a/doxygen/img/logo_python3.gif and /dev/null differ diff --git a/doxygen/img/logo_ql-compact.png b/doxygen/img/logo_ql-compact.png deleted file mode 100644 index d4c0233..0000000 Binary files a/doxygen/img/logo_ql-compact.png and /dev/null differ diff --git a/doxygen/img/logo_ql.png b/doxygen/img/logo_ql.png deleted file mode 100644 index d6d823f..0000000 Binary files a/doxygen/img/logo_ql.png and /dev/null differ diff --git a/doxygen/img/logo_qwin.jpg b/doxygen/img/logo_qwin.jpg deleted file mode 100644 index 9a67951..0000000 Binary files a/doxygen/img/logo_qwin.jpg and /dev/null differ diff --git a/doxygen/img/logo_win.png b/doxygen/img/logo_win.png deleted file mode 100644 index e761ad3..0000000 Binary files a/doxygen/img/logo_win.png and /dev/null differ diff --git a/doxygen/img/logo_win48.png b/doxygen/img/logo_win48.png deleted file mode 100644 index 0ae940c..0000000 Binary files a/doxygen/img/logo_win48.png and /dev/null differ diff --git a/doxygen/img/minus.png b/doxygen/img/minus.png deleted file mode 100644 index cd44ccc..0000000 Binary files a/doxygen/img/minus.png and /dev/null differ diff --git a/doxygen/img/model.png b/doxygen/img/model.png deleted file mode 100644 index d1e90ae..0000000 Binary files a/doxygen/img/model.png and /dev/null differ diff --git a/doxygen/img/movie.png b/doxygen/img/movie.png deleted file mode 100644 index 3468106..0000000 Binary files a/doxygen/img/movie.png and /dev/null differ diff --git a/doxygen/img/qp_link.png b/doxygen/img/qp_link.png deleted file mode 100644 index 2c4ff76..0000000 Binary files a/doxygen/img/qp_link.png and /dev/null differ diff --git a/doxygen/img/radiooff.png b/doxygen/img/radiooff.png deleted file mode 100644 index 41921e3..0000000 Binary files a/doxygen/img/radiooff.png and /dev/null differ diff --git a/doxygen/img/radioon.png b/doxygen/img/radioon.png deleted file mode 100644 index bf6c784..0000000 Binary files a/doxygen/img/radioon.png and /dev/null differ diff --git a/doxygen/img/splitbar.png b/doxygen/img/splitbar.png deleted file mode 100644 index 1b9ea10..0000000 Binary files a/doxygen/img/splitbar.png and /dev/null differ diff --git a/doxygen/img/tddbook.gif b/doxygen/img/tddbook.gif deleted file mode 100644 index 3f987f5..0000000 Binary files a/doxygen/img/tddbook.gif and /dev/null differ diff --git a/doxygen/img/tree-view_linked.png b/doxygen/img/tree-view_linked.png deleted file mode 100644 index 870c50a..0000000 Binary files a/doxygen/img/tree-view_linked.png and /dev/null differ diff --git a/doxygen/img/tree-view_unlinked.png b/doxygen/img/tree-view_unlinked.png deleted file mode 100644 index 8c8a653..0000000 Binary files a/doxygen/img/tree-view_unlinked.png and /dev/null differ diff --git a/doxygen/macros.h b/doxygen/macros.h deleted file mode 100644 index da38b03..0000000 --- a/doxygen/macros.h +++ /dev/null @@ -1,24 +0,0 @@ -/** -* \file -* \brief Command-line macros and macros for QS/QSPY -*/ - -/*! The preprocessor switch to activate the QS software tracing -* instrumentation in the code */ -/** -* When defined, Q_SPY activates the QS software tracing instrumentation. -* When Q_SPY is not defined, the QS instrumentation in the code does -* not generate any code. -*/ -#define Q_SPY - -/*! The preprocessor switch to activate the QUTEST unit testing -* instrumentation in the code */ -/** -* When defined, Q_UTEST activates the QUTEST unit testing facilities. -* When Q_UTEST unit testing is not defined, the unit testing macros -* expand to nothing and don't generate any code. -*/ -#define Q_UTEST - - diff --git a/doxygen/main.dox b/doxygen/main.dox deleted file mode 100644 index 3bae11c..0000000 --- a/doxygen/main.dox +++ /dev/null @@ -1,103 +0,0 @@ -/*! @mainpage About QTools™ - -@image html qtools_banner.jpg - -@htmlonly - -@endhtmlonly - -@section ab_new What's new? -To check what's new in QTools, please see @ref history "QTools Revision History". You can also get the latest __QTools code__, with the recent enhancements and bug fixes, from the GitHub QTools repository. - -
- - -@section qtools_about What is it? -QTools™ is a collection of open source tools for embedded software development on desktop platforms, such as Windows, Linux and macOS. The QTools collection contains the following tools developed by Quantum Leaps: - -- @ref qpspy "QP/Spy software tracing and testing for embedded systems", which includes: - + @ref qs "QS™ Target-Resident Component" - + @ref qspy "QSPY™ Host Application" -+ @ref qutest "QUTest™ Unit Testing Harness" -+ @ref qview "QView™ Visualization & Monitoring" -- @ref qwin "QWin GUI toolkit for prototyping embedded systems on Windows in C or C++" -- @ref qclean "QClean utility for cleaning the white space in the source code" -- @ref qfsgen "QFSGen utility for building ROM-based file systems" - - -@section qtools_win QTools™ on Windows -The QTools Collection for Windows contains additionally the following open-source, third-party tools: - -- GNU-make for Windows (version 4.2.1) -- GNU C/C++ toolchain for Windows (MinGW version 9.2.0) -- GNU C/C++ toolchain for ARM Cortex-M and Cortex-R ([GNU Arm Embedded Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/)) -- Python for Windows (version 3.8 with tkinter) - - -@section qtools_licensing Licensing QTools™ -Most tools included in the QTools™ collection are distributed under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. The text of GPL version 2 is included in the -file GPLv2.txt in the root directory of the QTools distribution. - -The Python package is distributed under the terms of the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2, included in the file LICENSE.txt in the Python38 sub-directory of the QTools distribution. - - -@section qtools_source Source Code -In compliance with GPL, this distribution contains the source code for -the utilities contributed by Quantum Leaps in the `/source/` -subdirectory, except for the QSPY source code, which is provided in the -`/qspy/source/` directory. All tools with names starting with 'q' -have been developed and are copyrighted by Quantum Leaps. - - -@subsection qtools_mingw The MinGW C and C++ compilers for Windows -Have been taken from the MinGW project at: - -http://www.mingw.org/ - -The installer `mingw-get-setup.exe` has been used and after the -installation, the files have been pruned to reduce the size of the -distribution. Please refer to the MinGW project for the source code. - - -@subsection qtools_gnu-arm The GNU-ARM (NONE-EABI) compilers for Windows -Have been taken from: - -https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads - -The source code is available from the download page under "Source Invariant". - - -@subsection qtools_make The GNU make executable for Windows -Has been taken from the MinGW project at: - -http://www.mingw.org/ - -The "GNU Make" manual (make.pdf) has been copied from the GNU make -project at: - -http://www.gnu.org/software/make - - -@subsection qtools_util The file and diff utilities -Have been taken from the UnixUtils project at SourceForge.net: - -https://prdownloads.sourceforge.net/unxutils/UnxUtils.zip - - -The file and diff utilities source (source/fileutils-3.16-src.zip) has -been taken from: - -https://prdownloads.sourceforge.net/unxutils/UnxUtilsSrc.zip - - -@section qtools_help How to get help? - -Please post any **technical questions** to the Free Support Forum hosted on SourceForge.net. Posts to this forum benefit the whole community and are typically answered the same day. - -Direct [commercial support](https://www.state-machine.com/licensing/#Support) is available to the commercial licensees. Every commercial license includes one year of Technical Support for the licensed software. The support term can be extended annually. - -[Training and consulting](https://www.state-machine.com/support/training) services are also available from Quantum Leaps. - - -@next{gs} -*/ diff --git a/doxygen/make.bat b/doxygen/make.bat deleted file mode 100644 index 06700c0..0000000 --- a/doxygen/make.bat +++ /dev/null @@ -1,81 +0,0 @@ -@echo off -:: ========================================================================== -:: Product: QTools script for generating Doxygen documentation -:: Last Updated for Version: 6.9.0 -:: Date of the Last Update: 2020-08-24 -:: -:: Q u a n t u m L e a P s -:: ------------------------ -:: Modern Embedded Software -:: -:: Copyright (C) 2005-2020 Quantum Leaps, LLC. All rights reserved. -:: -:: This program is open source software: you can redistribute it and/or -:: modify it under the terms of the GNU General Public License as published -:: by the Free Software Foundation, either version 3 of the License, or -:: (at your option) any later version. -:: -:: Alternatively, this program may be distributed and modified under the -:: terms of Quantum Leaps commercial licenses, which expressly supersede -:: the GNU General Public License and are specifically designed for -:: licensees interested in retaining the proprietary status of their code. -:: -:: This program is distributed in the hope that it will be useful, -:: but WITHOUT ANY WARRANTY; without even the implied warranty of -:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -:: GNU General Public License for more details. -:: -:: You should have received a copy of the GNU General Public License -:: along with this program. If not, see . -:: -:: Contact information: -:: -:: -:: ========================================================================== -@setlocal - -@echo usage: -@echo make -@echo make -CHM -@echo make -awesome - -:: Doxygen tool (adjust to your system) ...................................... -@set DOXYGEN=doxygen - -:: HTML Help tool (needed only with the -CHM option, (adjust to your system) . -@set HHC="C:\tools\HTML Help Workshop\hhc.exe" - -:: Generate Doxygen Documentation... -if "%1"=="-CHM" ( - @echo Generating HTML... - %DOXYGEN% Doxyfile-CHM - - @echo Adding custom images... - xcopy preview.js tmp\ - xcopy img tmp\img\ - @echo img\img.htm >> tmp\index.hhp - - @echo Generating CHM... - %HHC% tmp\index.hhp - - @echo. - @echo Cleanup... - @rmdir /S /Q tmp - @echo CHM file generated - -) else ( - @echo. - @echo Cleanup... - rmdir /S /Q ..\html - - @echo Adding custom images... - xcopy preview.js ..\html\ - xcopy img ..\html\img\ - copy images\favicon.ico ..\html - - @echo Generating HTML... - %DOXYGEN% Doxyfile%1 - @qclean ..\html -) - -@endlocal diff --git a/doxygen/modules.dox b/doxygen/modules.dox deleted file mode 100644 index 1ee7c84..0000000 --- a/doxygen/modules.dox +++ /dev/null @@ -1,60 +0,0 @@ -/*! @defgroup qpspy QP/Spy - -@brief -Software tracing and testing system - -@description -QP/Spy™ is a software tracing and testing system specifically designed for embedded systems, such as single chip microcontrollers. The job of QP/Spy is to capture information about an embedded code's execution and send it to the host computer with minimal impact on the real-time performance of the embedded code. -*/ - -/*###########################################################################*/ -/*! @defgroup qutest QUTest - -@brief -Unit Testing Harness (Framework) - -@description -QUTest™ (pronounced 'cutest') is a unit testing harness (a.k.a. unit testing framework), which is specifically designed for deeply embedded systems, but also supports unit testing of embedded code on host computers ("dual targeting"). QUTest is the fundamental tooling for Test-Driven Development (TDD) of QP/C/C++ applications, which is a highly recommended best-practice. -*/ - -/*###########################################################################*/ -/*! @defgroup qwin QWin GUI System - -@brief -free software toolkit for prototyping (dual-targeting) embedded systems on Windows in C - -@description -QF is a portable, event-driven, real-time framework for execution of active objects (concurrent state machines) specifically designed for real-time embedded (RTE) systems. -*/ - -/*###########################################################################*/ -/*! @defgroup qclean QClean - -@brief -White space cleanup utility - -@description -QS is software tracing system that enables developers to monitor live event-driven QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. -*/ - -/*###########################################################################*/ -/*! @defgroup qfsgen QFSgen - -@brief -ROM file system generator - -@description -QV is a simple **cooperative** kernel (previously called "Vanilla" kernel). This kernel executes active objects one at a time, with priority-based scheduling performed before processing of each event. Due to naturally short duration of event processing in state machines, the simple QV kernel is often adequate for many real-time systems. - - - -@section qv_overview QV Overview -The QV scheduler is engaged after every RTC step of any active object to choose the next active object to execute. The QV scheduler always chooses the highest-priority active object that has any events in its event queue. The QV scheduler then extracts the next event from this queue and dispatches it to the state machine associated with the active object. The state machine runs to completion, after which the QV scheduler runs and the cycle repeats. - -Please note that because the state machines always return to the QV scheduler after each RTC step, a single stack can be used to process all state machines (memory-friendly architecture). - -The QV scheduler can also very easily detect when all event queues are empty, at which point it can call the idle callback to let the application put the CPU and peripherals to a low-power sleep mode (power-friendly architecture). - -Given the simplicity, portability, and low-resource consumption, the QV scheduler is very attractive. It allows you to partition the problem into active objects and execute these active objects orderly. The task-level response of this scheduler is the longest RTC step in the whole system, but because event-driven active objects don’t block, the RTC steps tend to be very short (typically just a few microseconds). Also, often you can break up longer RTC steps into shorter pieces, by posting an event to self and returning (“Reminder” state pattern). The self-posted event then triggers the continuation of longer processing. - -*/ diff --git a/doxygen/qcalc.dox b/doxygen/qcalc.dox deleted file mode 100644 index af3e1b7..0000000 --- a/doxygen/qcalc.dox +++ /dev/null @@ -1,118 +0,0 @@ -/*! @page qcalc QCalc Programmer's Calculator - -@tableofcontents - -

QCalc is a powerful, cross-platform calculator specifically designed for embedded systems programmers. The calculator accepts *whole expressions* in the @ref qcalc_expr "C-syntax" and displays results simultaneously in decimal, hexadecimal, and binary without the need to explicitly convert the result to these bases. -

- -@image html qcalc.png "QCalc user interface" - -@note -The calculator is a console application, where you can type **complete C expressions**. You can also **copy-and-paste** expressions into and from the calculator console to use them almost directly in **your C code**. - - -@section qcalc_usage QCalc Usage -QCalc is included in the QTools Collection in the sub-directory qtools/qcalc/ and consists of a single file qcalc.py. To launch QCalc, you need to open this file with python. - -You use QCalc by typing (or pasting) an expression at the `> ` prompt and pressing Enter to evaluate the expression. You can conveniently edit any expression already inside the *user input* field, and you can @ref qcacl_hist "recall the previous expressions" by means of the Up and Down keys. - -@note -You **quit** the calculator by Enter without entering an expression. - - -@subsection qcalc_batch Batch Mode -If you provide the optional [expression] argument, QCalc will evaluate the expression, print the result and terminate. For example: - -@verbatim -qcalc "2*3 + (1 << 3)" -QCalc Programmer's Calculator 6.9.4 running on Python 3.9.1 -(c) 2005-2021 Quantum Leaps, www.state-machine.com - -2*3 + (1 << 3) -= 14 | 0x0000'000E | 0b00000000'00000000'00000000'00001110 - -@endverbatim - -@subsection qcalc_interact Interactive Mode -Otherwise, if no [expression] argument is provided, QCalc will start in the interactive mode, where you can enter expressions via your keyboard. - - -@subsection qcalc_win QCalc on Windows -The python interpreter is included in the QTools collection for Windows. The `%QTOOLS%\bin` directory contains also the `qcalc.bat` batch file and a shortcut qcalc, which you can copy to your desktop: - -@image html qcalc_lnk.png "Shortcut for launching QCalc" - - -@section qcalc_features QCalc Features - -@subsection qcalc_expr Expressions in C-Syntax -The most important feature of QCalc is that it accepts expressions in the **C-syntax** -- with the same operands and precedence rules as in the C or C++ source code. Among others, the expressions can contain all bit-wise operators (`<<`, `>>`, `|`, `&`, `^`, `~`) as well as mixed decimal, **hexadecimal** and even @ref qcalc_bin "binary" constants. QCalc is also a powerful floating-point scientific calculator and supports all mathematical functions (`sin()`, `cos()`, `tan()`, `exp()`, `ln()`, ...). Some examples of acceptable expressions are: - -`((0xBEEF << 16) | 1280) & ~0xFF` -- binary operators, mixed hex and decimal numbers@n -`($1011 << 24) | (1280 >> 8) ^ 0xFFF0` -- mixed @ref qcalc_bin "binary", dec and hex numbers@n -`(1234 % 55) + 4321//33` -- remainder, integer division (note the `//` integer division operator@n -`pi/6` -- pi-constant@n -`pow(sin(ans),2) + pow(cos(ans),2)` -- scientific floating-point calculations, @ref qcalc_ans "ans-variable"@n - - -@note -QCalc internally uses the Python command eval to evaluate the expressions. Please refer to the documentation of the Python math expressions for more details of supported syntax and features. - - -@subsection qcalc_conv Automatic Conversion to Hexadecimal and Binary -If the result of expression evaluation is integer (as opposed to floating point), QCalc automatically displays the result in hexadecimal and binary formats (see QCalc screenshot). For better readability the hex display shows an apostrophe between the two 16-bit half-words (e.g., `0xDEAD'BEEF`). Similarly, the binary output shows an apostrophe between the four 8-bit bytes (e.g., `0b11011110'10101101'10111110'11101111`). - - -@subsection qcalc_base Hexadecimal and Binary Numbers -As the extension to the C-syntax, QCalc supports both **hexadecimal numbers** and **binary numbers**. These numbers are represented as `0x...` and`0b...`, respectively, and can be mixed into expressions. Here are a few examples of such expressions: - -@verbatim -(0b0110011 << 14) & 0xDEADBEEF -(0b0010 | 0b10000) * 123 -@endverbatim - - -@subsection qcalc_hist History of Inputs -As a console application QCalc "remembers" the history of the recently entered expressions. You can recall and navigate the history of previously entered expressions by pressing the Up / Down keys. - - -@subsection qcalc_ans The ans Variable -QCalc stores the result of the last computation in the `ans` variable. Here are some examples of expressions with the `ans` variable: - -`1/ans` -- find the inverse of the last computation@n -`log(ans)/log(2)` -- find log-base-2 of the last computation@n - - -@subsection qcalc_64bit 64-bit Range -QCalc supports the 64-bit range and switches to 64-bit arithmetic automatically when an **integer** result of a computation exceeds the 32-bit range. Here are some examples of the 64-bit output: - -@verbatim -> 0xDEADBEEF << 27 -= 501427843159293952 | 0x06F5'6DF7'7800'0000 -= 0b00000110'11110101'01101101'11110111'01111000'00000000'00000000'00000000 -> 0xDEADBEEF << 24 -= 62678480394911744 | 0x00DE'ADBE'EF00'0000 -= 0b00000000'11011110'10101101'10111110'11101111'00000000'00000000'00000000 -> 0xDEADBEEF << 34 -! out of range -> -@endverbatim - - -@subsection qcalc_error Error handling -Expressions that you enter into QCalc might have all kinds of errors: syntax errors, computation errors (e.g., division by zero), etc. In all these cases, QCalc responds with the `Error` message and the explanation of the error: - -@verbatim -> (2*4) + ) -Traceback (most recent call last): - File "C:\qp\qtools\qcalc\qcalc.py", line 54, in _main - result = eval(expr) - File "", line 1 - (2*4) + ) - ^ -SyntaxError: unmatched ')' -> -@endverbatim - -@next{qfsgen} -*/ diff --git a/doxygen/qclean.dox b/doxygen/qclean.dox deleted file mode 100644 index 85a1d05..0000000 --- a/doxygen/qclean.dox +++ /dev/null @@ -1,114 +0,0 @@ -/*! @page qclean QClean Code Whitespace Cleanup - -@tableofcontents - -

Many programmers pay little attention to the **whitespace** in their source code, such as spaces, tabs, new-lines, etc. The common thinking is that compilers (C, C++, etc.) ignore whitespace anyway, so why bother? But, as a *professional* software developer you should not ignore whitespace, because it can cause all sorts of problems, some of them illustrated in the figure below: -

- -@image html qclean_dirty.png "Examples of problematic whitespace in source code" - -
    -
  • 1 Trailing whitespace after the last printable character in line can cause **bugs**. For example, trailing whitespace after the C/C++ macro-continuation character '\\' can confuse the C pre-processor and can result in a **program error**, as indicated by the bug icons. -
  • -
  • 2 Similarly, inconsistent use of End-Of-Line (EOL) convention can cause **bugs**. For example, mixing the DOS EOL Convention (0x0D,0x0A) with Unix EOL Convention (0x0A) can confuse the C pre-processor and can result in a **program error**, as indicated by the bug icons. -
  • -
  • 3 Inconsistent use of tabs and spaces can cause unnecessary churn in the version control system (VCS) in source files that otherwise should be identical. Also inconsistent use of whitespace can lead to different rendering of the source code by different editors and printers. -
  • -
- -@attention -The problems caused by whitespace in the source code are particularly insidious, because you **don't see** the culprit. By using an **automated** whitespace cleanup utility you can save yourself hours of frustration and significantly improve your code quality. - - - -

QClean Source Code Cleanup Utility

-QClean is a simple and blazingly fast command-line utility to **automatically clean whitespace** in your source code. QClean is deployed as natively compiled executable and is located in the sub-directory qtools/bin/. QClean is available in portable source code and can be compiled on all desktop platforms (Windows and POSIX -- Linux, macOS...). - -@attention -QClean is very simple to use (no parameters are needed in most cases) and is blazingly fast (it can easily cleanup hundreds of files per second). All this is designed so that you can use QClean frequently. In fact, the use of QClean after editing your code should become part of your **basic hygiene**--like washing hands after going to the bathroom. - - - -@section qclean_usage QClean Usage -Typically, you invoke QClean from a command-line prompt without any parameters. In that case, QClean will cleanup white space in the current directory and **recursively** in all its sub-directories. - -@note -If you have added the qtools/bin/ directory to your `PATH` environment variable (see @ref qtools_install "Installing QTools"), you can run `qclean` directly from your terminal window. - - -@image html qclean_run.png "Example run of the QClean utility" - -As you can see in the screen shot above, QClean processes the files and prints out the names of the cleaned up files. Also, you get information as to what has been cleaned, for example, "Trail-WS" means that trailing whitespace has been cleaned up. Other possibilities are: "CR" (cleaned up DOS/Windows (CR) end-of-lines), "LF" (cleaned up Unix (LF) end-of-lines), and "Tabs" (replaced Tabs with spaces). - - - -@subsection qclean_command QClean Command-Line Parameters -QClean takes the following command-line parameters: - -
-PARAMETER | DEFAULT | COMMENT -:--------------|:---------|:---------- -`[root-dir]` | `.` | root directory to clean (relative or absolute) -OPTIONS |   |   -`-h` |   | help (show help message and exit) -`-q` |   | query only (no cleanup when -q present) -`-r` |   | check also read-only files -`-l[limit]` | 80 | line length limit (not checked when -l absent) -
- - -@section qclean_features QClean Features -QClean fixes the following whitespace problems: - -- removing of all trailing whitespace (see figure above 1) -- applying consistent End-Of-Line convention (either Unix (LF) or DOS (CRLF) see figure above 2) -- replacing Tabs with spaces (untabify, see figure above 2) -- optionally, scan the source code for long lines exceeding the specified limit (`-l` option, default 80 characters per line). - -@note -QClean can optionally check the code for **long lines of code** that exceed a specified limit (80 characters by default) to reduce the need to either wrap the long lines (which destroys indentation), or the need to scroll the text horizontally. (All GUI usability guidelines universally agree that horizontal scrolling of text is always a bad idea.) In practice, the source code is very often copied-and-pasted and then modified, rather than created from scratch. For this style of editing, it’s very advantageous to see simultaneously and side-by-side both the original and the modified copy. Also, differencing the code is a routinely performed action of any VCS (Version Control System) whenever you check-in or merge the code. Limiting the line length allows to use the horizontal screen real estate much more efficiently for side-by-side-oriented text windows instead of much less convenient and error-prone top-to-bottom differencing. - - - -@subsection qclean_files QClean File Types - -QClean applies the following rules for cleaning the whitespace depending on the file types: - -
-FILE TYPE | END-OF-LINE | TRAILING WS | TABS | LONG-LINES -:--------------|:------------|:-----------:|:--------:|:------------: -`.c` | Unix (LF) | remove | remove | check -`.h` | Unix (LF) | remove | remove | check -`.cpp` | Unix (LF) | remove | remove | check -`.hpp` | Unix (LF) | remove | remove | check -`.s` | Unix (LF) | remove | remove | check -`.asm` | Unix (LF) | remove | remove | check -`.lnt` | Unix (LF) | remove | remove | check -`.txt` | DOS (CR,LF) | remove | remove | don't check -`.md` | DOS (CR,LF) | remove | remove | don't check -`.bat` | DOS (CR,LF) | remove | remove | don't check -`.ld` | Unix (LF) | remove | remove | check -`.py` | Unix (LF) | remove | remove | check -`.pyw` | Unix (LF) | remove | remove | check -`.tcl` | Unix (LF) | remove | remove | check -`.java` | Unix (LF) | remove | remove | check -`Makefile` | Unix (LF) | remove | leave | check -`.mak` | Unix (LF) | remove | leave | check -`.html` | Unix (LF) | remove | remove | don't check -`.htm` | Unix (LF) | remove | remove | don't check -`.php` | Unix (LF) | remove | remove | don't check -`.dox` | Unix (LF) | remove | remove | don't check -`.m` | Unix (LF) | remove | remove | check -
- -@n -@note -The cleanup rules specified in the table above can be easily customized by editing the array `l_fileTypes` in the `qclean/source/main.c` file. Also, you can change the **Tab size** by modifying the `TAB_SIZE` constant (currently set to 4) as well as the default **line-limit** by modifying the `LINE_LIMIT` constant (currently set to 80) at the top of the the `qclean/source/main.c` file. Of course, after any such modification, you need to re-build the QClean executable and copy it into the qtools/bin directory. - - -@n -@attention -For best code portability, QClean enforces the consistent use of the specified End-Of-Line convention (typically Unix (LF)), **regardless of the native EOL of the platform**. The DOS/Windows EOL convention (CR,LF) is typically not applied because it causes compilation problems on Unix-like systems (Specifically, the C preprocessor doesn't correctly parse the multi-line macros.) On the other hand, most DOS/Windows compilers seem to tolerate the Unix EOL convention without problems. - -@next{qfsgen} -*/ diff --git a/doxygen/qfsgen.dox b/doxygen/qfsgen.dox deleted file mode 100644 index 4551d31..0000000 --- a/doxygen/qfsgen.dox +++ /dev/null @@ -1,150 +0,0 @@ -/*! @page qfsgen QFSGen ROM File-System Generator - -@tableofcontents - -

QFSGen is a cross-platform, command-line utility that generates a ROM-based file system, which can be incorporated in a C source code. Specifically, QFSGen utility generates a C header file that contains a bunch of constant byte arrays representing your files and directories. This generated header file (named `fsdata.h` by default) can be subsequently included in the ROM-Based File System implementation. -

- -QFSGen is deployed as natively compiled executable and is located in the sub-directory qtools/bin/. QFSGen is available in portable source code and can be compiled on all desktop platforms (Windows and POSIX -- Linux, macOS...). - -@note -The main motivation for the QFSGen utility is to generate ROM-based file systems for embedded HTTP servers. However, the utility can be used for any ROM-based file systems. - - - -@section qfsgen_usage QFSGen Usage -You use the QFSGen utility from command-prompt. First, change current directory to the directory, where you wish to generate the C header file (named `fsdata.h` by default) and type: - -@verbatim -qfsgen website -h -@endverbatim - -where `website` is a directory, which contains the files and sub-directories you wish to include into your ROM-based file system. This particular QFSGen invocation will generate the file-system found in the directory `website` with HTTP headers (`-h` option). - -@image html qfsgen_run.png "Example run of the QFSGen utility" - - - -@subsection qfsgen_command QFSGen Command-Line Parameters -QFSGen takes the following command-line parameters: - -
-PARAMETER | DEFAULT | COMMENT -:--------------|:---------|:---------- -`fs-dir` | | file system directory (relative or absolute) -`[output-flie]`|`fsdata.h`| output file name (optional) -OPTIONS |   |   -`-h` |   | generate HTTP headers -
- - - -@section qfsgen_works How QFSGen Works -QFSGen recursively scans the provided directory and **recursively** encodes any file and sub-directory into an array in the generated header file. For example, here is the content of the `website` directory: - -@verbatim -+-website/ - +-img/ - | +-AN_QP_and_lwIP.jpg - | +-arrow.gif - | +-favicon.ico - | +-footer.jpg - | +-logo_lwip_qp.jpg - | +-logo_ql.jpg - | +-logo_sics.gif - | +-PSiCC2.gif - | +-QP_datasheet.gif - +-404.htm - +-bg_footer.gif - +-cgi_demo.htm - +-index.htm - +-ssi_demo.shtm - +-style.css - +-thank_you.htm - +-udp_demo.htm -@endverbatim - -This directory structure is then encoded into the following header file `fsdata.h`: - -@code -/* This file has been generated with the qfsgen utility. */ - -/* /404.htm */ -static unsigned char const data_404_htm[] = { - /* name: */ - 0x2F, 0x34, 0x30, 0x34, 0x2E, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ - 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x34, - . . . - 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ - 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, - 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x0A -}; - -struct fsdata_file const file_404_htm[] = { - { - (struct fsdata_file *)0, - data_404_htm, - data_404_htm + 9, - sizeof(data_404_htm) - 9 - } -}; - -/* /thank_you.htm */ -static unsigned char const data_thank_you_htm[] = { - /* name: */ - 0x2F, 0x74, 0x68, 0x61, 0x6E, 0x6B, 0x5F, 0x79, 0x6F, 0x75, - 0x2E, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ - 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, - . . . - 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ - 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, - - 0x4D, 0x4C, 0x3E, 0x0A -}; - -struct fsdata_file const file_thank_you_htm[] = { - { - file_style_css, - data_thank_you_htm, - data_thank_you_htm + 15, - sizeof(data_thank_you_htm) - 15 - } -}; - -/* /udp_demo.htm */ -static unsigned char const data_udp_demo_htm[] = { - /* name: */ - 0x2F, 0x75, 0x64, 0x70, 0x5F, 0x64, 0x65, 0x6D, 0x6F, 0x2E, - 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ - 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, - . . . - 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ - 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, - . . . - 0x3E, 0x0A -}; - -struct fsdata_file const file_udp_demo_htm[] = { - { - file_thank_you_htm, - data_udp_demo_htm, - data_udp_demo_htm + 14, - sizeof(data_udp_demo_htm) - 14 - } -}; - -#define FS_ROOT file_udp_demo_htm - -#define FS_NUMFILES 17 -@endcode - -Subsequently, the `fsdata.h` header file is included in the ROM file-system implementation file `fs.c`, which is included in the `qfsgen/source` directory. - -@next{history} -*/ diff --git a/doxygen/qpspy.dox b/doxygen/qpspy.dox deleted file mode 100644 index 62e8d01..0000000 --- a/doxygen/qpspy.dox +++ /dev/null @@ -1,161 +0,0 @@ -/*! @page qpspy QP/Spy™ Software Tracing - -@image html qspy_banner.jpg - -

In any real-life project, getting the code written, compiled, and successfully linked is only the first step. The system still needs to be tested, validated, and tuned for best performance and resource consumption. A single-step debugger is frequently not helpful because it stops the system and exactly hinders seeing **live interactions** within the application. Clogging up high-performance code with `printf` statements is usually too intrusive and simply unworkable in many embedded systems, because `printf` formatting and output via a serial port happen exactly in the most time-critical paths through the code. -

- -So the questions are: How can you monitor the behavior of a running real-time system without degrading the system itself? How can you discover and document elusive, intermittent bugs that are caused by subtle interactions among concurrent components? How do you design and execute repeatable @ref qutest "unit tests" and **integration tests** of your system? How do you ensure that a system runs reliably for long periods of time and achieves optimal performance? - -Techniques based on **software tracing** can answer many of these questions. Software tracing is a method for obtaining diagnostic information in a live environment without the need to stop the application to get the system feedback. Software tracing always involves some form of a target system instrumentation to log interesting discrete events for subsequent retrieval from the system and analysis. - -@anchor qpspy_framework -@note -Software tracing is particularly effective and powerful in combination with the event-driven **reactive programming** model, such as the one implemented in QP™ real-time frameworks. Due to the inversion of a control, a real-time framework controls almost all interesting interactions in the system, so an instrumented real-time framework can provide much more comprehensive and detailed information than any traditional RTOS. - - - -@section ab_about What is it? - -QP/Spy™ is a @ref qpspy "software tracing and testing system" specifically designed for embedded systems, such as single chip microcontrollers. The job of QP/Spy is to capture information about an embedded code's execution and send it to the host computer with minimal impact on the real-time performance of the embedded code. - -@image html qpspy0.gif "Software tracing data records flowing from Target to the Host" - -@remarks -QP/Spy can also (optionally) send commands and data **to the embedded target** (see @ref qpspy_rx "Bi-Directional QP/Spy"), which serves as the basis for @ref qutest "Unit Testing" and for @ref qview "Visualization and Monitoring" subsystems of the QP/Spy system. - - - -@section ab_how How it works? -In a nutshell, working with QP/Spy™ is similar to peppering the code with `printf` or similar (like `sprintf`) statements for logging and debugging, except that QP/Spy™ is much less intrusive, more lightweight, portable and @ref qs_filters "selective" than the primitive `printf`. Additionally, unlike the `printf` output, the data produced by QP/Spy™ contain the data *integrity* and *continuity* checks, so the host computer can tell when it receives corrupt data or incomplete data. - -The main advantages of the QP/Spy™ tracing system over peppering the code with `printf` statements are: - -- When you use `printfs`, the data formatting and sending occur in the *time-critical* paths through the embedded code. In contrast, QP/Spy produces raw *binary data*, so all the time-consuming formatting is removed from the embedded system and is done after the fact in the host computer. - -- in QP/Spy, data logging and sending to the host are **separated** so that the embedded system can typically perform the transmission outside of the time-critical path, for example in the *idle processing* of the embedded CPU. - -- Data produced by `printf` gives you no clue if the data gets corrupted or lost in transmission. In contrast, the @ref qpspy_proto "QP/Spy transmission protocol" checks for data **integrity** and **continuity**. - -- The QP/Spy tracing provides flexible @ref qs_filters "filtering" mechanisms, which allow you to selectively trace only the aspects of the system that you choose and suppress the data that is not interesting at the moment. - -- The QP/Spy tracing is implemented as macros that are active only in the "Spy" build configuration and are inactive in the Release or Debug build configurations. This means that you can safely leave the instrumentation in the code for future maintenance, development and testing. - -- The QP/Spy trace data contain precise, high-granularity **timestamps**, so you can tie the data to the common timeline. - -- The code size of the @ref qs "target-resident component" in QP/Spy is merely a few hundred bytes, which contrasts with several kilobytes of code required by a full-blown `printf` formatter. - - -The picture below shows a typical setup for software tracing. The embedded Target system is executing instrumented code, which logs the trace data into a RAM buffer inside the Target. From that buffer the trace data is sent over a data link to a Host computer, which stores, displays, and analyzes the information. This configuration means that a software tracing always requires two components: a "Target resident component" for generating and sending the trace data (@ref qs "QS" in QP/Spy™), and a "Host resident component" to receive, decompress, visualize, and analyze the data (@ref qspy "QSPY" in QP/SPy™). - -@image html qspy1.gif "Typical setup for software tracing with QP/Spy™" - -@note -Software tracing instrumentation logs interesting discrete events that occur in the target system. These discrete events will be called **trace records**, to avoid confusing them with the application-level events. - - -A good tracing solution, such as QP/Spy, is minimally intrusive, which means that it can provide visibility into the running code with minimal impact on the target system behavior. Properly implemented and used, it will let you diagnose a live system without interrupting or significantly altering the behavior of the system under investigation. - -Of course, it's always possible that the overhead of software tracing, no matter how small, will have some effect on the target system behavior, which is known as the probe effect (a.k.a. the "Heisenberg effect"). To help you determine whether that is occurring, you must be able to configure the instrumentation in and out both at compile-time as well as at run-time. - -To minimize the "probe effect", a good trace system performs efficient, selective logging of trace records using as little processing and memory resources of the target as possible. Selective logging means that the tracing system provides user-definable, fine granularity filters so that the target-resident component only collects events of interest you can filter as many or as few instrumented events as you need. That way you can make the tracing as noninvasive as necessary. - -To minimize the RAM usage, the target-resident trace component typically uses a circular trace buffer that is continuously updated, and new data overwrites the old when the buffer "wraps around" due to limited size or transmission rate to the host. This reflects the typically applied last-is-best policy in collecting the trace data. In order to focus on certain periods of time, software trace provides configurable software triggers that can start and stop trace collection before the new data overwrites the old data of interest in the circular buffer. - -To further maximize the amount of data collected in the trace buffer, the Target-resident component typically applies some form of data compression to squeeze more trace information into the buffer and to minimize the bandwidth required to uplink the data to the Host. - -However, perhaps the most important characteristic of a flexible software tracing system is the separation of trace logging (what is being traced) from the data transmission mechanism (how and when exactly the data is sent to the Host). This separation of concerns allows the transmissions to occur in the least time-critical paths of the code, such as the idle loop. Also, clients should be able to employ any data transmission mechanism available on the Target, meaning both the physical transport layer (e.g., serial port, SPI, USB, Ethernet, etc.) as well as implementation strategy (polling, interrupt, DMA, etc.). The tracing facility should tolerate and be able to detect any RAM buffer overruns due to bursts of tracing data production rate or insufficient transmission rate to the host. - -Finally, the tracing facility must allow consolidating data from all parts of the system, including concurrently executing threads and interrupts. This means that the instrumentation facilities must be *reentrant* (i.e., both thread-safe and interrupt-safe). Also, to be able to correlate all this data, most tracing systems provide precise @ref qs_tstamp "time-stamping" of the trace records. - - - -@subsection qpspy_rx Bi-Directional Connection to the Target -While traditional software tracing systems support only uni-directional output of trace data from the embedded Target to a Host computer, QP/Spy supports bi-directional communication to the target as well. This capability allows users to send commands and data to the Target and form the basis for @ref qutest "Unit Testing" and @ref qview "Visualization and Monitoring" of embedded Targets. - -@image html qpspy1.gif "Bi-directional data exchange between the Target and the Host" - - -@subsection qpspy_udp UDP Socket Extension -The QP/Spy system provides a @ref qspy_udp "UDP socket", which is open for communication with various Front-Ends (GUI-based or "headless"). Currently, the UDP connection point is used by the @ref qutest "QUTest" headless (console-based) front-end and GUI-based @ref qview "QView" front-end. - - - -@subsection qpspy_exa QP/Spy Session Example -To give you a better idea how QP/Spy works, the listing below shows an example output from a QP/Spy session. The left-hand side shows the raw, @ref qpspy_proto "binary output" generated by the target-resident component (@ref qs "QS"). The right-hand side shows the @ref qspy_text "human-readable format" generated from the same data by the host-resident component (@ref qspy "QSPY"). The compression ratio between the binary and textual outputs in this data sample is about 3.7. - -@image html qpspy_exa.png "Example of the QP/Spy output" - - -The following sections explain the concepts and components of QP/Spy™: -- @subpage qpspy_proto -- @subpage qs -- @subpage qspy - -@next{qpspy_proto} -*/ -/****************************************************************************/ -/*! @page qpspy_proto QP/Spy™ Data Protocol - -@tableofcontents - -

One of the greatest strengths of the QP/Spy™ tracing system is the data transmission protocol. The QP/Spy protocol is very lightweight, but contains the mechanisms for checking both data **integrity** and **continuity**. -

- -The QP/Spy™ data protocol has many elements of the High Level Data Link Control (HDLC) protocol defined by the International Standards Organization (ISO). The QP/Spy protocol has been specifically designed to simplify the data management overhead in the target, yet to allow detection of any data dropouts due to the trace buffer overruns. The protocol has not only provisions for detecting gaps in the data and other errors, but allows for instantaneous re-synchronization after any bufferning or transmission error to minimize loss of useful data. - -@image html qspy6.gif "QP/Spy transmission protocol" - -The QS protocol transmits each trace record in an HDLC-like frame. The upper part of the figure above shows the serial data stream transmitted from the target containing frames of different lengths. The bottom part of the figure above shows the details of a single frame: - -1. Each frame starts with the Frame **Sequence-No** byte. The target QS component increments the Frame Sequence Number for every frame inserted into the circular buffer. The Sequence Number naturally rolls-over from 255 to 0. The Frame Sequence Number allows the QSPY host component to detect any data discontinuities. - -2. Following the Fame Sequence Number is the **Record-Type** byte, which is one of the predefined QS records, or an application-specific record. - -3. Following the Record-Type is zero or more **Data** bytes. - -4. Following the data is the **Checksum**. The Checksum is computed over the Fame Sequence Number, the Record ID, and all the Data bytes. The next section gives the detailed Checksum computation formula. - -5. Following the Checksum is the **HDLC Flag**, which delimits the frame. The HDLC flag is the `01111110` binary string (`0x7E` hexadecimal). Please note that the QP/Spy protocol uses only one HDLC Flag at the end of each frame an no HDLC Flag at the beginning of a frame. In other words, only one Flag is inserted between frames. - -The QS target component performs the HDLC-like framing described above at the time the bytes are inserted into the circular trace buffer. This means that the data in the buffer is already cleanly divided into frames and can be transmitted in any chunks, typically not aligned with the frame boundaries. - - - -@section qspy_transparent Transparency -One of the most important characteristics of HDLC-type protocols is establishing very easily identifiable frames in the serial data stream. Any receiver of such a protocol can instantaneously synchronize to the frame boundary by simply finding the Flag byte. This is because the special Flag byte can never occur within the content of a frame. To avoid confusing unintentional Flag bytes that can naturally occur in the data stream with an intentionally sent Flag, HDLC uses a technique known as transparency (a.k.a. byte-stuffing or escaping) to make the Flag bytes transparent during the transmission. Whenever the transmitter encounters a Flag byte in the data, it inserts a two-byte escape sequence to the output stream. The first byte is the Escape byte, defined as binary `01111101` (hexadecimal `0x7D`). The second byte is the original byte XOR-ed with `0x20`. - -Of course, now the Escape byte itself must also be transparent to avoid interpreting an unintentional Escape byte as the two-byte escape sequence. The procedure of escaping the Escape byte is identical to that of escaping the Flag byte. - -The transparency of the Flag and Escape bytes complicates slightly the computation of the Checksum. The transmitter computes the Checksum over the Fame Sequence Number, the Record-Type, and all Data bytes before performing any “byte-stuffing”. The receiver must apply the exact reversed procedure of performing the “byte-un-stuffing” before computing the Checksum. - -An example may make this clearer. Suppose that the following trace record needs to be inserted to the trace buffer (the transparent bytes are shown in bold): - - Record-Type = 0x7D, Record Data = 0x7D 0x08 0x01 - -Assuming that the current Fame Sequence Number is, say `0x7E`, the Checksum will be computed over the following bytes: - - Checksum == (uint8_t)(~(0x7E + 0x7D + 0x7D + 0x08 + 0x01)) == 0x7E - -and the actual frame inserted into the QS trace buffer will be as follows: - - 0x7D 0x5E 0x7D 0x5D 0x7D 0x5D 0x08 0x01 0x7D 0x5E 0x7E - -Obviously, this is a degenerated example, where the Frame Sequence Number, the Record-Type, a Data byte, and the Checksum itself turned out to be the transparent bytes. Typical overhead of transparency with real trace data is one escape sequence per several trace records. - - - -@section qpspy_endianness Endianness -In addition to the HDLC-like framing, the QS transmission protocol specifies the endianness of the data to be little-endian. All multi-byte data elements, such as 16-, 32-, or 64-bit integers, pointers, and floating point numbers are inserted into the QS trace buffer in the little-endian byte order (least-significant byte first). The QS data inserting macros place the data in the trace buffer in a platform-neutral manner, meaning that the data is inserted into the buffer in the little-endian order regardless of the endianness of the CPU. Also, the data-inserting macros copy the data to the buffer one byte at a time, thus avoiding any potential data misalignment problems. Many embedded CPUs, such as ARM, require certain alignment of 16-, 32-, or 64-bit quantities. - - - -@section qpspy_last_is_best Last-is-Best Data Policy -The QS Trace Buffers (transmit QS buffer and receive QS-RX buffer) store only complete HDLC frames, which is the pivotal point in the design of the QS target component and has two important consequences. - -First, the use of HDLC frames in the buffers enables the last is best tracing policy. The QS transmission protocol maintains both the Frame Sequence Number and the Checksum over each trace record, which means that any data corruption caused by overrunning the old data with the new data can be always reliably detected. Therefore, the new trace data is simply inserted into the circular trace buffers, regardless if it perhaps overwrites the old data that hasn't been sent out yet, or is in the process of being sent. The burden of detection any data corruption is placed on the QSPY host component. When you start missing the frames (which the host component easily detects by discontinuities in the Frame Sequence Number), you have several options. Your can apply some additional filtering, increase the size of the buffer, or improve the data transfer throughput. - -Second, the use of HDLC-formatted data in the trace buffers allows decoupling the data insertion into the trace buffers from the data removal out of the trace buffers. You can simply remove the data in whichever chunks you like, without any consideration for frame boundaries. You can employ just about any available physical data link available on the target for transferring the trace data from the target to the host. - -@next{qs} -*/ diff --git a/doxygen/qs.dox b/doxygen/qs.dox deleted file mode 100644 index 84de858..0000000 --- a/doxygen/qs.dox +++ /dev/null @@ -1,332 +0,0 @@ -/*! @page qs QS Target Component - -@tableofcontents - -

The target-resident component of the QP/Spy™ tracing system is called **QS**. The purpose of QS is to provide facilities for **instrumenting** the target code so that it will produce interesting real-time trace from code execution. In this sense it is similar to peppering the code with `printf` statements. However, the main difference between QS and `printf` is *where* the data **formatting** and **sending** is done. When you use `printf`s, the data formatting and sending occur in the time-critical paths through your embedded code. In contrast, the QS target-resident component inserts raw binary data into the QS ring buffer, so all the time-consuming formatting is removed from the Target system and is done *after* the fact in the Host. Additionally, in QS, data logging and sending to the Host are separated so that the target system can typically perform the transmission outside of the time-critical path, for example in the *idle processing* of the target CPU. -

- -The QS target component consists of the QS ring buffer, the QS filters, as well as the instrumentation added to the QP framework and the application, as shown in figure below. Additionally, the QS target component contains the receive-channel (@ref qs_rx "QS-RX") with its own receive buffer, which can receive data from the QSPY host component. - -@anchor fig_struct -@image html qspy5.gif "Structure of the QP/Spy software tracing system" - -A nice byproduct of removing the data formatting from the Target is a natural **data compression**. For example, formatted output of a single byte takes two hexadecimal digits(and 3 decimal digits), so avoiding the formatting gives at least a factor of two in data density. On top of this natural compression, QS uses such techniques as data dictionaries, and compressed format information, which in practice result in compression factor of 4-5 compared to the expanded human-readable format. - -@attention -The QS instrumentation is designed such that it is active only in the *Spy build configuration* (when the external macro #Q_SPY is defined) and is **inactive** otherwise. This means that you don't need to comment-out or remove the instrumentation in the Debug or Release build configurations, but rather you can **leave** the instrumentation in your code for its future development, testing, profiling and maintenance. - - -@section qs_tstamp Target Time-Stamps -Most QS trace records produced by QS are **time-stamped** with a high-resolution counter (the resolution depends on the availability of a hardware timer-counter in the Target, but typically provides sub-microsecond granularity). QS provides an efficient API for obtaining platform-specific timestamp information. Given the right timer-counter resource in you Target system, you can provide QS with as precise timestamp information as required. The size of the timestamp is configurable to be 1, 2, or 4 bytes (see #QS_TIME_SIZE). - -@note -The QS **timestamps** are used differently in the @ref qutest "QUTest™" unit testing. In that case the timestamps are used to count the QS records produced. - - - -@section qs_pre Predefined QS Trace Records -The QP/C and QP/C++ frameworks contain the QS instrumentation for tracing the interesting occurrences within the frameworks, such as state machines activity (dispatching events, entering/exiting a state, executing transitions, etc.), active object activity (allocating events, posting/publishing events, time events, etc.), and more. All this instrumentation reserves 100 **predefined** QS trace records, which are enumerated in ::QSpyRecords. These QS records have predefined (hard-coded) structure both in the QS target-resident component and the @ref qspy "QSPY" host-based application. See also the documentation of the @ref qspy_pre "human-readable output" generated from the predefined QS records. - - - -@section qs_app Application-Specific QS Trace Records -Additionally to the predefined QS records, you can add your own, flexible, **application-specific** trace records, which are not known in advance to the @ref qspy "QSPY" host-resident component. You can think of the application-specific records as an equivalent to `printf()` but with much less overhead. The following code snippet shows an example of an application-specific QS record from your embedded code: - -@code -enum MyAppRecords { - PHILO_STAT = QS_USER, /* offset for User QS Records */ - COMMAND_STAT, - ~ ~ ~ -}; -~ ~ ~ -QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* application-specific record begin */ - QS_U8(1, n); /* application-specific data element (Philo number) */ - QS_STR(stat); /* application-specific data element (Philo status) */ -QS_END() /* application-specific record end */ -@endcode - -As you can see from the example above, an application-specific trace record always begins with QS_BEGIN_ID(), followed by a number of @ref qs_app_el "application-specific data elements", followed by QS_END(). - -@attention -The application-specific records use the 25 @ref qpspy_proto "Record-Types" in the range #QS_USER .. 124 (see also User-All group in @ref qs_global "Global Filter"). Therefore, you need to **offset** your application-specific trace records by the #QS_USER constant to avoid overlap with the @ref qs_pre "predefined QS records" already instrumented into the QP components. - -@note -As all QS trace records, the application-specific records are produced in a critical section of code (interrupts disabled). Therefore, you should keep the number of @ref qs_app_el "application-specific data elements" of the record reasonably short. - - -@subsection qs_app_rep Application-Specific Record Representation -The biggest challenge in supporting flexible "application-specific" trace records is to provide the data type information with the data itself, so that @ref qspy "QSPY" "knows" how to parse such record and move on to the next data element within the record. The figure below shows the encoding of the application-specific trace record from the listing previous. - -@image html qspy_app.gif "Structure of an Application-Specific trace record" - -The application-specific trace record, like all @ref qpspy_proto "QS records", starts with the Sequence Number and the -Record-Type. Every application-specific trace record also contains the @ref qs_tstamp "timestamp" immediately following the Record Type. The number of bytes used by the timestamp is configurable by the macro #QS_TIME_SIZE. After the timestamp, you see the data elements, such as a byte (QS_U8()) and a string (QS_STR()). Each of these data elements starts with a fmt (format) byte, which actually contains both the data-type information (in the lower nibble) and the format width for displaying that element (in the upper nibble). For example, the data element QS_U8(1, n) will cause the value 'n' to be encoded as u`int8_t` with the format width of 1 decimal digits. - -@remark -The maximum allowed format width is 15 decimal digits, while format width of 0 means that a numeric value should be formatted in minimum number of digits. - - -As shown in the listing above, typically the application-specific records are enclosed with the QS_BEGIN_ID() / QS_END() pair of macros. This pair of macros disables interrupts at the beginning and enables at the end of each record. Occasionally you would want to generate trace data from within already established critical sections or ISRs. In such rare occasions, you would use the macros QS_BEGIN_NOCRIT() / QS_END_NOCRIT() to avoid nesting of critical sections. - -The record-begin macro QS_BEGIN_ID() takes two arguments. The first argument (e.g., `PHILO_STAT`) is the enumerated @ref qpspy_proto "Record-Type", which is used in the @ref qs_global "global filter" and is part of the each record header. - -The second argument (e.g., `AO_Philo[n]->prio` in the example above) is used for the @ref qs_local "local filter", which allows you to selectively log only specific objects. The code snippet shows an example of an application-specific trace record, including the use of the second parameter of the QS_BEGIN_ID() macro. - - -@subsection qs_app_exa Application-Specific Record Examples -The following examples show the QS application-specific trace records as C code on the left, and the output generated by the @ref qspy "QSPY" host application from these records. The examples assume that the @ref qs_dict "QS dictionaries" have been produced for the Record-Types and function/object pointers used. - - - - - - - - - - - - - - - - - - - - - - - - - - -
Trace RecordQSPY ouptut
-@code -QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) - QS_U8(1, n); - QS_STR(stat); -QS_END() -@endcode - -`1018004718 PHILO_STAT 1 thinking`@n -NOTE: produced only when `AO_Philo[n]` is enabled in the @ref qs_local "QS Local Filter" -
-@code -QS_BEGIN_ID(IO_CALL, 0U) - QS_FUN(&IO_Read); - QS_I16(0, ret); - QS_U32(0, offset); -QS_END() -@endcode - -`1055004424 IO_CALL IO_Read -129 0` -
-@code -QS_BEGIN_ID(DATA_RX, 0U) - QS_OBJ(me); - QS_U16(data_len); - QS_MEM(data_buf, 16); -QS_END() -@endcode - -`0207024814 DATA_RX l_uart2 10 17 84 BB 40 FD 15 00 00 99 0B 00 00 90 0D 00 20` -
-@code -QS_BEGIN_ID(FP_DATA, QS_AP_ID + 1U) - QS_F32(6, 3141.5F); - QS_F64(10, -2.718281828e5); -QS_END() -@endcode - -`0991501750 FP_DATA 3.141500e+003 -2.7182818280e+005`@n -NOTE: produced only when QS-ID `QS_AP_ID + 1` is enabled in the @ref qs_local "QS Local Filter" -
- - -@subsection qs_app_el Application-Specific Data Elements -The following table summarizes the supported data elements that can be used inside the Application-Specific trace records: - -
-Data Element | Example | Comments -----------------|-----------------|--------- -QS_U8() | `QS_U8(0, n);` | Outputs a `uint8_t` integer with format `"%u"` -QS_I8() | `QS_I8(3, m);` | Outputs a `int8_t` integer with format `"%3d"` -QS_U16() | `QS_U16(5, n);` | Outputs a `uint16_t` integer with format `"%5u"` -QS_I16() | `QS_I16(0, m);` | Outputs a `int16_t` integer with format `"%d"` -QS_U32() | `QS_U32(8, n);` | Outputs a `uint32_t` integer with format `"%8u"` -QS_I32() | `QS_I32(0, m);` | Outputs a `int32_t` integer with format `"%d"` -QS_U32_HEX() | `QS_U32_HEX(8, h)` | Outputs a `uint32_t` integer with format `"%8X"` -QS_U64() | `QS_U32(0, n);` | Outputs a `uint32_t` integer with format `"%2"PRIi64` -QS_F32() | `QS_F32(0, 3.1415F);` | Outputs a 32-bit `float` with format `"%7.0e"`@n (zero digits after the comma) -QS_F64() | `QS_F64(4, sqrt(2.0));` | Outputs a 64-bit `double` with format `"%12.4e"` @n (4 digits after the comma) -QS_STR() | `QS_STR("Hello")` | Outputs a zero-terminated string with format `"%s"` -QS_MEM() | `QS_MEM(&my_struct, 16)` | Outputs 16 bytes of memory starting from `&my_struct`.@n The bytes are output using the hex format `"%02X"` -QS_OBJ() | `QS_OBJ(&my_obj);` | Outputs an object pointer.@n If an object dictionary for the object exists,@n @ref qspy "QSPY" will display the symbolic name of the object -QS_FUN() | `QS_OBJ(&foo);` | Outputs a function pointer.@n If a function dictionary for the function exists,@n @ref qspy "QSPY" will display the symbolic name of the function -QS_SIG() | `QS_SIG(TIMEOUT_SIG, (void*)0);` | Outputs a signal.@n If siganl dictionary for the siganl exists,@n @ref qspy "QSPY" will display the symbolic name of the signal -
- - -@section qs_filters QS Filters -Obviously, QS cannot eliminate completely the overhead of software tracing. But with the fine-granularity __filters__ available in QS, you can make this impact as small as necessary. For greatest flexibility, QS uses two complementary levels of filters: @ref qs_global "Global Filter" and @ref qs_local "Local Filter" described below. Combination of such two complementary filtering criteria results in very selective tracing capabilities. - -@note -The Global and Local filters are initialized in the QS_INIT() macro. Subsequently, the QP application can change the filters __at runtime__ by means of the QS_GLB_FILTER() and QS_LOC_FILTER() macros. Also, if the QS receive channel is enabled (@ref qs_rx "QS-RX"), the filters can be changed from the @ref qutest "QUTest" or @ref qview "QView" front-ends. - - -@subsection qs_global Global Filter -The Global Filter is based on trace @ref qpspy_proto "Record-Types" associated with each QS record (see ::QSpyRecords). This filter allows you to disable or enable each individual Record-Type or a whole group of QS records. For example, you might enable or disable #QS_QEP_STATE_ENTRY (entry to a state), #QS_QEP_STATE_EXIT (exit from a state), #QS_QEP_INIT_TRAN (state transition), #QS_QF_ACTIVE_POST (event posting), #QS_QF_PUBLISH (event publishing), and all other pre-defined and application-specific event types. This level works globally for all state machines, active objects, and time event objects in the entire system. - -QS provides a simple interface QS_GLB_FILTER() for setting and clearing individual Record-Types as well as groups of Record-Types in the Target code. The following table summarizes the Record-Types and groups of Record-Types that you can use as arguments to QS_GLB_FILTER(). - -@n -
-Record-Type@n/Group | Example | Applies to QS Records -----------------|---------|---------------------- -All Record-Types | QS_GLB_FILTER(QS_ALL_RECORDS);@n QS_GLB_FILTER(-QS_ALL_RECORDS); | all Record-Types -State@n Machine@n Group | QS_GLB_FILTER(QS_SM_RECORDS);@n QS_GLB_FILTER(-QS_SM_RECORDS); | #QS_QEP_STATE_ENTRY,@n #QS_QEP_STATE_EXIT,@n #QS_QEP_STATE_INIT,@n #QS_QEP_INIT_TRAN,@n #QS_QEP_INTERN_TRAN,@n #QS_QEP_TRAN,@n #QS_QEP_IGNORED,@n #QS_QEP_TRAN_HIST,@n #QS_QEP_TRAN_EP,@n #QS_QEP_TRAN_XP -Active@n Object@n Group | QS_GLB_FILTER(QS_AO_RECORDS);@n QS_GLB_FILTER(-QS_AO_RECORDS); | #QS_QF_ACTIVE_SUBSCRIBE,@n #QS_QF_ACTIVE_UNSUBSCRIBE,@n #QS_QF_ACTIVE_POST, @n #QS_QF_ACTIVE_POST_LIFO,@n #QS_QF_ACTIVE_GET, @n #QS_QF_ACTIVE_GET_LAST -Event@n Queue@n Group | QS_GLB_FILTER(QS_EQ_RECORDS);@n QS_GLB_FILTER(-QS_EQ_RECORDS); | #QS_QF_EQUEUE_POST,@n #QS_QF_EQUEUE_POST_LIFO,@n #QS_QF_EQUEUE_GET,@n #QS_QF_EQUEUE_GET_LAST -Memory@n Pool@n Group | QS_GLB_FILTER(QS_MP_RECORDS);@n QS_GLB_FILTER(-QS_MP_RECORDS); | #QS_QF_MPOOL_GET,@n #QS_QF_MPOOL_PUT -Time@n Event @n Group | QS_GLB_FILTER(QS_TE_RECORDS);@n QS_GLB_FILTER(-QS_TE_RECORDS); | #QS_QF_TICK,@n #QS_QF_TIMEEVT_ARM,@n #QS_QF_TIMEEVT_AUTO_DISARM,@n #QS_QF_TIMEEVT_DISARM_ATTEMPT,@n #QS_QF_TIMEEVT_DISARM,@n #QS_QF_TIMEEVT_REARM,@n #QS_QF_TIMEEVT_POST -QF Group@n Event@n Management| QS_GLB_FILTER(QS_QF_RECORDS);@n QS_GLB_FILTER(-QS_QF_RECORDS); | #QS_QF_NEW,@n #QS_QF_NEW_ATTEMPT,@n #QS_QF_GC_ATTEMPT,@n #QS_QF_GC,@n #QS_QF_TIMEEVT_DISARM_ATTEMPT,@n #QS_QF_TICK,@n -Scheduler@n Group | QS_GLB_FILTER(QS_SC_RECORDS);@n QS_GLB_FILTER(-QS_SC_RECORDS); | #QS_SCHED_LOCK,@n #QS_SCHED_UNLOCK,@n #QS_SCHED_NEXT,@n #QS_SCHED_IDLE,@n #QS_SCHED_RESUME,@n #QS_QF_TIMEEVT_DISARM_ATTEMPT,@n #QS_QF_TICK,@n -User Group-0 | QS_GLB_FILTER(QS_U0_RECORDS);@n QS_GLB_FILTER(-QS_U0_RECORDS); | #QS_USER + 0 .. #QS_USER + 4 -User Group-1 | QS_GLB_FILTER(QS_U1_RECORDS);@n QS_GLB_FILTER(-QS_U1_RECORDS); | #QS_USER + 5 .. #QS_USER + 9 -User Group-2 | QS_GLB_FILTER(QS_U2_RECORDS);@n QS_GLB_FILTER(-QS_U2_RECORDS); | #QS_USER + 10 .. #QS_USER + 14 -User Group-3 | QS_GLB_FILTER(QS_U3_RECORDS);@n QS_GLB_FILTER(-QS_U3_RECORDS); | #QS_USER + 15 .. #QS_USER + 19 -User Group-4 | QS_GLB_FILTER(QS_U4_RECORDS);@n QS_GLB_FILTER(-QS_U4_RECORDS); | #QS_USER + 20 .. #QS_USER + 24 -User-All@Group | QS_GLB_FILTER(QS_UA_RECORDS);@n QS_GLB_FILTER(-QS_UA_RECORDS); | #QS_USER + 0 .. #QS_USER + 24 -Non-Maskable | | #QS_SIG_DICT,@n #QS_OBJ_DICT,@n #QS_FUN_DICT,@n #QS_USR_DICT,@n #QS_TARGET_INFO,@n #QS_TARGET_DONE,@n #QS_EMPTY,@n #QS_TEST_PAUSED,@n #QS_TEST_PROBE_GET,@n #QS_RX_STATUS,@n #QS_QUERY_DATA,@n #QS_PEEK_DATA,@n #QS_ASSERT_FAIL,@n #QS_QF_RUN -
-@n - -@attention -The QS Global Filter is initialized in the QS_INIT() macro to __all OFF__ - - -Here are some examples of setting and clearing QS Global Filter with QS_GLB_FILTER(): - -@code{c} -if (!QS_INIT(argv)) { /* Initialize QS target component */ - return -1; /* unable to initialize QSpy */ -} -~ ~ ~ -/* apply the QS Global Filter... */ -QS_GLB_FILTER(QS_QF_RECORDS); /* turn QF-group ON */ -QS_GLB_FILTER(-QS_QF_TICK); /* turn #QS_QF_TICK OFF */ -@endcode - - -@subsection qs_local Local Filter -The Local Filter is based on __QS-IDs__ associated with various objects in the Target memory. The __QS-IDs__ are small integer numbers, such as the unique __priorities__ assigned to QP Active Objects, but there are more such QS-IDs, which _you_ can assign to various objects. Then, you can setup the QS Local Filter to trace only a specific groups of such QS-IDs. - -The main use case for QS Local Filter is an application, where certain active objects are very "noisy", and would overwhelm your trace. The QS Local Filter allows you to silence the "noisy" active objects and let the others through. - -Please note that the @ref qs_global "QS Global Filter" will not do the trick, because you don't want to suppress all QS records of a given Record-Type. Instead, you want to suppress only __specific objects__. - -QS provides a simple interface QS_LOC_FILTER() for setting and clearing individual QS-IDs as well as groups of QS-IDs in the Target code. The following table summarizes the QS-IDs and groups of QS_IDs that you can use as arguments to QS_LOC_FILTER(). - - -
-QS-ID@n /Group| Range | Example | Comments ---------------|---------|--------------------|------------- -0 | 0 | | always enabled -#QS_AO_IDS | 1..64 | QS_LOC_FILTER(QS_AO_IDS);@n QS_LOC_FILTER(-QS_AO_IDS);@n QS_LOC_FILTER(6);@n QS_LOC_FILTER(-6);@n QS_LOC_FILTER(AO_Table->prio)| Active Object priorities -#QS_EP_IDS@n | 65..80@n | QS_LOC_FILTER(QS_EP_ID + 1U); | enable Event-Pool #1 -#QS_EQ_IDS | 81..96 | QS_LOC_FILTER(QS_EQ_ID + 1U); | enable Event-Queue #1 -#QS_AP_IDS | 97..127 | QS_LOC_FILTER(QS_AP_ID + 1U); | enable Application Specific QS_ID -
-@n - -@attention -The QS Local Filter is initialized in the QS_INIT() macro to __all ON__ - - -Here are some examples of setting and clearing QS Local Filter with QS_LOC_FILTER(): - -@code{c} -if (!QS_INIT(argv)) { /* Initialize QS target component */ - return -1; /* unable to initialize QSpy */ -} -~ ~ ~ -/* apply the QS Local Filter... */ -QS_LOC_FILTER(-QS_EP_IDS); /* turn EP (Event-Pool) group OFF */ -QS_LOC_FILTER(3); /* turn AO with prioity 3 ON */ -QS_LOC_FILTER(AO_Table->prio); /* turn AO_Table ON */ -@endcode - - -@section qs_curr Current Objects -QS maintains a set of **Current Objects**, to which it applies commands received through the @ref qs_rx "QS-RX channel". For example, the event-post operation is applied to the current Active Object, while the peek/poke/fill operations are applied to the current Application Object. QS maintains the following Current Objects: -- ::SM_OBJ - State Machine object -- ::AO_OBJ - Active Object object -- ::MP_OBJ - Memory Pool object -- ::EQ_OBJ - Event Queue object -- ::TE_OBJ - Time Event object - -@note -Current Objects can be set only by sending commands to the @ref qs_rx "QS-RX receive channel". - - -@section qs_dict QS Dictionaries -By the time you compile and load your application image to the Target, the symbolic names of various objects, function names, and event signal names are stripped from the code. Therefore, if you want to have the symbolic information available to the @ref qspy "QSPY" host-resident component, you need to supply it somehow to the software tracing system. - -The QS Target-resident component provides special **dictionary trace records** designed expressly for providing the symbolic information about the target code in the trace itself. These "dictionary records" are very much like the symbolic information embedded in the object files for the traditional single-step debugger. QS can supply four types of dictionary trace records: - -- object dictionary ( QS_OBJ_DICTIONARY() ) -- function dictionary ( QS_FUN_DICTIONARY() ) -- signal dictionary ( QS_SIG_DICTIONARY() ) -- user dictionary ( QS_USR_DICTIONARY() ) - -The dictionary trace records are typically generated during the system initialization and this is the only time when they are sent to the @ref qspy "QSPY" host component. It is **your** responsibility to code them in (by means of the `QS_???_DICTIONARY()` macros). The following code snippet provides some examples of generating QS dictionaries: - - -@code{c} -void main(void) { - ~ ~ ~ - if (!QS_INIT(argv)) { /* Initialize QS target component */ - return -1; /* unable to initialize QSpy */ - } - - /* dictionaries... */ - QS_OBJ_DICTIONARY(&myObject); - QS_OBJ_DICTIONARY(AO_Table); /* opaque pointer */ - QS_FUN_DICTIONARY(&myFun); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void*)0); - - QS_USR_DICTIONARY(ON_TEST_SETUP); - QS_USR_DICTIONARY(ON_TEST_TEARDOWN); - QS_USR_DICTIONARY(COMMAND_X); - ~ ~ ~ -} -@endcode -@n - -@remarks -The dictionary trace records are not absolutely required to generate the human-readable output, in the same way as the symbolic information in the object files is not absolutely required to debug your code. However, in both cases, the availability of the symbolic information greatly improves the productivity in working with the software trace or the debugger. - - -@section qs_rx QS-RX Receive-Channel -The QS target component contains the receive-channel (QS-RX), which can receive data from the @ref qspy "QSPY" host application. The QS-RX channel provides the following services: -- Remotely reset of the Target -- Request target information (version, all sizes of objects, build time-stamp) -- Execute a user-defined command inside the Target with arguments supplied from @ref qspy "QSPY" -- Inject an arbitrary event to the Target (dispatch, post or publish) -- Set @ref qs_global "QS Global Filter" inside the Target -- Set @ref qs_local "QS Local Filter" inside the Target -- Set @ref qs_curr "current QS object" inside the Target -- Peek data inside the Target and send to @ref qspy "QSPY" -- Poke data (supplied from @ref qspy "QSPY") into the Target -- Fill specified memory area in the Target with bit pattern supplied from @ref qspy "QSPY" -- Execute clock tick inside the Target -- Execute test setup inside the Target -- Execute test teardown inside the Target -- Store a @ref qutest_fixture-probe "Test Probe" supplied from @ref qspy "QSPY" inside the Target - -@note -The QS-RX channel is the backbone for interacting with the target system and implemeting such features as @ref qutest "Unit Testing" and @ref qview "Visualization/Monitoring" of the target system. - -@next{qspy} -*/ diff --git a/doxygen/qspy.dox b/doxygen/qspy.dox deleted file mode 100644 index c7dae0f..0000000 --- a/doxygen/qspy.dox +++ /dev/null @@ -1,2809 +0,0 @@ -/*! @page qspy QSPY Host Application - -@tableofcontents - -@section qspy_about About QSPY -

As described in the @ref qpspy "previous section", **QSPY** is the host-resident component in the QP/Spy software tracing system. QSPY is a simple console application without a GUI, because its main purpose is to provide @ref qspy_link "communication" with the @ref qs "QS target-resident component", parsing of the @ref qpspy_proto "QP/Spy Data Protocol" and displaying the data in a simple @ref qspy_text "human-readable format". -

- -QSPY can also export the data in various other formats, such as format suitable for @ref qspy_matlab "MATLAB/GNU-Octave", and format suitable for generating @ref qspy_seq "sequence diagrams". Additionally, QSPY can also save the symbolic information about the Target objects in form of @ref qspy_dict "QSPY dictionaries". An example of a @ref qpspy_exa "QSPY session" is shown in the Introduction to QP/Spy. - -Finally, QSPY supports also extensible @ref qspy_udp "UDP-socket" connection, which allows it to serve as a "Back-End" for attaching various "Front-Ends" (such as the @ref qutest "QUTest" Front-End and @ref qview "QView" Front-End). - -@remark -QSPY is written in portable C with ports to Windows and POSIX (Linux, macOS) provided. QSPY is also designed to be adaptable to various target-host communication links. Out of the box, the QSPY host application supports serial (RS232), TCP/IP, and file communication links. Adding other communication links is straightforward, because the data link is accessed only through a generic Platform Abstraction Layer (PAL). - - -@section qspy_command QSPY Command-Line Parameters -

The QSPY application accepts several command-line parameters to configure the data link to the Target, backwards-compatibly with previous versions, and target dependencies, such as pointer sizes, signal sizes, etc. This means that the single QSPY host application can process data from any Target running the QS component. QSPY has been tested with wide range of 8-, 16-, 32-, and 64-bit CPUs. -

- -The general form of invoking QSPY is as follows: - -@verbatim -qspy [options] -@endverbatim - -where `options` are described in the following table: - -@verbatim -Usage: qspy [options] = required, [arg] = optional -@endverbatim - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Option Example Default@n (key) Must match QP macro@n (QP port header file) Comments
-h-hHelp. Prints the summary of options
-q [num]-q 99(key-q)Quiet mode (reduced stdout output)
-u [UDP_port|0]-u7701UDP socket for "Front-Ends".@n`-u0` suppresses opening the UPD socket
-v <QS_version>-v 6.26.6Enforce backwards-compatibility with the specific QS version
-k-ksuppress keyboard input
-o-o(key-o)Produce output to the specified file
-s-s(key-s)Save the binary input to a file. Not compatible with -f -
-m-m(key-m)Produce @ref qspy_matlab "MATLAB/GNU-Octave output" to a file
-g [object-list]-g Table::inst,Philo::inst[0],Philo::inst[1](key-g)Produce @ref qspy_seq "Sequence diagram output" to a file
-t [TCP-port]-t 6601TCP/IP input selection. Not compatible with -c, -b, -f
-c <port>-c COM2COM1COM port selection. Not compatible with -t, -p, -f
-b <baud>-b 38400115200Baud rate selection. Not compatible with -t, -p, -f
-f <file>-f qs.spyFile input selection. Not compatible with -c, -b, -t, -p
-d [file]-d qspy150831_144229.dicRead @ref qspy_dict "dictionaries" from a file.
Options for configuring Target object sizes:@n -The Target can **report** it's configuration to QSPY, which means that you don't need to provide any upper-case options (such as: `-T`, `-O`, `-F`, etc.). -
-T <size>-T 24@c QS_TIME_SIZE @n (qs_port.h)Time stamp size in bytes. Valid values: 1, 2, 4
-O <size>-O 24@c QS_OBJ_PTR_SIZE @n (qs_port.h)Object pointer size in bytes. Valid values: 1, 2, 4, 8
-F <size>-F 24@c QS_FUN_PTR_SIZE @n (qs_port.h)Function pointer size in bytes. Valid values: 1, 2, 4, 8
-S <size>-S 12@c Q_SIGNAL_SIZE @n (qep_port.h)Signal size in bytes. Valid values: 1, 2, 4
-E <size>-E 12@c QF_EVENT_SIZ_SIZE @n (qf_port.h)Event-size size in bytes (i.e., the size of variables that hold - event size). Valid values: 1, 2, 4
-Q <size>-Q 21@c QF_EQUEUE_CTR_SIZE @n (qf_port.h)Queue counter size in bytes. Valid values 1, 2, 4
-P <size>-P 42@c QF_MPOOL_CTR_SIZE @n (qf_port.h)Pool counter size in bytes. Valid values: 1, 2, 4
-B <size>-B 12@c QF_MPOOL_SIZ_SIZE @n (qf_port.h)Block size size in bytes. (i.e., the size of variables that hold - memory block size). Valid values 1, 2, 4
-C <size>-C 42@c QF_TIMEEVT_CTR_SIZE @n (qf_port.h)Time event counter size. Valid values: 1, 2, 4
- - -Your main concern when invoking QSPY is to match exactly the target system you -are using. The fourth column of the table above lists the configuration macros -used by the target system as well as the platform-specific QP header files -where those macros are defined. You need to use the corresponding QSPY -command-line option only when the QP macro differs from the default. The -default values assumed by QSPY are consistent with the defaults used in QP. - -@note -When you do not match the QSPY host application with the QS target -component, the QSPY application will be unable to parse correctly the -mismatched trace records and will start generating the following errors:@n -@n -@verbatim - ~ ~ ~ - ERROR 4 bytes unused in Rec=QS_QEP_INTERN_TRAN - ~ ~ ~ - ERROR 2 bytes unused in Rec=QS_QEP_DISPATCH -@endverbatim -@n -The name after `Rec=` indicates the Record ID of the trace record that failed to be parsed. - - - -@subsection qspy_default Default Configuration -The QSPY application invoked **without any parameters** defaults to the following configuration: - -@verbatim -C:\tmp>qspy -QSPY 6.6.0 Copyright (c) 2005-2019 Quantum Leaps -Documentation: https://www.state-machine.com/qtools/qspy.html -Current timestamp: 190811_124028 --u 7701 --t 6601 --v 660 --T 4 --O 4 --F 4 --S 2 --E 2 --Q 1 --P 2 --B 2 --C 2 -@endverbatim - -Specifically, by default QSPY **opens the UDP socket** at the default port (`-u 7701`) for "back-ends" (such as @ref qutest "QUTest") and **opens the TCP/IP socket** at the default port (`-t 6601`) for communication with the Targets. - - -The other parameters correspond to 32-bit Target CPUs, such as ARM and x86 compiled in 32-bit mode. The x86 is relevant for running the embedded software on host machines based on the x86 processors. - -@remark -The default QSPY configuration is specifically designed for running @ref qutest "QUTest" tests on the x86-based hosts with target executables compiled in the 32-bit x86 mode. This default configuration also matches 32-bit ARM CPUs, but typically requires the single `-c ` parameter to communicate with the embedded Target via a serial port.@n -@n -The default QSPY configuration (without any parameters) is also backwards-compatible with the following invocation: `qspy -u -t`, which is recommended for running QUTest tests on the host computer. Starting with QSPY version 7.x.y, you can use the simpler `qspy` invocation. - - -@section qspy_terminating Terminating QSPY -The QSPY host application can be terminated in the following ways: - -- by typing `x` or `X` key (works only in the absence of the __-k__ @ref qspy_command "command-line option") -- by typing `Esc` key (works only in the absence of the __-k__ @ref qspy_command "command-line option") -- by typing `Ctrl-C` (works also with the `-k` option) -- by sending the Kill signal to the process running QSPY - - -@section qspy_keyboard QSPY Keyboard Commands -In the __absence of the -k (suppress keyboard) command-line option__, the QSPY console application accepts keyboard input. The following table shows the currently supported key-strokes: - - -Key | Action -----|--------- -`<Esc>` | Exit QSPY -`h` | display keyboard help and QSPY status -`c` | clear the screen -`q` | toggle quite mode (no Target output to the screen) -`r` | send RESET command to the Target -`i` | send the INFO request to the Target (see also @ref qspy_dict) -`t` | send TIKC[0] command to the Target -`u` | send TICK[1] command to the Target -`d` | save @ref qspy_dict "QP/Spy Dictionaries" to a file -`o` | toggle @ref qspy_text "QSPY Human-Readable Output" to a file (open/close) -`s`/`b` | toggle binary file output (open/close) -`m` | toggle @ref qspy_matlab "MATLAB Output" to a file (open/close) -`g` | toggle @ref qspy_seq "Sequence Output" to a file (open/close) - - -@n -@note -QSPY can send many more sophisticated commands to the Target by means of the @ref qview "Front-End extension mechanism". - - -@section qspy_link QSPY Communication with the Target -QSPY currently provides the following communication links to the @ref qs "QS target-resident component": - - -Communication Link | Command-Line Option -:------------------|:-------------------- -TCP/IP | `-t [TCP_port]` (default) -Serial port | `-c ` and `-b` -Binaly File | `-f ` -Other link@n(e.g., JTAG debug probe) | can be added to the QSPY Platform Abstraction Layer - - -@section qspy_saving Saving Files from QSPY - -QSPY can save the tracing data from the Target in various formats into files. QSPY assigns file names **automatically**. Also, QSPY can open/close various files multiple times in a single session, so it is no longer necessary to exit QSPY and launch it again with different command-line parameters to save data to a different file. - -@attention -QSPY saves all files into the current directory from which `qspy` has been launched. - -QSPY uses a very simple naming convention to assign file names. All names start with `qspy`, where the time-stamp format is: `YYMMDD_hhmmss`, where `YY` is 2-digit year, `MM` is a 2-digit month, `DD` is a 2-digit day of the month, `hh` is a 2-digit hour, `mm` is a 2-digit minute, and `ss` is a 2-digit second. The time-stamp is accurate to a one second, so its virtually impossible to have name conflicts for files generated on the same machine. The various types of files are distinguished by the following extensions: - -Command-Line@n Option | Keyboard@n Option| File@n Extension | Example | Comment -:-------------------:|:-----------------:|:----------------:|----------|---------- -`-o` | `o` | `.txt` | `qspy150914_132234.txt`| @ref qspy_text "text (screen) output" -`-s` | `s` | `.qs` | `qspy150914_132234.qs` | @ref qpspy_proto "raw binary output" -`-d` | `d` | `.dic` | `qspy150901_101203.dic` | @ref qspy_dict "dictionary output" -`-m` | `m` | `.mat` | `qspy150914_132234.mat` | @ref qspy_matlab "MATLAB output" -`-g` | `g` | `.seq` | `qspy150914_132234.seq` | @ref qspy_seq "Sequence diagram output" - -@note -All files except the dictionary output are time-stamped with the local time of the Host. The **dictionary** output is time-stamped with the build-time of the Target image. - - - -The following sub-sections explain the following QSPY features: - -- @subpage qspy_text "text (screen) output" -- @subpage qspy_dict "dictionary output" -- @subpage qspy_udp "UDP socket interface" -- @subpage qspy_seq "Sequence diagram output" -- @subpage qspy_matlab "MATLAB output" - -@next{qspy_text} -*/ -/*###########################################################################*/ -/** -@page qspy_text QSPY Screen Output - -@tableofcontents - -

QSPY provides a simple consolidated, human-readable textual output to the screen. The readability of this output depends strongly on the availability of the symbolic information about the various objects in the Target code, called @ref qspy_dict "dictionaries". If the "dictionaries" are not available, QSPY can output only the hexadecimal values of various object addresses and event signals. However, if QSPY has acquired the @ref qs_dict "dictionaries" from the Target, or has @ref qspy_dict "read them from a file", it can apply the symbolic information to output the provided identifiers for objects, signals, and states. -

- -@note -In the process of adapting QSPY for supporting @ref qutest "QUTest Unit Testing", the QSPY human-redable output has been changed to avoid any special characters used in regular expressions, such as `*, [, ], ?, !`. This is because the QUTest scripts use regular expressions to match QSPY textuall output with the expected output. - - -@section qspy_text_exa Screen Output Example -For example, the following listing shows the QSPY text output when the @ref qs_dict "dictionaries" **are** available: - -
-@verbatim -QSPY 6.9.0 Copyright (c) 2005-2020 Quantum Leaps -Documentation: https://www.state-machine.com/qtools/qspy.html -Current timestamp: 200827_093625 --c COM7 --u 7701 --v 660 --T 4 --O 4 --F 4 --S 2 --E 2 --Q 1 --P 2 --B 2 --C 2 - -########## Trg-RST QP-Ver=690,Build=200824_123230 - Obj-Dict 0x20001048->QS_RX - Obj-Dict 0x08004009->l_SysTick_Handler - Usr-Dict 00000100->PHILO_STAT - Obj-Dict 0x20000EE0->AO_Table - Obj-Dict 0x20000DDC->AO_Philo[0] - Obj-Dict 0x20000E10->AO_Philo[1] - . . . . . - Obj-Dict 0x20000F94->EvtPool1 - Obj-Dict 0x20000DDC->Philo_inst[0] - Obj-Dict 0x20000E00->Philo_inst[0].timeEvt - Obj-Dict 0x20000E10->Philo_inst[1] - Obj-Dict 0x20000E34->Philo_inst[1].timeEvt - Obj-Dict 0x20000E44->Philo_inst[2] - . . . . . - Fun-Dict 0x080006A9->Philo_initial - Fun-Dict 0x08000915->Philo_thinking - Fun-Dict 0x08000871->Philo_hungry - Fun-Dict 0x080007C5->Philo_eating - Sig-Dict 00000010,Obj=0x20000DDC->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000DDC->TIMEOUT_SIG -0000000000 AO-Subsc Obj=Philo_inst[0],Sig=00000004,Obj=0x20000DDC -0000000000 AO-Subsc Obj=Philo_inst[0],Sig=00000008,Obj=0x20000DDC -===RTC===> St-Init Obj=Philo_inst[0],State=0x08001099->Philo_thinking -0000000000 TE0-Arm Obj=Philo_inst[0].timeEvt,AO=Philo_inst[0],Tim=84,Int=0 -===RTC===> St-Entry Obj=Philo_inst[0],State=Philo_thinking -0000000000 Init===> Obj=Philo_inst[0],State=Philo_thinking - Sig-Dict 00000010,Obj=0x20000E10->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000E10->TIMEOUT_SIG - . . . . . - . . . . . -===RTC===> St-Init Obj=Table_inst,State=0x08001099->Table_serving -===RTC===> St-Entry Obj=Table_inst,State=Table_serving -0000000000 Init===> Obj=Table_inst,State=Table_serving - QF_RUN -4294946722 QF-Pub Sdr=l_SysTick_Handler,Evt -4294947277 AO-Post Sdr=l_SysTick_Handler,Obj=Table_inst,Evt,Que -4294948158 Sch-Next Pri=0->6 -4294948490 AO-GetL Obj=Table_inst,Evt -4294949010 Disp===> Obj=Table_inst,Sig=SERVE_SIG,State=Table_serving -4294949660 =>Ignore Obj=Table_inst,Sig=SERVE_SIG,State=Table_serving -4294950254 Sch-Idle Pri=6->0 - TE0-ADis Obj=Philo_inst[4].timeEvt,AO=Philo_inst[4] -4294946907 TE0-Post Obj=Philo_inst[4].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[4] -4294947535 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[4],Evt,Que -4294948568 Sch-Next Pri=0->5 -4294948900 AO-GetL Obj=Philo_inst[4],Evt -4294949419 Disp===> Obj=Philo_inst[4],Sig=TIMEOUT_SIG,State=Philo_thinking -4294950135 TE0-DisA Obj=Philo_inst[4].timeEvt,AO=Philo_inst[4] -===RTC===> St-Exit Obj=Philo_inst[4],State=Philo_thinking -4294951090 QF-New Sig=HUNGRY_SIG,Size=6 -4294951506 MP-Get Obj=EvtPool1,Free=9,Min=9 -4294952081 AO-Post Sdr=Philo_inst[4],Obj=Table_inst,Evt,Que -4294952841 Sch-Next Pri=5->6 -4294953173 AO-GetL Obj=Table_inst,Evt -4294953692 Disp===> Obj=Table_inst,Sig=HUNGRY_SIG,State=Table_serving -4294954299 PHILO_STAT 4 hungry -4294954817 QF-New Sig=EAT_SIG,Size=6 -4294955233 MP-Get Obj=EvtPool1,Free=8,Min=8 -4294955759 QF-Pub Sdr=Table_inst,Evt -4294956277 Sch-Lock Ceil=0->5 -4294956667 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt,Que -4294957464 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt,Que -4294958261 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt,Que -4294959058 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt,Que -4294959855 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt,Que -4294960624 Sch-Unlk Ceil=5->0 -. . . . . . -@endverbatim -
- -The QS trace log shown in the listing above contains quite detailed information, because most QS records are enabled (are not blocked in the @ref qs_filters "QS filters"). The following bullet items highlight the most interesting parts of the trace and illustrate how you can interpret the trace data: - -- The QS output starts with the QSPY application version number, the date and time of the run (run time-stamp), and all the options explicitly provided to the QSPY host application. - -- The first trace records in the log are typically @ref qspy_dict "dictionary trace records" that provide a mapping between addresses of various objects in memory and their symbolic names. - -- After the dictionaries, you see the active object initialization. For example, the `===RTC===> St-Init` record indicates that the top-most initial transition in the active object `l_table` has been taken. After this, the `===RTC===> St-Entry` record informs you that the state `Table_serving` has been entered, and finally the record `==>Init` tells you that the top-most initial transition sequence has completed. This trace record has a high-resolution @ref qs_tstamp "time-stamp" (the first 10-digit number) generated by the Target. The time units used by this time-stamp depend on the specific hardware timer used in the Target, but typically it is sub-microsecond. - -- After this you see that at the time-stamp `0000380805` an event was dispatched (`Disp===>` record) to `l_table`, but it was subsequently `Ignored`, while `l_table` was in the state `Table_serving`. - - -@section qspy_pre Predefined Trace Records -The following table summarizes the text output format used for all predefined QS trace records (see ::QSpyRecords). - -@note -To better adapt QSPY to support @ref qutest "QUTest Unit Testing", the QSPY human-redable output has been changed at @ref qtools_5_9_0 "version 5.9.0" to avoid any special characters used in regular expressions, such as `*, [, ], ?, !`. This is because the QUTest scripts use regular expressions to match QSPY textuall output with the expected output. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
State Machine Trace Records (QEP)
Rec.@n Num.Rec.@n Enum.Start of recordComment
1#QS_QEP_STATE_ENTRY`===RTC===> St-Entry`a state was entered
2#QS_QEP_STATE_EXIT`===RTC===> St-Exit`a state was exited
3#QS_QEP_STATE_INIT` St-Init`an initial transition was taken in a state
4#QS_QEP_INIT_TRAN` Init===>`the top-most initial transition was taken
5#QS_QEP_INTERN_TRAN` =>Intern`an internal transition was taken
6#QS_QEP_TRAN` ===>Tran `a regular transition was taken
7#QS_QEP_IGNORED` =>Ignore`an event was ignored (silently discarded)
8#QS_QEP_DISPATCH` Disp===>`an event was dispatched (begin of RTC step)
9#QS_QEP_UNHANDLED`===RTC===> St-Unhnd`a guard prevented handling of an event
55#QS_QEP_TRAN_HIST`===RTC===> St-Hist`an a transition to history was taken
56#QS_QEP_TRAN_EP`===RTC===> St-EP`an a transition to entry point into a submachine
57#QS_QEP_TRAN_XP`===RTC===> St-XP`an a transition to exit point out of a submachine
Active Object Trace Records
Rec.@n Num.Rec.@n Enum.Start of recordComment
12#QS_QF_ACTIVE_SUBSCRIBE` AO-Subsc`an AO subscribed to an event
13#QS_QF_ACTIVE_UNSUBSCRIBE` AO-Unsub`an AO unsubscribed to an event
14#QS_QF_ACTIVE_POST` AO-Post`an event was posted (FIFO) directly to AO
15#QS_QF_ACTIVE_POST_LIFO` AO-LIFO`an event was posted (LIFO) directly to AO
16#QS_QF_ACTIVE_GET` AO-Get`AO got an event and its queue is still not empty
17#QS_QF_ACTIVE_GET_LAST` AO-GetL`AO got an event and its queue is empty
45#QS_QF_ACTIVE_POST_ATTEMPT` AO-PostA`attempt to post an evt to AO failed
Raw Event Queue Trace Records
Rec.@n Num.Rec.@n Enum.Start of recordComment
19#QS_QF_EQUEUE_POST` EQ-Post`an event was posted (FIFO) to a raw queue
20#QS_QF_EQUEUE_POST_LIFO` EQ-LIFO`an event was posted (LIFO) to a raw queue
21#QS_QF_EQUEUE_GET` EQ-Get`get an event and queue still not empty
22#QS_QF_EQUEUE_GET_LAST` EQ-GetL`get the last event from the queue
46#QS_QF_EQUEUE_POST_ATTEMPT` EQ-PostA`attempt to post an evt to QEQueue failed
Raw Memory Pool Trace Records
Rec.@n Num.Rec.@n Enum.Start of recordComment
24#QS_QF_MPOOL_GET` MP-Get`a memory block was removed from a memory pool
24#QS_QF_MPOOL_GET_ATTEMPT` MP-GetA`a memory block was removed from a memory pool
25#QS_QF_MPOOL_PUT` MP-Put`a memory block was returned to a memory pool
47#QS_QF_MPOOL_GET_ATTEMPT` MP-GetA`attempt to get a memory block failed
Event Management (QF)
Rec.@n Num.Rec.@n Enum.Start of recordComment
26#QS_QF_PUBLISH` QF-Pub`an event was published
27RESERVED
28#QS_QF_NEW` QF-New`new event creation
29#QS_QF_GC_ATTEMPT` QF-gcA`garbage collection attempt
30#QS_QF_GC` QF-gc`garbage collection performed
31#QS_QF_TICK`           Tick`QF system clock tick processing was called
39#QS_QF_CRIT_ENTRY` QF-CritE`critical section was entered
40#QS_QF_CRIT_EXIT` QF-CritX`critical section was exited
41#QS_QF_ISR_ENTRY` QF-IsrE`an ISR was entered
42#QS_QF_ISR_EXIT` QF-IsrX`an ISR was exited
Time Events (TE)
Rec.@n Num.Rec.@n Enum.Start of recordComment
32#QS_QF_TIMEEVT_ARM` TE-Arm`a time event was armed
33#QS_QF_TIMEEVT_AUTO_DISARM` TE-ADis`a time event expired and was disarmed
34#QS_QF_TIMEEVT_DISARM_ATTEMPT` TE-DisA`attempt to disarmed a disarmed tevent
35#QS_QF_TIMEEVT_DISARM` TE-Dis`true disarming of an armed time event
36#QS_QF_TIMEEVT_REARM` TE-Rarm`rearming of a time event
37#QS_QF_TIMEEVT_POST` TE-Post`a time event posted itself directly to an AO
38#QS_QF_TIMEEVT_CTR` TE-Ctr`a time event counter was requested
Scheduler Trace Records
Rec.@n Num.Rec.@n Enum.Start of recordComment
50#QS_SCHED_LOCK` Sch-Lock`scheduler was locked
51#QS_SCHED_UNLOCK` Sch-Unlk`scheduler was unlocked
52#QS_SCHED_NEXT` Sch-Next`scheduler found next task to execute
53#QS_SCHED_IDLE` Sch-Idle`scheduler became idle
54#QS_SCHED_RESUME` Sch-Rsme`scheduler resumed previous task (not idle)
Miscellaneous Trace Records@n - NOT MASKABLE WITH THE @ref qs_global "QS GLOBAL FILTER"! - -
Rec.@n Num.Rec.@n Enum.Start of recordComment
58#QS_TEST_PAUSED`           TstPause`test has been paused
59#QS_TEST_PROBE_GET` TstProbe`reports that Test-Probe has been used
60#QS_SIG_DICTIONARY`           Sig-Dict`signal dictionary entry
61#QS_OBJ_DICTIONARY`           Obj-Dict`object dictionary entry
62#QS_FUN_DICTIONARY`           Fun-Dict`function dictionary entry
63#QS_USR_DICTIONARY`           Usr-Dict`User record dictionary entry
64#QS_TARGET_INFO`########## Trg-Info`reports the Target information
65#QS_TARGET_DONE` Trg-Done`reports completion of a user callback
66#QS_RX_STATUS`           Trg-Ack`reports QS data receive status
66RESERVED
66#QS_PEEK_DATA`           Trg-Peek`reports the data from the PEEK query
67#QS_ASSERT_FAIL` =ASSERT=`Assertion fired
User (Application Specific) Records
100#QS_USER + xxx` USER+xxx`@ref qs_app "application-specific" (user) QS records (100..124)
- -@next{qspy_dict} -*/ -/*###########################################################################*/ -/** -@page qspy_dict QSPY Dictionaries - -@tableofcontents - -@section qspy_dict_about About QSPY Dictionaries -By the time you compile and load your application image to the Target, the symbolic names of various objects, function names, and event signal names are stripped from the code. Therefore, if you want to have the symbolic information available to the QSPY host-resident component, you need to supply it somehow to the software tracing system. - -The QS Target-resident component provides special @ref qs_dict "dictionary trace records" designed expressly for providing the symbolic information about the target code in the trace itself. These "dictionary records" are very much like the symbolic information embedded in the object files for the traditional single-step debugger. QS can supply four types of dictionary trace records: - -- object dictionary -- for identifying objects (HSMs, AOs, Time events, etc) -- function dictionary -- for identifying functions (state-handlers) -- signal dictionary -- for identifying event signals -- user dictionary -- for identifying @ref qs_app "application-specific" (user) records - -@note -QSPY does not absolutely require the presence of dictionary trace records to generate the human-readable output, in the same way as the symbolic information in the object files is not absolutely required to debug code. However, in both cases, the availability of the symbolic information greatly improves the readability of the disassembly code shown in the debugger. - - -For instance, the following listing shows an example of the QSPY text output when the "dictionaries" are **not** available. (NOTE: dictionaries might not be available because (1) the Target does not produce @ref qs_dict "dictionary trace records" for all relevant objects or (2) the Target does produce all dictionaries, but QSPY has never seen them, because it was attached to the Target after the dictionaries have been transmitted): -@n -@verbatim -. . . . . . -0009692721 Disp===> Obj=0x2000133C,Sig=00000010,Obj=0x2000133C,State=0x000010C5 -0009693389 USER+000 4 hungry -0009695383 USER+000 4 eating -0009695932 =>Intern Obj=0x2000133C,Sig=00000010,Obj=0x2000133C,State=0x000010C5 -===RTC===> St-Entry Obj=0x200012F8,State=0x00000D49 -0009697188 ===>Tran Obj=0x200012F8,Sig=00000011,Obj=0x200012F8,State=0x00000DD5->0x00000D49 -0009698052 Disp===> Obj=0x200012F8,Sig=00000004,Obj=0x200012F8,State=0x00000D49 -===RTC===> St-Entry Obj=0x200012F8,State=0x00000CA9 -0009699697 ===>Tran Obj=0x200012F8,Sig=00000004,Obj=0x200012F8,State=0x00000D49->0x00000CA9 -0009700602 Disp===> Obj=0x200012B8,Sig=00000004,Obj=0x200012B8,State=0x00000DD5 -0009701247 =>Intern Obj=0x200012B8,Sig=00000004,Obj=0x200012B8,State=0x00000DD5 -0009702038 Disp===> Obj=0x20001278,Sig=00000004,Obj=0x20001278,State=0x00000DD5 -0009702677 =>Intern Obj=0x20001278,Sig=00000004,Obj=0x20001278,State=0x00000DD5 -0009703468 Disp===> Obj=0x20001238,Sig=00000004,Obj=0x20001238,State=0x00000DD5 -0009704107 =>Intern Obj=0x20001238,Sig=00000004,Obj=0x20001238,State=0x00000DD5 -0009704899 Disp===> Obj=0x200011F8,Sig=00000004,Obj=0x200011F8,State=0x00000DD5 -0009705538 =>Intern Obj=0x200011F8,Sig=00000004,Obj=0x200011F8,State=0x00000DD5 -0015961105 Disp===> Obj=0x200011F8,Sig=00000011,Obj=0x200011F8,State=0x00000DD5 -===RTC===> St-Exit Obj=0x200011F8,State=0x00000DD5 -0015962823 Disp===> Obj=0x2000133C,Sig=00000010,Obj=0x2000133C,State=0x000010C5 -0015963491 USER+000 0 hungry -. . . . . . -@endverbatim - -And here is the exact same trace data when the "dictionaries" **are** available: - -@verbatim -. . . . . . -0009692721 Disp===> Obj=l_table,Sig=HUNGRY_SIG,State=Table_serving -0009693389 PHILO_STAT 4 hungry -0009695383 PHILO_STAT 4 eating -0009695932 =>Intern Obj=l_table,Sig=HUNGRY_SIG,State=Table_serving -===RTC===> St-Entry Obj=l_philo[4],State=Philo_hungry -0009697188 ===>Tran Obj=l_philo[4],Sig=TIMEOUT_SIG,State=Philo_thinking->Philo_hungry -0009698052 Disp===> Obj=l_philo[4],Sig=EAT_SIG,State=Philo_hungry -===RTC===> St-Entry Obj=l_philo[4],State=Philo_eating -0009699697 ===>Tran Obj=l_philo[4],Sig=EAT_SIG,State=Philo_hungry->Philo_eating -0009700602 Disp===> Obj=l_philo[3],Sig=EAT_SIG,State=Philo_thinking -0009701247 =>Intern Obj=l_philo[3],Sig=EAT_SIG,State=Philo_thinking -0009702038 Disp===> Obj=l_philo[2],Sig=EAT_SIG,State=Philo_thinking -0009702677 =>Intern Obj=l_philo[2],Sig=EAT_SIG,State=Philo_thinking -0009703468 Disp===> Obj=l_philo[1],Sig=EAT_SIG,State=Philo_thinking -0009704107 =>Intern Obj=l_philo[1],Sig=EAT_SIG,State=Philo_thinking -0009704899 Disp===> Obj=l_philo[0],Sig=EAT_SIG,State=Philo_thinking -0009705538 =>Intern Obj=l_philo[0],Sig=EAT_SIG,State=Philo_thinking -0015961105 Disp===> Obj=l_philo[0],Sig=TIMEOUT_SIG,State=Philo_thinking -===RTC===> St-Exit Obj=l_philo[0],State=Philo_thinking -0015962823 Disp===> Obj=l_table,Sig=HUNGRY_SIG,State=Table_serving -0015963491 PHILO_STAT 0 hungry -. . . . . . -@endverbatim - -As you can see, the difference in readability is quite dramatic. - - -@section qspy_dict_get Acquiring Dictionaries -The QS Target-resident component generates the dictionary trace records during the initialization of active objects components in the Target code, that is, typically right after the reset. Consequently, the best way to acquire the dictionaries is to capture the trace when the Target performs the reset. This can be done in a couple of ways: -- Start QSPY **before** the Target resets -- Manually reset the Target while QSPY is running (e.g., press a Reset button on the Target board) -- Send the @ref qspy_keyboard "RESET command" to the Target from QSPY while it is running - -Either way, the dictionary records should be produced and acquired by the Target. The following listing shows the dictionary records sent by the DPP example application running on a STM32 NUCLEO board: - -
-@verbatim -C:\qp\qpc\examples\arm-cm\dpp_nucleo-l152re\qk\gnu>qspy -cCOM7 -QQSPY 6.9.0 Copyright (c) 2005-2020 Quantum Leaps -Documentation: https://www.state-machine.com/qtools/qspy.html -Current timestamp: 200827_093625 --c COM7 --u 7701 --v 620 --T 4 --O 4 --F 4 --S 2 --E 2 --Q 1 --P 2 --B 2 --C 2 - -########## Trg-RST QP-Ver=690,Build=200824_123230 - Obj-Dict 0x20001048->QS_RX - Obj-Dict 0x08004009->l_SysTick_Handler - Usr-Dict 00000100->PHILO_STAT - Obj-Dict 0x20000EE0->AO_Table - Obj-Dict 0x20000DDC->AO_Philo[0] - Obj-Dict 0x20000E10->AO_Philo[1] - Obj-Dict 0x20000E44->AO_Philo[2] - Obj-Dict 0x20000E78->AO_Philo[3] - Obj-Dict 0x20000EAC->AO_Philo[4] - Obj-Dict 0x20000F94->EvtPool1 - Obj-Dict 0x20000DDC->Philo_inst[0] - Obj-Dict 0x20000E00->Philo_inst[0].timeEvt - Obj-Dict 0x20000E10->Philo_inst[1] - Obj-Dict 0x20000E34->Philo_inst[1].timeEvt - Obj-Dict 0x20000E44->Philo_inst[2] - Obj-Dict 0x20000E68->Philo_inst[2].timeEvt - Obj-Dict 0x20000E78->Philo_inst[3] - Obj-Dict 0x20000E9C->Philo_inst[3].timeEvt - Obj-Dict 0x20000EAC->Philo_inst[4] - Obj-Dict 0x20000ED0->Philo_inst[4].timeEvt - Fun-Dict 0x080006A9->Philo_initial - Fun-Dict 0x08000915->Philo_thinking - Fun-Dict 0x08000871->Philo_hungry - Fun-Dict 0x080007C5->Philo_eating - Sig-Dict 00000010,Obj=0x20000DDC->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000DDC->TIMEOUT_SIG -0000000000 AO-Subsc Obj=Philo_inst[0],Sig=00000004,Obj=0x20000DDC -0000000000 AO-Subsc Obj=Philo_inst[0],Sig=00000008,Obj=0x20000DDC -===RTC===> St-Init Obj=Philo_inst[0],State=0x08001099->Philo_thinking -0000000000 TE0-Arm Obj=Philo_inst[0].timeEvt,AO=Philo_inst[0],Tim=84,Int=0 -===RTC===> St-Entry Obj=Philo_inst[0],State=Philo_thinking -0000000000 Init===> Obj=Philo_inst[0],State=Philo_thinking - Sig-Dict 00000010,Obj=0x20000E10->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000E10->TIMEOUT_SIG -0000000000 AO-Subsc Obj=Philo_inst[1],Sig=00000004,Obj=0x20000E10 -0000000000 AO-Subsc Obj=Philo_inst[1],Sig=00000008,Obj=0x20000E10 -===RTC===> St-Init Obj=Philo_inst[1],State=0x08001099->Philo_thinking -0000000000 TE0-Arm Obj=Philo_inst[1].timeEvt,AO=Philo_inst[1],Tim=107,Int=0 -===RTC===> St-Entry Obj=Philo_inst[1],State=Philo_thinking -0000000000 Init===> Obj=Philo_inst[1],State=Philo_thinking - Sig-Dict 00000010,Obj=0x20000E44->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000E44->TIMEOUT_SIG -0000000000 AO-Subsc Obj=Philo_inst[2],Sig=00000004,Obj=0x20000E44 -0000000000 AO-Subsc Obj=Philo_inst[2],Sig=00000008,Obj=0x20000E44 -===RTC===> St-Init Obj=Philo_inst[2],State=0x08001099->Philo_thinking -0000000000 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=102,Int=0 -===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking -0000000000 Init===> Obj=Philo_inst[2],State=Philo_thinking - Sig-Dict 00000010,Obj=0x20000E78->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000E78->TIMEOUT_SIG -0000000000 AO-Subsc Obj=Philo_inst[3],Sig=00000004,Obj=0x20000E78 -0000000000 AO-Subsc Obj=Philo_inst[3],Sig=00000008,Obj=0x20000E78 -===RTC===> St-Init Obj=Philo_inst[3],State=0x08001099->Philo_thinking -0000000000 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=148,Int=0 -===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_thinking -0000000000 Init===> Obj=Philo_inst[3],State=Philo_thinking - Sig-Dict 00000010,Obj=0x20000EAC->HUNGRY_SIG - Sig-Dict 00000011,Obj=0x20000EAC->TIMEOUT_SIG -0000000000 AO-Subsc Obj=Philo_inst[4],Sig=00000004,Obj=0x20000EAC -0000000000 AO-Subsc Obj=Philo_inst[4],Sig=00000008,Obj=0x20000EAC -===RTC===> St-Init Obj=Philo_inst[4],State=0x08001099->Philo_thinking -0000000000 TE0-Arm Obj=Philo_inst[4].timeEvt,AO=Philo_inst[4],Tim=51,Int=0 -===RTC===> St-Entry Obj=Philo_inst[4],State=Philo_thinking -0000000000 Init===> Obj=Philo_inst[4],State=Philo_thinking - Obj-Dict 0x20000EE0->Table_inst - Sig-Dict 00000005,Obj=0x00000000->DONE_SIG - Sig-Dict 00000004,Obj=0x00000000->EAT_SIG - Sig-Dict 00000006,Obj=0x00000000->PAUSE_SIG - Sig-Dict 00000007,Obj=0x00000000->SERVE_SIG - Sig-Dict 00000008,Obj=0x00000000->TEST_SIG - Sig-Dict 00000010,Obj=0x20000EE0->HUNGRY_SIG -0000000000 AO-Subsc Obj=Table_inst,Sig=DONE_SIG -0000000000 AO-Subsc Obj=Table_inst,Sig=PAUSE_SIG -0000000000 AO-Subsc Obj=Table_inst,Sig=SERVE_SIG -0000000000 AO-Subsc Obj=Table_inst,Sig=TEST_SIG -0000000000 PHILO_STAT 0 thinking -0000000000 PHILO_STAT 1 thinking -0000000000 PHILO_STAT 2 thinking -0000000000 PHILO_STAT 3 thinking -0000000000 PHILO_STAT 4 thinking - Fun-Dict 0x08000BB5->Table_active - Fun-Dict 0x08000BDD->Table_serving - Fun-Dict 0x08000AD1->Table_paused -===RTC===> St-Init Obj=Table_inst,State=0x08001099->Table_serving -===RTC===> St-Entry Obj=Table_inst,State=Table_serving -0000000000 Init===> Obj=Table_inst,State=Table_serving - QF_RUN -@endverbatim -
- -Once QSPY acquires the dictionaries, it keeps them in the memory and applies them to display the data in symbolic form (rather than hex addresses). - -@note -The dictionaries do not need to be complete to be useful. QSPY simply applies the symbolic information whenever it can find a match in the dictionaries acquired so far. When a dictionary entry is not available, QSPY displays only hex addresses. - - -@section qspy_dict_save Saving Dictionaries to a File - -QSPY can save the dictionaries acquired thus far into a file. This is triggered by the #QS_QF_RUN trace record from the Target, but it can also be triggered by the user (by means of the `d` @ref qspy_keyboard "keyboard command" or from @ref qview_file "QView menu File->Save Dictionaries"), because QSPY does not "know" when the dictionaries are "complete", therefore it cannot know when to save them automatically. - -@note -For dictionaries to be saved to a file, the QSPY host application must be launched with the `-d` @ref qspy_command "command-line option", with of without the optional `[file]` parameter. - - -On the other hand, QSPY generates automatically the file name for saving dictionaries. This file name has always the form `qspy.dic`, where `` unambiguously identifies the Target build date and time. For example, the Target code last built on August 31, 2015 at 14:42:29 will have the name `qspy150831_144229.dic`. - -@attention -The internal addresses of objects can change by every code re-build, so dictionaries are applicable only to the specific Target build and must be freshly re-acquired after every new Target code build. - - -The dictionaries are saved to a file in ASCII format. The following listing shows the dictionaries from the DPP example application running on a STM32 NUCLEO board: - -
-@verbatim --v690 --T4 --O4 --F4 --S2 --E2 --Q1 --P2 --B2 --C2 --t200824_123230 - -Obj-Dic: -4 -0x08004009 l_SysTick_Handler -0x20000DDC Philo_inst[0] -0x20000E00 Philo_inst[0].timeEvt -0x20000E10 Philo_inst[1] -0x20000E34 Philo_inst[1].timeEvt -0x20000E44 Philo_inst[2] -0x20000E68 Philo_inst[2].timeEvt -0x20000E78 Philo_inst[3] -0x20000E9C Philo_inst[3].timeEvt -0x20000EAC Philo_inst[4] -0x20000ED0 Philo_inst[4].timeEvt -0x20000EE0 Table_inst -0x20000F94 EvtPool1 -0x20001048 QS_RX -*** -Fun-Dic: -4 -0x080006A9 Philo_initial -0x080007C5 Philo_eating -0x08000871 Philo_hungry -0x08000915 Philo_thinking -0x08000AD1 Table_paused -0x08000BB5 Table_active -0x08000BDD Table_serving -*** -Usr-Dic: -1 -0x00000064 PHILO_STAT -0x0000007C QUTEST_ON_POST -*** -Sig-Dic: -4 -00000004 0x00000000 EAT_SIG -00000005 0x00000000 DONE_SIG -00000006 0x00000000 PAUSE_SIG -00000007 0x00000000 SERVE_SIG -00000008 0x00000000 TEST_SIG -00000010 0x20000E44 HUNGRY_SIG -00000010 0x20000EAC HUNGRY_SIG -00000010 0x20000E78 HUNGRY_SIG -00000010 0x20000DDC HUNGRY_SIG -00000010 0x20000E10 HUNGRY_SIG -00000010 0x20000EE0 HUNGRY_SIG -00000011 0x20000E78 TIMEOUT_SIG -00000011 0x20000EAC TIMEOUT_SIG -00000011 0x20000E44 TIMEOUT_SIG -00000011 0x20000DDC TIMEOUT_SIG -00000011 0x20000E10 TIMEOUT_SIG -*** -@endverbatim -
- - -@section qspy_dict_use Using Dictionary File -The dictionary file saved in previous QSPY sessions can be used in two ways: - -- you can specify the dictionary file in the `-d ` @ref qspy_command "command-line option" to QSPY. In this case QSPY reads the dictionaries from the provided `` before processing any trace records from the Target. (**NOTE:** in this case you don't need to provide any of the upper-case command-line options, because they are read from the dictionary file.) For example: command line: `qspy -d qspy180117_155932.dic` will attempt to read the dictionaries from the specified file. - -- you can specify the dictionary option without the dictionary file `-d` @ref qspy_command "command-line option" to QSPY. Subsequently, once you run QSPY, you can query the Target information (by means of the `i` or `r` @ref qspy_keyboard "keyboard command" or from @ref qview_menu "QView menu Commands->Query Target Info"). When the Target replies and provides its build-time-stamp, QSPY looks for the corresponding dictionary file in the current directory and if such a file is found, QSPY reads the dictionaries from it. - - -@note -That last option requires that the Target implements the @ref qs_rx "QS receive channel, QS-RX" so that it can receive commands from QSPY. - -@next{qspy_udp} -*/ -/*##########################################################################*/ -/** -@page qspy_udp QSPY UDP Interface - -@tableofcontents - -

This section describes the structure of the UDP packets exchanged between the QSPY Back-End and the various front-ends, such as @ref qutest "QUTest" and @ref qview "QView" (blue arrows in the sequence diagram below). -

- -@image html qspy_comm.gif "Communication between Target, QSPY, and QView" -@n - - -@section udp_top General UDP Packet Structure - -@image html qspy_udp.gif "UDP packet structure" - -The UDP packets exchanged between the QSPY Back-End and the `QView` Front-End consists of: - -- 1-byte **Sequence-No**, which increments by 1 for every packet and wraps naturally from 0xFF to 0. The sequence number allows `QView` to detect any data discontinuities. - -- 1-byte **Record-ID**. The Record-IDs are divided into two categories: - - Records to and from the Target have Record-IDs in the range 0..127. Specifically, QS records originated from the Target are enumerated in ::QSpyRecords. Records destined to the Target are enumerated in ::QSpyRxRecords. - - Records to and from the QSPY Back-End have record-IDs in the range 128..255. Specifically, records destined to QSPY are enumerated in ::QSpyCommands. - -- optional **Data Payload**, which can be either text or binary, depending on the @ref udp_channel "UDP Channel" to which the front-end attaches. The various Data Payloads for different packets are described in the separate sections below. - - - -@subsection udp_channel UDP Data Channels -The QSPY UDP socket supports two "channels": -- **binary channel** (channel 1), in which the *Data Payload* is sent in binary, but after removing @ref qspy_transparent "escaping" and checksum; -- **text channel** (channel 2), in which the *Data Payload* is sent in the @ref qspy_text "QSPY Textual Format"; - -A Front-End can choose the "data channels" when "attaching" to the QSPY host application (see qspy::attach()). The data channels are not exclusive, meaning that a front-end can "attach" simultaneously to both binary and text channels. In this case, the front-end would receive each packet as both binary and text formats. - -@remark -The binary-channel (0x01) is used by the @ref qview "QView" GUI front-end, while the text-channel (0x02) is used by the @ref qutest "QUTest" Unit Testing front-end. - - -@section udp_Target Records to the Target - - -@subsection udp_INFO Query Target Info (INFO) -This packet has Record-ID==INFO and has no Data Payload. - -@note -To understand the following detailed UDP packet descriptions, it is highly recommended to read the Python documentation for the Python struct.pack() command.@n -@n -All data to and from the Target are sent according to the @ref qpspy_proto "QP/Spy™ Data Protocol" in **little endian**. - - -Code Example: -@code -::qspy::sendPkt [binary format c $::qspy::QS_RX(INFO)] -@endcode - - - -@subsection udp_COMMAND Execute a User-Defined Command in the Target (COMMAND) -This packet has Record-ID==COMMAND and Data Payload of the form: - -Data item | binary format | description ------------|-----------------------------|------------- -Command-ID | B (byte) | command number -Command-Par| I (unsigned 4-byte integer) | command parameter - - -@subsection udp_RESET Reset the Target (RESET) -This packet has Record-ID==RESET and has no Data Payload. - - -@subsection udp_TICK Call QF_TICK_X() in the Target (TICK) - -Data item | binary format | description ------------|---------------|------------- -Tick-rate | B (byte) | system tick rate number - - -@subsection udp_PEEK Peek Target Memory (PEEK) -This packet has Record-ID==PEEK and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -Peek-addr | Target-dependent@n Typically I | Address of the data in the Target -Peek-length| B (byte) | Number of bytes to peek - - -@subsection udp_POKE Poke Target Memory (POKE) -This packet has Record-ID==POKE and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -Poke-addr | Target-dependent@n Typically I | Address of the data in the Target -Poke-length| B (byte) | Number of bytes to poke (<= 8) -Poke-data | user-defined | Binary data to poke to the Target (8 bytes maximum) - -@note -The Poke-data part of the Data Payload must be formatted with the particular endianness of the Target and with any padding required for proper alignment of objects in the Target memory. - - -@subsection udp_GLB_FILTER Set Global Filters in the Target (GLB_FILTER) -This packet has Record-ID==GLB_FILTER and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -Data Len | B (byte) | Number of bytes sent (currently 16) -Filters | 16B | 8-bytes (128-bits), each bit corresponding to Global Filter - - -@subsection udp_LOC_FILTER Set Local Filters in the Target (LOC_FILTER) -This packet has Record-ID==LOC_FILTER and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -Local filter #| B (byte) | The Number of the Local Filter -Object-addr | Target-dependent@n Typically I | Address of the object in the Target - -The Local filters are numbered as follows: - -0. State Machine Local Filter (SM) -1. Active Object Local Filter (AO) -2. Memory Pool Local Filter (MP) -3. Event Queue Local Filter (EQ) -4. Time Event Local Filter (TE) -5. Application-Specific Local Filter (AP) - - -@subsection udp_AO_FILTER Set Local AO Filter in the Target (AO_FILTER) -This packet provides a shortcut for setting the Active Object Local Filter by providing just the unique priority of the AO. -The packet has Record-ID==AO_FILTER and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -AO prio | B (byte) | Priority of the AO to filter (0 to disable the AO filter) - - - -@subsection udp_EVENT Inject an Event to the Target (EVENT) -This packet has Record-ID==EVENT and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -AO prio | B (byte) | Priority of the recipient AO (0 to publish the event) -signal | Target-dependent@n Typically H | signal of the event -parameters | user-defined | Binary data corresponding to all event parameters - -The Event signal `sig` must be formatted according to the Target configuration (see Q_SIGNAL_SIZE) - -The Event **parameters** must be formatted with the particular **endianness** of the Target and with any padding required for proper alignment of objects in the Target memory. - -The parameters need to match exactly the event memory layout in your Target, including the endianness and any padding that the Target compiler might be using. (To test the right binary format and padding, you can use the @ref qview_events "Generate Event..." command). - -For example, let's assume that the parameters of your event are: a byte, followed by a 2-byte integer, followed by a 4-byte integer. Also, let's assume that your Target is little endian. From the @ref qview_events "Generate Event..." command you discover that to format this event correctly you need to use the following event parameters: - -Par # | format | data (example) -------|--------|------------- -par1: | B | 0x11 -par2: | B | 0x00 -par3: | H | 0x1122 -par4: | I | 0x11223344 - - -@section udp_QSPY Packets to the QSPY Back-End - - -@subsection udp_ATTACH Attach to the QSPY Back-End (ATTACH) -This packet has Record-ID==ATTACH and Data Payload of the form: - -Data item | binary format | description ------------|---------------|------------- -channels | B (byte) | Binary bitmask of @ref udp_channel "QSPY channels" to attach to - - -@subsection udp_DETACH Detach from the QSPY Back-End (DETACH) -This packet has Record-ID==DETACH and has no Data Payload. - - -@subsection udp_SAVE_DIC Save Dictionaries to a File in QSPY (SAVE_DIC) -This packet has Record-ID==SAVE_DIC and has no Data Payload. - - -@subsection udp_SCREEN_OUT Toggle Screen Output to a File in QSPY (SCREEN_OUT) -This packet has Record-ID==SCREEN_OUT and has no Data Payload. - - -@subsection udp_BIN_OUT Toggle Binary Output to a File in QSPY (BIN_OUT) -This packet has Record-ID==BIN_OUT and has no Data Payload. - - -@subsection udp_MATLAB_OUT Toggle MATLAB Output to a File in QSPY (MATLAB_OUT) -This packet has Record-ID==MATLAB_OUT and has no Data Payload. - - -@subsection udp_SEQUENCE_OUT Toggle Sequence Output to a File in QSPY (SEQUENCE_OUT) -This packet has Record-ID==SEQUENCE_OUT and has no Data Payload. - - - -@section udp_from Packets from the QSPY Back-End - - -@subsection udp_from_ATTACH Attach Response from the QSPY Back-End (ATTACH) -This packet has Record-ID==ATTACH and has no Data Payload. - - -@subsection udp_from_DETACH Detach Request from the QSPY Back-End (DETACH) -This packet has Record-ID==DETACH and has no Data Payload. - - -@next{qspy_seq} -*/ -/*###########################################################################*/ -/** -@page qspy_seq QSPY Sequence Output - -@tableofcontents -

The QSPY host application can also present the tracing data as a **sequence diagram**. To generate a Sequence file, you need to invoke QSPY with the `-g [obj-list]` @ref qspy_command "command-line option". -

- -The `[obj-list]` is a comma-separated list of objects shown in the sequence. The names in the list must correspond exactly to the @ref qs_dict "object dictionaries" produced by the Target. Examples of the valid `-g` options are shown below: - -- `-g -g l_SysTick_Handler,Table::inst,Philo::inst[0],Philo::inst[1]` -- `-g l_QF_onClockTick,TServer::inst` - -Additionally, the list could include `?` (questionmark), which denotes @ref qspy_seq_sys "System Border". - -- `-g -g Table::inst,Philo::inst[0],Philo::inst[1],?` -- `-g ?,l_QF_onClockTick,TServer::inst` - - -@note -The Sequence diagram can show only information actually sent from the Target. Therefore, by adjusting @ref qs_filters "QS filters" you can control the kind of information displayed in the sequence. - - -The following QS trace records produce the most interesting output: -- #QS_QF_ACTIVE_POST, -- #QS_QF_ACTIVE_POST_ATTEMPT, -- #QS_QF_ACTIVE_POST_LIFO, -- #QS_QF_PUBLISH, and -- #QS_QF_TICK. - - -Additional annotations of the sequence diagrams are also available if the following QS trace records are enabled: -- #QS_QEP_TRAN, -- #QS_QF_ACTIVE_DEFER, -- #QS_QF_ACTIVE_RECALL, and -- #QS_QF_ACTIVE_RECALL_ATTEMPT. - - - -@section qspy_seq_ref Sequence Elements -The main elements of the QSPY sequence diagram shown in the following sequence output are marked with the `[xx]` labels, which are explained below the listing. - -@note -The sequence output generated by QSPY is a **simple ASCII file**, which you can browse even with the most basic text editor, or a web browser. **No special tools are needed to view the sequence diagrams produced from your data**. - - -@verbatim -[1] -g ?,l_QF_onClockTick,TServer::inst - - +-------+-------+ +-------+-------+ +-------+-------+ -[2] | ? | |l_QF_onClockTic| | TServer::inst | - +-------+-------+ +-------+-------+ +-------+-------+ -[3] 3115372171 / | | -[4] 3127751904 *--NEW_REQUEST_SIG--+------------------>| -[5] 3127792184 / | - 3144424365 / *--RECEIVED_SIG---->| - 3144429488 / | - 3177742936 / *--AUTHORIZED_SIG-->| -[6] 3177796020 / | (RcallA) - 3177816231 / | - 3190753295 *--NEW_REQUEST_SIG--+------------------>| - 3190792988 / | - 3200126862 *--NEW_REQUEST_SIG--+------------------>| -[7] 3200127346 / | (Defer) - 3207429692 / *--RECEIVED_SIG---->| - 3207435638 / | - 3240835283 / *--AUTHORIZED_SIG-->| -[8] 3240884412 / | *<=NEW_REQUEST_SIG] - 3240884486 / | (RCall) - 3240902469 / | - . . . . . . . . . . . . . . -@endverbatim - -
-
1
The sequence diagram starts with repeating the `-g [obj-list]` option, so that you can conveniently copy-and-paste this option to run the same sequence again. -
-
2
Below that, you can see the header containing the boxes of participating objects from the `[obj-list]`. From each box descends a **lifeline** that runs vertically down the page and represents the ordering of exchanged events and other interesting occurrences involving a given object. -> **NOTE:** This first object in this particular sequence diagram, denoted as`?', is the @ref qspy_seq_sys explained below. - -> **NOTE:** The names in the sequence diagram are **truncated** to the first 15 characters. - -> **NOTE:** The sequence header is **repeated** every 100 lines of the sequence output. -
-
3
Each output line starts with the **timestamp** followed by the life-lines of all participating objects with event arrows or annotations. -
-
4
This line shows a **event posting** (with FIFO policy), which corresponds to the QS records #QS_QF_ACTIVE_POST and #QS_QF_ACTIVE_POST_ATTEMPT. The event **source** is marked with `*`, the event **target** is pointed to with `>` or `<`. The source and target are connected with a line `*----->`. The line is annotated with the **signal** of the posted event. -
-
5
This line shows a **state change**, which corresponds to the QS record #QS_QEP_TRAN. The lifeline of the object is annotated with new **state** assumed by the object. The state-name is placed between `<` or `>`. -
-
6
This line shows a **event recall**, which corresponds to the QS records #QS_QF_ACTIVE_RECALL, and #QS_QF_ACTIVE_RECALL_ATTEMPT. The lifeline of the object is annotated with `(Rcall)` or `(RcallA)`, respectively. -
-
7
This line shows a **event deferral**, which corresponds to the QS record #QS_QF_ACTIVE_DEFER. The lifeline of the object is annotated with `(Defer)`. -
-
8
This line shows a **event self-posting** with LIFO policy, which corresponds to the QS record #QS_QF_ACTIVE_POST_LIFO. The event **source/target** is marked with `*<`, the LIFO policy of the event posting is denoted by the `=` line right before the **signal** of the posted event. -
-
-
- - -@section qspy_seq_sys The System Border Object -As mentioned before, the `[obj-list]` that specifies objects participating in the sequence might include `?` (questionmark), which denotes @ref qspy_seq_sys "System Border". The system border is the "environment" that can produce and consume events. The "System Border" denotes possibly **multiple objects** that are not explicitly listed in the `[obj-list]`, including even objects without @ref qs_dict "object dictionaries". The sequence diagram in the previous section shows the "System Border", labeled as `?` and life-line shown as `//////`. - -@note -You can place the "System Border" (the `?`) anywhere in the `[obj-list]`. However, it is customary to place it either as the very first or the very last object in the list, as shown in the sequence diagram below: - - -The listing below shows a sequence output (`.seq`) generated from the Deferred Event example application with the following `-g` option: - -`-g ?,l_QF_onClockTick,TServer::inst` - - - -@section qspy_seq_exa More Involved Example -The listing below shows an example of a more involved sequence diagram output (`.seq`) generated from the Dining Philosophers Problem (DPP) application with the following `-g` option: - -`-g l_SysTick_Handler,Table::inst,Philo::inst[0],Philo::inst[1],Philo::inst[2],Philo::inst[3],Philo::inst[4]` - - -In addition to the elements described above, this sequence diagram illustrates the **event publishing**, which corresponds to the #QS_QF_PUBLISH trace record. The event multicasting is represented as a horizontal line `. . . .`, with the event **source** marked as `*`. - - -
-@verbatim --g l_SysTick_Handler,Table::inst,Philo::inst[0],Philo::inst[1],Philo::inst[2],Philo::inst[3],Philo::inst[4] - - +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ - |l_SysTick_Handl| | Table::inst | |Philo::inst[0] | |Philo::inst[1] | |Philo::inst[2] | |Philo::inst[3] | |Philo::inst[4] | - +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ -0000042339 . . . . * .SERVE_SIG. . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0000042896 *--SERVE_SIG------->| | | | | | -0001070723 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+-------------------+------------------>| -0001075362 | |<------------------+-------------------+-------------------+-------------------+-------HUNGRY_SIG--* -0001079065 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0001079975 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -0001080774 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -0001081583 | *--EAT_SIG----------+-------------------+------------------>| | | -0001082382 | *--EAT_SIG----------+------------------>| | | | -0001083181 | *--EAT_SIG--------->| | | | | -0001087412 | | | | | | -0001091293 | | | | | | -0001762885 *--TIMEOUT_SIG------+------------------>| | | | | -0001767416 | |<------HUNGRY_SIG--* | | | | -0001772368 | | | | | | -0002097460 . . . . * .PAUSE_SIG. . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0002098016 *--PAUSE_SIG------->| | | | | | -0002101049 | | | | | | -0002140275 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -0002144842 | |<------------------+-------------------+-------HUNGRY_SIG--* | | -0002149765 | | | | | | -0002245145 *--TIMEOUT_SIG------+-------------------+------------------>| | | | -0002249676 | |<------------------+-------HUNGRY_SIG--* | | | -0002254599 | | | | | | -0003104906 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+------------------>| | -0003109447 | |<------------------+-------------------+-------------------+-------HUNGRY_SIG--* | -0003114370 | | | | | | -0005013277 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+-------------------+------------------>| -0005016745 . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -0005017655 | |<------------------+-------------------+-------------------+-------------------+---------DONE_SIG--* -0005025076 | | | | | | -0007760487 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+-------------------+------------------>| -0007764998 | |<------------------+-------------------+-------------------+-------------------+-------HUNGRY_SIG--* -0007769921 | | | | | | -0011827861 . . . . * .SERVE_SIG. . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0011828417 *--SERVE_SIG------->| | | | | | -0011832381 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0011833291 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -0011834089 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -0011834887 | *--EAT_SIG----------+-------------------+------------------>| | | -0011835685 | *--EAT_SIG----------+------------------>| | | | -0011836483 | *--EAT_SIG--------->| | | | | -0011839510 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0011840421 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -0011841199 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -0011841977 | *--EAT_SIG----------+-------------------+------------------>| | | -0011842755 | *--EAT_SIG----------+------------------>| | | | -0011843533 | *--EAT_SIG--------->| | | | | -0011846001 | | | | | | -0011864225 | | | | | | -0011874191 | | | | | | -0015268086 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -0015271590 . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . . . . . . . | . . . -0015272500 | |<------------------+-------------------+---------DONE_SIG--* | | -0015276635 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0015277545 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -0015278343 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -0015279141 | *--EAT_SIG----------+-------------------+------------------>| | | -0015279939 | *--EAT_SIG----------+------------------>| | | | -0015280737 | *--EAT_SIG--------->| | | | | -0015289641 | | | | | | -0015294035 | | | | | | -0015540732 *--TIMEOUT_SIG------+------------------>| | | | | -0015544272 . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0015545182 | |<--------DONE_SIG--* | | | | -0015549317 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -0015550227 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -0015551025 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -0015551823 | *--EAT_SIG----------+-------------------+------------------>| | | -0015552621 | *--EAT_SIG----------+------------------>| | | | -0015553419 | *--EAT_SIG--------->| | | | | -0015567245 | | | | | | -0015571639 | | | | | | -@endverbatim -
- -@next{qspy_matlab} -*/ -/*###########################################################################*/ -/** -@page qspy_matlab QSPY MATLAB Support - -@tableofcontents - -

The QSPY host application can also export trace data to MATLAB®, which is a popular numerical computing environment and a high-level technical programming language. Created by The MathWorks, Inc., MATLAB allows easy manipulation and plotting of data represented as matrices. -

- -@note -The QSPY MATLAB interface is also compatible with the GNU Octave environment, which is an open source alternative to MATLAB and is compatible with the QSPY MATLAB interface described below. - -The following sections provide a reference manual for all 11 the MATLAB matrices generated by the @c qspy.m script. By MATLAB convention, the different variables are put into columns, allowing observations to vary down -through the rows. Therefore, a data set consisting of twenty four time samples of six variables is stored in a matrix of size 24-by-6. The pound sign '#' in a given cell of the matrix represents data available from the target. Other values, represent data added by the @c qspy.m script to allow unambiguous identification of the trace records. - -- @ref MATLAB_Q_STATE -- @ref MATLAB_Q_ACTIVE -- @ref MATLAB_Q_EQUEUE -- @ref MATLAB_Q_MPOOL -- @ref MATLAB_Q_NEW -- @ref MATLAB_Q_PUB -- @ref MATLAB_Q_TIME -- @ref MATLAB_Q_INT -- @ref MATLAB_Q_ISR -- @ref MATLAB_Q_MUTEX -- @ref MATLAB_Q_SCHED - - -@section MATLAB_Q_STATE Q_STATE Matrix -

The N-by-6 @c Q_STATE matrix stores all QS records generated by the QEP hierarchical event processor and pertaining to all the state machines in the system. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->123456
QS Record@n |@n VTime@n StampSignalState@n Machine@n ObjectSource@n StateNew@n State Event@n Hanlder
@c #QS_QEP_STATE_ENTRYNaN1#(2)#NaN1
@c #QS_QEP_STATE_EXITNaN2#(2)#NaN1
@c #QS_QEP_STATE_INITNaN3###1
@c #QS_QEP_INIT_TRAN#3#(2)NaN#1
@c #QS_QEP_INTERN_TRAN##(1)#(2)#NaN1
@c #QS_QEP_TRAN##(1)#(2)##1
@c #QS_QEP_IGNORED##(1)#(2)#NaN0
@c #QS_QEP_DISPATCH##(1)#(2)#NaN0
@c #QS_QEP_UNHANDLEDNaN#(1)#(2)#NaN0
-(1) The valid USER signal is > 3 - -(2) Per inheritance, an active object is a state machine object as well - - -The following criteria (index matrices in MATLAB) unambiguously select the QS -records from the @c Q_STATE matrix: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QEP_STATE_ENTRYQ_STATE(:,2) == 1
@c #QS_QEP_STATE_EXITQ_STATE(:,2) == 2
@c #QS_QEP_STATE_INITQ_STATE(:,2) == 3
@c #QS_QEP_INIT_TRANisnan(Q_STATE(:,4))
@c #QS_QEP_INTERN_TRANQ_STATE(:,2) > 3 & isnan(Q_STATE(:,5))
@c #QS_QEP_TRANQ_STATE(:,2) > > & ~isnan(Q_STATE(:,5))
@c #QS_QEP_IGNORED~Q_STATE(:,6)
- -For example, the following MATLAB plot shows the timing diagrams for all Philo state machines in the DPP example application made by the `philo_timing.m` script located in the directory `qtools/qspy/matlab` (see Section @ref qspy_files). The vertical axis represents states "thinking" (lowest), "hungry" (middle) and "eating" (top) states. - -@image html FigQSPY.01.jpg "Timing diagrams for all Philo state machines." - - -@section MATLAB_Q_ACTIVE Q_ACTIVE Matrix -

The N-by-5 @c Q_ACTIVE matrix stores QS records pertaining to adding/removing active objects and subscribing/unsubscribing to events from active objects. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->12345
QS Record@n |@n VTime@n StampSignalActive@n ObjectQF@n PriorityDelta
@c #QS_QF_ACTIVE_SUBSCRIBE###NaN+1
@c #QS_QF_ACTIVE_UNSUBSCRIBE###NaN-1
- -The following criteria (index matrices in MATLAB) unambiguously select the QS records from the @c Q_ACTIVE matrix: - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_ACTIVE_SUBSCRIBEisnan(Q_ACTIVE(:,4)) & Q_ACTIVE(:,5) > 0
@c #QS_QF_ACTIVE_UNSUBSCRIBEisnan(Q_ACTIVE(:,4)) & Q_ACTIVE(:,5) < 0
- - -@section MATLAB_Q_EQUEUE Q_EQUEUE Matrix -

The N-by-10 @c Q_EQUEUE matrix stores QS records pertaining to queuing events in the QF. Both the active object event queues and the "raw" thread-safe queues are included. The 'nUsed' field denotes the current number of used entries in the queue. The 'Maximum nUsed' filed denotes the maximum number of used entries since initialization (high watermark). Both fields contain the number of used entries in the queues ring-buffer plus one, to account for the extra location at the front of the queue. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->12345678910
QS Record@n |@n VTime@n StampSenderEvent@n Queue (1)nFreeMinimum@n UsedSignalPool IDRef.@n CountLIFODelta
@c #QS_QF_ACTIVE_POST########0+1
@c #QS_QF_ACTIVE_POST_LIFO########1+1
@c #QS_QF_ACTIVE_GET#NaN##NaN###0-1
@c #QS_QF_ACTIVE_GET_LAST#NaN#NaNNaN###0-1
@c #QS_QF_EQUEUE_POST#NaN####1#0+1
@c #QS_QF_EQUEUE_POST_LIFO#NaN######1+1
@c #QS_QF_EQUEUE_GET#NaN######0-1
@c #QS_QF_EQUEUE_GET_LAST#NaN#NaNNaN###0-1
-(1) This field (index 3) is actually the pointer to the ring buffer of the queue. - -The following criteria (index matrices in MATLAB) unambiguously select the QS records from the @c Q_EQUEUE matrix: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_ACTIVE_POSTQ_EQUEUE(:,3) == <active obj> & ~Q_EQUEUE(:,9) & Q_EQUEUE(:,10) > 0
@c #QS_QF_ACTIVE_POST_LIFOQ_EQUEUE(:,3) == <active obj> & Q_EQUEUE(:,9) & Q_EQUEUE(:,10) > 0
@c #QS_QF_ACTIVE_GETQ_EQUEUE(:,3) == <active obj> & ~isnan(Q_EQUEUE(:,4) & Q_EQUEUE(:,10) < 0
@c #QS_QF_ACTIVE_GET_LASTQ_EQUEUE(:,3) == <active obj> & isnan(Q_EQUEUE(:,4) & Q_EQUEUE(:,10) < 0
@c #QS_QF_EQUEUE_POSTQ_EQUEUE(:,3) == <raw queue> & ~Q_EQUEUE(:,9) & Q_EQUEUE(:,10) > 0
@c #QS_QF_EQUEUE_POST_LIFOQ_EQUEUE(:,3) == <raw queue> & Q_EQUEUE(:,9) & Q_EQUEUE(:,10) > 0
@c #QS_QF_EQUEUE_GETQ_EQUEUE(:,3) == <raw queue> & ~isnan(Q_EQUEUE(:,4) & Q_EQUEUE(:,10) < 0
@c #QS_QF_EQUEUE_GET_LASTQ_EQUEUE(:,3) == <raw queue> & isnan(Q_EQUEUE(:,4) & Q_EQUEUE(:,10) < 0
- - -@section MATLAB_Q_MPOOL Q_MPOOL Matrix -

The N-by-5 @c Q_MPOOL matrix stores QS records pertaining to memory pools in the QF. The 'nFree' field denotes the current number of free blocks in the event pool. The 'Minimum nFree' filed denotes the minimal number of free blocks since initialization (low watermark). The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->12345
QS Record@n |@n VTime@n StampPool@n ObjectnFreeMinimal@n nFreeDelta
@c #QS_QF_MPOOL_GET####-1
@c #QS_QF_MPOOL_PUT###NaN+1
- -The cumulative sum over the 'Delta' column should not have any long-time trends, because this would indicate a leak from the pool. The following picture shows the plot for the test data. - -@image html FigQSPY.02.jpg "Plot stairs(Q_MPOOL(:,1), cumsum(Q_MPOOL(:,5)))" - -The following criteria (index matrices in MATLAB) unambiguously select the QS -records from the @c Q_MPOOL matrix: - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_MPOOL_GETQ_MPOOL(:,5) < 0
@c #QS_QF_MPOOL_PUTQ_MPOOL(:,5) > 0
- - -@section MATLAB_Q_NEW Q_NEW Matrix -

The N-by-6 @c Q_NEW matrix stores QS records pertaining to dynamic event allocation and automatic event recycling (garbage collection) in the QF. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->123456
QS Record@n |@n VTime@n StampSignalPoolIDRef.@n CountEvent@n SizeDelta
@c #QS_QF_NEW##NaNNaN#+1
@c #QS_QF_GC_ATTEMPT####NaN0
@c #QS_QF_GC###NaNNaN-1
- -The cumulative sum over the 'Delta' column should not have any long-time trends, because this would indicate event leak. The following picture shows the plot for the test data. - -@image html FigQSPY.03.jpg "Plot stairs(Q_NEW(:,1), cumsum(Q_NEW(:,6)))" - -The following criteria (index matrices in MATLAB) unambiguously select the QS -records from the @c Q_NEW matrix: - - - - - - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_NEW%Q_NEW(:,6) > 0
@c #QS_QF_GC_ATTEMPT%Q_NEW(:,6) == 0
@c #QS_QF_GC%Q_NEW(:,6) < 0
- - -@section MATLAB_Q_PUB Q_PUB Matrix -

The N-by-7 @c Q_PUB matrix stores QS records pertaining to publishing events in QF. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->1234567
QS Record@n |@n VTime@n StampSenderSignalPoolIDRef.@n Count# Events@n MulticastDelta
@c #QS_QF_PUBLISH######
- -The following criteria (index matrices in MATLAB) unambiguously select the QS -records from the @c Q_PUB matrix: - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_PUBLISHQ_PUB(:,7) > 0
- - -@section MATLAB_Q_TIME Q_TIME Matrix -

The N-by-7 @c Q_TIME matrix stores QS records pertaining to time events in QF. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->1234567
QS Record@n |@n VTime@n StampQTimeEvt@n ObjectSignalQActive@n ObjectQTimeEvt@n CounterQTimeEvt@n IntervalQTimeEvt@n Delta
@c #QS_QF_TICKNaNNaNNaNNaN#(1)NaN0
@c #QS_QF_TIMEEVT_ARM##NaN###+1
@c #QS_QF_TIMEEVT_DISARM##NaN###-1
@c #QS_QF_TIMEEVT_AUTO_DISARMNaN#NaN#NaNNaN-1
@c #QS_QF_TIMEEVT_DISARM_ATTEMPT##NaN#NaNNaN0
@c #QS_QF_TIMEEVT_REARM##NaN####(2)
@c #QS_QF_TIMEEVT_POST####NaNNaN0
-(1) For #QS_QF_TICK record this matrix element contains the Tick Counter. - -(2) For #QS_QF_TIMEEVT_REARM event this matrix element is 0 if the time event was disarmed and rearmed again, and 1 if the time event was only armed. - -The cumulative sum over the 'Delta' column indicates the total number of armed time events at any given time. The following picture shows the plot for the test data: - -@image html FigQSPY.04.jpg "Plot stairs(Q_TIME(:,1), cumsum(Q_TIME(:,7)))" - -The following criteria (index matrices in MATLAB) unambiguously select the QS -records from the @c Q_TIME matrix: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_TICKisnan(Q_TIME(:,2))
@c #QS_QF_TIMEEVT_ARMQ_TIME(:,7) > 0
@c #QS_QF_TIMEEVT_DISARM~isnan(Q_TIME(:,1)) & Q_TIME(:,7) < 0
@c #QS_QF_TIMEEVT_AUTO_DISARMisnan(Q_TIME(:,1)) & Q_TIME(:,7) < 0
@c #QS_QF_TIMEEVT_DISARM_ATTEMPTisnan(Q_TIME(:,3)) & isnan(Q_TIME(:,5)) & Q_TIME(:,7) == 0
@c #QS_QF_TIMEEVT_REARMisnan(Q_TIME(:,3)) & ~isnan(Q_TIME(:,5))
@c #QS_QF_TIMEEVT_POST~isnan(Q_TIME(:,3)) & ~isnan(Q_TIME(:,4))
- - -@section MATLAB_Q_INT Q_INT Matrix -

The N-by-3 @c Q_INT matrix stores QS records pertaining to interrupt disabling and enabling. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->123
QS Record@n |@n VTime@n StampInterrupt@n NestingNesting@n Delta
@c #QS_QF_INT_DISABLE##+1
@c #QS_QF_INT_ENABLE##-1
- -The cumulative sum over the 'Delta' column indicates interrupt lock nesting -and should closely follow column 2. - -The following criteria (index matrices in MATLAB) unambiguously select the QS -records from the @c Q_INT matrix: - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_INT_DISABLEQ_INT(:,3) > 0
@c #QS_QF_INT_ENABLEQ_INT(:,3) < 0
- - -@section MATLAB_Q_ISR Q_ISR Matrix -

The N-by-4 @c Q_ISR matrix stores QS records pertaining to interrupt entry and exit. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->1234
QS Record@n |@n VTime@n StampInterrupt@n NestingISR@n PriorityNesting@n Delta
@c #QS_QF_ISR_ENTRY###+1
@c #QS_QF_ISR_EXIT###-1
- -The cumulative sum over the 'Delta' column indicates interrupt nesting level and should closely follow column 2. - -The following criteria (index matrices in MATLAB) unambiguously select the QS records from the @c Q_ISR matrix: - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_QF_ISR_ENTRYQ_ISR(:,4) > 0
@c #QS_QF_ISR_EXITQ_ISR(:,4) < 0
- - -@section MATLAB_Q_MUTEX Q_MUTEX Matrix -

The N-by-4 @c Q_MUTEX matrix stores QS records pertaining to the priority-ceiling mutex activity in QK. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->1234
QS Record@n |@n VTime@n StampOriginal@n PriorityPriority@n CeilingNesting@n Delta
@c #QS_MUTEX_LOCK###+1
@c #QS_MUTEX_UNLOCK###-1
- - -The cumulative sum over the 'Delta' column indicates QK scheduler lock nesting level. - -@image html FigQSPY.05.jpg "Plot stairs(Q_MUTEX(:,1), cumsum(Q_MUTEX(:,4)), 'r') (red)" - - -The following criteria (index matrices in MATLAB) unambiguously select the QS records from the @c Q_ISR matrix: - - - - - - - - - - - - - - - - -
QS RecordMATLAB Index Matrix
@c #QS_MUTEX_LOCKQ_MUTEX(:,4) > 0
@c #QS_MUTEX_UNLOCKQ_MUTEX(:,4) < 0
- - -@section MATLAB_Q_SCHED Q_SCHED Matrix -

The N-by-3 @c Q_SCHED matrix stores QS records pertaining to scheduling next task in QK. The following table summarizes how the QS records are stored in the matrix: -

- - - - - - - - - - - - - - - - - - - - - - -
 MATLAB index -->123
QS Record@n |@n VTime@n StampPreempted@n PriorityNew@n Priority
@c #QS_SCHED_NEXT###
- - -@next{qutest} -*/ diff --git a/doxygen/qutest.dox b/doxygen/qutest.dox deleted file mode 100644 index 4d0374b..0000000 --- a/doxygen/qutest.dox +++ /dev/null @@ -1,496 +0,0 @@ -/*! @page qutest QUTest™ Unit Testing Harness - -@image html qutest_banner.jpg - -@subpage qutest_tut " " -@subpage qutest_rtc " " -@subpage qutest_fixture " " -@subpage qutest_script " " - - -@section qutest_about About QUTest™ -

QUTest™ (pronounced "cutest") is a **unit testing harness** (a.k.a. *unit testing framework*), which is specifically designed for deeply embedded systems, but also supports unit testing of embedded code on host computers ("dual targeting"). QUTest™ is the fundamental tooling for Test-Driven Development (TDD) of QP/C/C++ applications, which is a highly recommended best-practice. -

- -@note -Even though QUTest™ has been primarily designed for testing of event-driven systems, it can also be used to test **any embedded C or C++ code**. To demonstrate this capability, the QUTest™ comes with a few examples from the conventional Unity testing framework, which among others demonstrate such techniques as using test doubles and mocks with QUTest™. - - - -@subsection qutest_how How it works? -In a nutshell, working with QUTest™ is similar to "debugging with printf" (or `sprintf` or similar), where you instrument the code to output information about its execution. You then run the code with a controlled set of inputs, and examine the produced output from the `printf`s to determine whether the code under test operates correctly. The main differences from using `printf`s are: (1) that the much more efficient @ref qpspy "QP/Spy" output mechanism is used instead and (2) that both generating the inputs and the checking of the test outputs are **automated**. - -The process of testing embedded code with QUTest™ involves the following components: - --# The **Target** that runs an instrumented @ref qutest_fixture "test fixture" code, whose job is to exercise your **CUT** (Code Under Test). Please note that a *test fixture* only exercises the CUT and reports the results to the host using @ref qpspy "QP/Spy", but the *test fixture* does **not** check if the CUT operates "correctly".@n -> NOTE: Several examples of *test fixtures* are explained in the @ref qutest_tut "QUTest Tutorial". The details of *test fixtures* are described in @ref qutest_fixture "QUTest Fixture Reference". - --# The @ref qspy "QSPY" "back-end" application that receives the tracing data from the Target and also opens a communication channel for the QUTest "front-end". - --# The **QUTest** "front-end" that executes @ref qutest_script "test scripts", which drive the tests and check the QSPY output against the expectations ("test-assertions").@n -> NOTE: Several examples of *test scripts* are explained in the @ref qutest_tut "QUTest Tutorial". The details of *test scripts* are described in @ref qutest_script "QUTest Script Reference". - - -@n -@image html qutest_targ.gif "Communication between Target, QSPY, and QUTest" - - -@remark -The separation between CUT execution and checking the test results has many benefits. One of the most important ones is that CUT execution (*test fixture*) and checking the results (*test script*) can be done in *different programming languages*. To this end QUTest™ provides support for writing the @ref qutest_script "test scripts in Python". -@n -@image html img/logo_python3.gif - - -The general QUTest™ structure just described corresponds to running tests on an embedded Target. But QUTest™ can also execute tests on the **host computer**. In that case (shown in the figure below), the **test fixture** is a host executable that communicates with the QSPY host application via a TCP/IP socket (QSPY started with the `-t` @ref qspy_command "command-line option"). In this case all QUTest™ components execute on the host computer. - - -@image html qutest_host.gif "QUTest with Host Executable" - - -@remark -To work effectively with QUTest™, you need to understand **how much output to expect from any given input**. Additionally, you need to understand how QUTest ensures that for every input to the *test fixture*, the generated QSPY output matches all test expectations and that there are no extra expectations or missing expectations after every command from the *test script*. These subjects are explained in the section @ref qutest_rtc "Run-to-Completion Processing". - - - -@subsection qutest_special What's Special about QUTest™? -Unlike other existing unit testing harnesses for embedded systems (e.g., Unity or CppUTest) QUTest™ is **not based on** xUnit that was originally designed to run tests on host computers. Instead, QUTest™ is geared towards unit testing of **deeply embedded systems**. Here is a list of QUTest™ unique features, specifically designed for this purpose: - -- QUTest™ separates the *execution* of the CUT (Code Under Test) from *checking* of the "test assertions". The embedded target is concerned only with running a @ref qutest_fixture "test fixture" that exercises the CUT and produces QP/Spy™ trace, but it does *not* check the "test assertions". Checking the "test assertions" against the expectations is performed on the host computer by means of @ref qutest_script "test scripts". - -- The QUTest™ approach is more **intuitive for embedded developers**, because it is conceptually like automated "debugging by printf" that most embedded developers use extensively. As it turns out, this approach also simplifies the development of all sorts of test doubles, including mocks, *without breaking encapsulation* of the CUT. - -- QUTest™ is a unique test harness on the embedded market that supports **scripting**. QUTest @ref qutest_script "test scripts" run on the Host, which skips compilation and uploading the code to the Target and thus shortens the TDD micro-cycle. - -> **NOTE:** QUTest™ supports *test scripts* written in [Python](https://www.python.org) (3.3+). - - -- QUTest™ supports **resetting the Target** for each individual test, if needed. This goes far beyond providing test `setup()` and `teardown()` functions that other test fixtures offer (and of course QUTest supports as well). Clean reset of the Target avoids erroneous tests that implicitly rely on side effects from previously executed code. This is particularly important for embedded systems and for state machines, so that each test can start from a known reset condition. - -- QUTest™ supports **testing Design by Contract** (assertions in C or C++, not to be confused with "test assertions") in the CUT. This is a carefully designed, unique feature of QUTest not available in other test harnesses. A successful test of DbC might actually mean breaking an assertion in the Target code. - -- QUTest™ @ref qutest_fixture "test fixtures" that run on the Target **do not require dynamic memory** allocation (`malloc()/free()` in C or `new/delete` in C++). This means that you don't need to commit any of your precious embedded RAM to the heap (you can set the heap size to zero) and you don't need to link the heap management code. Avoiding dynamic memory allocation is one of the best practices of real-time embedded programming, which you don't need to compromise to run QUTest. - -- QUTest™ @ref qutest_fixture "test fixtures" that run on the Target **do not require non-local jumps** (`setjmp()()/longjmp()` in C or `throw/catch` in C++), which are needed by other test harnesses to discontinue failing tests. QUTest™ *test fixtures* do not need to discontinue failing tests, because they don't check "testing assertions", so a *test fixture does* not "know" if it is failing or passing. Should a test fixture crash on the Target, it simply waits for the target reset commanded by a @ref qutest_script "test script". - -- QUTest™ @ref qutest_fixture "test fixtures" can be based on the actual **application code**. For example you can reuse the same `main()` function in a *test fixture* and in your final application. This means that you can either grow your *test fixture* into a final application through TDD, or you can more easily add unit tests to an existing application. - -@note -Even though QUTest™ is particularly suitable for running tests on deeply embedded targets, it also fully supports running *the same* tests on your **host computer** (Windows, Linux, and MacOS are supported). In fact, running the tests as much as possible on the host and thus avoiding the target-hardware bottleneck is the highly recommended best-practice of embedded TDD. QUTest™ supports **fully-automated** unit testing, both on the embedded target and on the host computer. - - -@section qutest_use Installation & Use -The qutest.py script can be used standalone, without any installation in your Python system (see @ref qutest_run below). - -@note -The qutest.py script is included in the @ref qtools_about "QTools™ collection". Also, the @ref qtools_win "QTools™ collection for Windows" already includes Python (3.8), so you don't need to install anything extra. - - -Alternatively, you can use *your own Python** installation, into which you can install the latest QUTest™ with `pip` from the [PyPi index](https://pypi.org/project/qutest/) by executing the following command: - -@verbatim -pip install qutest -@endverbatim - - -@subsection qutest_run Running QUTest™ -If you are using QUTest™ as a standalone Python script, you invoke it as follows: - -@verbatim -python3 /qutest.py [-x] [test-scripts] [host_exe] [qspy_host[:udp_port]] [qspy_tcp_port] -@endverbatim - -Alternatively, if you've installed QView™ with `pip`, you invoke it as follows: - -@verbatim -qutest [-x] [test-scripts] [host_exe] [qspy_host[:udp_port]] [qspy_tcp_port] -@endverbatim - - - -@subsection qutest_command Command-line Options - -- `-x` - optional flag that causes qutest to exit on first test failure. - -- `test_scripts` - optional specification of the Python test scripts to run. If not specified, qutest will try to run all *.py files in the current directory as test scripts - -- `host_exe | "" | DEBUG` - optional specification of the test-fixture compiled for the host (host executable) for testing on the host computer. The placeholder value `""` (empty string) can be used for running test fixtures on an embedded Target. The special value DEBUG means that qutest will run in the "debug mode", in which it will NOT launch the host executables and it will wait for the Target reset and other responses from the Target. If host_exe is not specified, an embedded target is assumed (which is loaded with the test fixture already). - -- `qspy_host[:udp_port]` - optional host-name/IP-address:port for the host running the QSPY host utility. If not specified, the default is 'localhost:7701'. - -- `tcp_port`- optional the QSpy TCP port number for connecting host executables. If not specified, the default is `6601`. - - -@note -The command-line options for `qutest.py` are **positional**, meaning that an option must be at the specific position in the command-line to be parsed correctly. For example, if you wish to run QUTest on an embedded target at the specified `[qspy_host]` host-name, you still need to provide a placeholder for the host executable `[host_exe]` ("") option, to get to the right position for the `[qspy_host]` option. - - - -@subsection qutest_exa Examples - - - -@verbatim -python3 %QTOOLS%\qutest\qutest.py -@endverbatim - -runs all the test scripts (`*.py`) in the current directory. - -@verbatim -python3 %QTOOLS%\qutest\qutest.py *.py -@endverbatim - -runs the test scripts (`*.py`) in the current directory. - -@verbatim -python3 %QTOOLS%\qutest\qutest.py *.py build\dpp.exe -@endverbatim - -runs the test scripts (`*.py`) in the current directory and uses the host executable: `build\dpp.exe` - -@verbatim -python3 %QTOOLS%\qutest\qutest.py *.py "" 192.168.1.100:7705 -@endverbatim - -runs the test scripts (`*.py`) in the current directory, without a host executable: (`""`), and connects to QSPY at `192.168.1.100:7705` - -@verbatim -qutest *.py build\dpp.exe 192.168.1.100:7705 -@endverbatim - -runs "qutest" (**installed with pip**) to execute the test scripts (`*.py`) in the current directory, uses the host executable: `build\dpp.exe`, and connects to QSPY at `192.168.1.100:7705` - -@verbatim -qutest *.py build\dpp.exe localhost:7701 6605 -@endverbatim - -runs "qutest" (**installed with pip**) to execute the test scripts (`*.py`) in the current directory, uses the host executable: `build\dpp.exe`, and connects to QSPY at `localhost:7701`, using the local UDP port `6605` - - - - -@verbatim -python3 $(QTOOLS)/qutest/qutest.py -@endverbatim - -runs all the test scripts (`*.py`) in the current directory. - -@verbatim -python3 $(QTOOLS)/qutest/utest.py *.py -@endverbatim - -runs the test scripts (`*.py`) in the current directory. - -@verbatim -python3 $(QTOOLS)/qutest/qutest.py *.py build/dpp -@endverbatim - -runs the test scripts (`*.py`) in the current directory and uses the host executable: `build/dpp` - -@verbatim -python3 $(QTOOLS)/qutest/utest.py *.py "" 192.168.1.100:7705 -@endverbatim - -runs the test scripts (`*.py`) in the current directory, without a host executable: (`""`), and connects to QSPY at `192.168.1.100:7705` - -@verbatim -qutest *.py build/dpp 192.168.1.100:7705 -@endverbatim - -runs "qutest" (**installed with pip**) to execute the test scripts (`*.py`) in the current directory, uses the host executable: `build/dpp`, and connects to QSPY at `192.168.1.100:7705` - -@verbatim -qutest *.py build/dpp localhost:7701 6605 -@endverbatim - -runs "qutest" (**installed with pip**) to execute the test scripts (`*.py`) in the current directory, uses the host executable: `build/dpp`, and connects to QSPY at `localhost:7701`, using the local UDP port `6605` - - -@next{qutest_tut} -*/ - -/*###########################################################################*/ -/*! @page qutest_rtc Run-to-Completion Processing - -@tableofcontents - -

The central concept applied in QUTest is **Run-to-Completion (RTC)** processing, both in the *test fixture* (Target) and in the *test script* (Host). RTC processing means that the code progresses in discrete, uninterruptible steps and that new inputs (commands) are recognized only *after* the current RTC step completes. -

- -@attention -RTC Processing is the key to understanding **how much output to expect from any given input** as well as **when a given input will be processed**. - - -Of course, it is not a coincidence that the RTC processing of QUTest matches exactly the RTC processing in event-driven systems of state machines. And the good news here is that for all interactions with state machines, the RTC output generated by a *test fixture* will correspond exactly to the RTC step in the state machine. - -However, a bit more tricky parts are the system reset, test initialization, and general processing of commands issued by *test scripts*. The following sections explain these parts by means of annotated sequence diagrams. - -@remark -For simplicity, the sequence diagrams in this section omit the QSPY intermediary from the communication between a *test fixture* (Target) and a *test script*. It is understood that every command from the *test script* goes to QSPY first and then is forwarded to the Target, and that every output from the Target goes through QSPY to reach the *test script*. - - - -@section qutest_reset Target Reset -Most individual tests in a *test script*, start with a clean **target reset**. The following sequence diagram shows the details of this process. The explanation section following the diagram clarifies the interesting points (labeled with `[xx]`). : - -![Target reset](qutest_reset.gif) - -
-
0
A *test script* executes the test() command. -
-
1
By default, each test starts with calling an internal function reset() to reset the Target. This reset() function sends the `QS_RX_RESET` request to the *test fixture*. After this, the *test script* enters a wait state in which it waits for `QS_TARGET_INFO` reply from the Target. -
-> **NOTE:** The Target reset can be suppressed by the `NORESET` option given in the test() command, which is illustrated in the @ref qutest_noreset "NORESET Tests" sequence diagram. Please note, however, that the first test in a *test script* (test group) and any test immediately following an "assertion-test" **must** cleanly reset the Target (so it cannot use the `NORESET` option). -
2
The *test fixture* processes the #QS_RX_RESET request immediately by calling the QS_onReset() callback inside the Target. -
-> **NOTE:** Embedded Targets reboot automatically after resetting. In case of a **host executable**, however, QUTest™ (qutest.py) launches it again.@n -
3
The Target starts executing the *test fixture* code from the beginning. After QS gets initialized (QS_INIT()), the *test fixture* sends the `QS_TARGET_INFO` reply to the *test script*. -
-
4
Upon reception of the awaited `QS_TARGET_INFO` reply, the *test script* attempts to execute the `on_reset()` procedure. If `on_reset()` is defined in the script, it runs at this time. (This scenario assumes that `on_reset()` is defined and runs until step [8]). -
-
5
A *test fixture* continues the initialization RTC step and typically produces some @ref qs_dict "QS dictionaries". -
-> **NOTE:** The @ref qs_dict "QS dictionaries" are consumed by QSPY and are **not** forwarded to the *test script*. -
6
The *test fixture* might also produce some output that **is** forwarded to the *test script*. -
-
7
Any such output needs to be explicitly expected by the *test script*. The `on_reset()` procedure is the ideal place to handle such output. -
-> **NOTE:** The main purpose of the `on_reset()` procedure is to consume any output generated during the reset RTC step as well as to perform any setup that should follow the Target reset. In principle, instead of coding `on_reset()`, you could place all this code directly at every test, but this would be repetitious and defining `on_reset()` allows you to avoid such repetitions. -
8
The `on_reset()` procedure ends and the *test script* sends `QS_RX_TEST_SETUP` to the Target. -
-
9
`QS_RX_TEST_SETUP` typically arrives while the *test fixture* still runs the initialization RTC. Therefore, `QS_RX_TEST_SETUP` is **not** processed immediately and its processing is delayed until the end of the current RTC step. -
-
10
A *test fixture* continues the initialization RTC step and might still produce some @ref qs_dict "QS dictionaries". -
-
11
Finally, the *test fixture* completes the initialization RTC by calling `QF_run()`. `QF_run()` runs an event loop, in which it processes commands that have accumulated from the *test script*. -
-
12
The first such command is `QS_RX_TEST_SETUP`, which has been waiting in the input buffer. -
-
13
The acknowledgement for the `QS_RX_TEST_SETUP` is sent back to the *test script* -
-
14
Upon reception of `Trg-Ack QS_RX_TEST_SETUP`, the *test script* attempts to execute the `on_setup()` procedure. If `on_setup()` is defined in the script, it runs at this time. -
-> **NOTE:** The main purpose of the `on_setup()` procedure is to consume any output generated from the `QS_onTestSetup()` callback in the *test fixture* invoked in the next step [15]. Note also the `QS_onTestSetup()` runs in all tests, including @ref qutest_noreset "NORESET tests". -
15
The *test fixture* calls the `QS_onTestSetup()` callback function in the Target. -
-
16
The *test script* proceeds with commands defined after the test() command. Processing of these commands is explained in sections @ref qutest_simple and @ref qutest_complex. -
-
-
- - - -@section qutest_pause Pausing the Reset -As explained in the previous section, the initialization RTC step in the *test fixture* extends throughout `main()`, from the beginning till the final call to `QF_run()`. The *test fixture* is unable to process any commands from the *test script* until the end of this long RTC step, which can limit the flexibility of the *test fixture*. - -For example, consider the *test fixture* in the DPP example for QUTest (directory `qpc/examples/qutest/dpp/test/`). This *test fixture* reuses the `main()` function from the actual DPP application, which starts multiple active objects. To enable unit testing of a specific single active objects, it would be very convenient if the *test script* could set up the @ref qs_local "QS Local Filter" for the chosen active object component. Such local filter would then select the output, such as initialization from a given AO. But the problem is that such local filter requires the @ref qs_dict "QS object dictionary" to be already transmitted to QSPY. On the other hand, the local filter needs to take effect before the AOs are started. In other words, the initialization RTC step needs to be split into shorter pieces, right after sending the dictionaries, but before starting active objects. - -For such situations, QUTest provides the QS_TEST_PAUSE() macro, which pauses the execution of an RTC step and enters an event loop within the *test fixture*. This, in turn, allows the *test fixture* to process any commands from the *test script*, before the RTC continues to completion (or to another QS_TEST_PAUSE(), if needed). - -The following *test fixture* code illustrates the use of the QS_TEST_PAUSE() macro: - -@code - int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - ~ ~ ~ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* NOTE: calls QS_INIT() */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - ~ ~ ~ - - /* pause execution of the test and wait for the test script to continue */ - [1] QS_TEST_PAUSE(); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - ~ ~ ~ - - [2] return QF_run(); /* run the QF application */ - } -@endcode - -
-
1
The QS_TEST_PAUSE() macro pauses the initialization RTC after producing QS dictionaries, but before starting active objects. -
-
2
The QF_run() function completes the initialization RTC. -
-
-
- -The following sequence diagram shows the details of pausing a test. The explanation section following the diagram clarifies the interesting points (labeled with `[xx]`). : - -![Pausing a test](qutest_pause.gif) - -
-
1
The target reset proceeds as before and produces the QS_TARGET_INFO trace record. -
-
2
At some point, however, the *test fixture* executes QS_TEST_PAUSE(), which sends QS_TEST_PAUSED record to the *test script*. At this point, the *test fixture* enters the event loop, so the initialization RTC finishes and the *test fixture* is now responsive to commands. -
-
3
At this point, the *test script* must be explicitily expecting QS_TEST_PAUSE by means of the expect_pause() command. -
-> **NOTE:** The best place to put expect_pause() is the on_reset() callback function, which should be defined in *test scripts* corresponding to *test fixtures* that call QS_TEST_PAUSE(). -
4
The on_reset() callack can now execute commands that are processed **immediately** in the *test fixture*. -
-
5
Eventually the on_reset() callback releases the *test fixture* from the pause by executing the continue_test() command. This command sends QS_RX_TEST_CONTINUE to the *test fixture*. -
-
6
Upon reception of QS_RX_TEST_CONTINUE, the *test fixture* continues the initialization in another RTC step. -
-
7
The on_reset() callback ends and the test script sends QS_RX_TEST_SETUP to the Target. -
-
8
The test proceeds as before. -
-
-
- -The following *test script* code illustrates the use of the expect_pause() and continue_test() commands: - -@code - def on_reset(): - [1] expect_pause() - [2] glb_filter(GRP_SM) - loc_filter(OBJ_SM_AO, "AO_Philo<2>") - [3] continue_test() - [4] expect("===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking") - expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking") - expect("@timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking") - glb_filter(GRP_SM_AO, GRP_UA) - current_obj(OBJ_SM_AO, "AO_Philo<2>") - } -@endcode - - - -@section qutest_noreset NORESET Tests -In some tests, you specifically don't want to reset the Target, but rather you want to pick up exactly where the previous test left off. For example, you wish to test a specific state of your state machine, which you reached by dispatching or posting a specific sequence of events to it in the previous tests. - -For such tests, you can suppress the target reset by following the test() command with the **NORESET** option. Such tests are called @ref qutest_noreset "NORESET Tests". - -@note -A "-norest Test" is not allowed as the first test of a *test group* and also not after an @ref qutest_assert. - - -The following sequence diagram shows the details of this process. The explanation section following the diagram clarifies the interesting points (labeled with `[xx]`). : - -![NORESET Test](qutest_noreset.gif) - -
-
0
The *test fixture* is done processing commands from any previous test(s) and is running an event loop. -
-
1
The *test script* executes the @ref test() "test(..., NORESET)" command. -
-
2
The @ref test() "test(..., NORESET)" command sends QS_RX_TEST_SETUP command to the *test fixture*. -
-
3
The *test fixture* processes QS_RX_TEST_SETUP immediately, because it is running event loop. -
-
4
The *test fixture* responds with Trg-Ack QS_RX_TEST_SETUP. -
-
5
Upon reception of Trg-Ack QS_RX_TEST_SETUP, the *test script* attempts to execute the on_setup() callback. If on_setup() is defined in the script, it runs at this time. -> **NOTE**: The main purpose of the on_setup() callback is to consume any output generated from the QS_onTestSetup() callback in the test fixture invoked in the next step [6]. -
-
6
The *test fixture* calls the QS_onTestSetup() callback function in the Target. -
-
7
The *test script* proceeds with commands defined after the test() command. Processing of these commands is explained in sections @ref qutest_simple and @ref qutest_complex. -
-
-
- - -@section qutest_assert Assertion Test - -The use of assertions in embedded code (and especially in safety-critical code) is considered one of the **best practices** and the QP frameworks provide assertion facilities specifically designed for deeply embedded systems. - -Assuming that you are using QP assertions in your code, an assertion failure can happen during a unit test. When it happens, the *test fixture* will produce the non-maskable QS_ASSERT_FAIL trace record. When this record arrives during a regular test, it will not be expected, so the test will fail. This is exactly what you want, because a failing assertion represents an error, which needs to be fixed. - -@note -The QP assertion handler Q_onAssert() is defined in the @ref qutest_stub "QUTest Stub". This assertion handler is instrumented to produce the QS_ASSERT_FAIL trace record. - - -However, sometimes you exactly want to test the assertion code itself, so you intentionally force an assertion in your test. In that case an assertion failure is expected and the test passes when assertion fails. Such tests are called "Assertion Tests" and QUTest™ has been specifically designed to support such tests. - -Here is an example of an "Assertion Test": - -@code -test("TIMEOUT->Philo_thinking (ASSERT)") -probe("QActive_post_", 1) -dispatch("TIMEOUT_SIG") -expect("@timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking") -expect("===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking") -expect("@timestamp TstProbe Fun=QActive_post_,Data=1") -expect("@timestamp =ASSERT= Mod=qf_actq,Loc=110") -@endcode - -As you can see, the test ends with an explicit expectation of an assertion failure: @ref expect() "expect('@timestamp =ASSERT= Mod=qf_actq,Loc=...')". This is very easy and natural in QUTest. - -@note -The only special treatment required here is that a test immediately following an such an "Assertion Test" must necessarily reset the Target (it cannot be a @ref qutest_noreset "NORESET-Test"). - - - -@section qutest_simple Simple Commands -Simple *test script* commands do not produce any output from the Target, except only the "Trg-Ack" (acknowledgement). Examples of `` include glb_filter(), loc_filter() and current_obj(), - -![Simple command processing](qutest_simple.gif) - -
-
1
A *test script* sends a `` to the *test fixture*. -
-
2
The *test fixture* receives the command and immediately starts processing it. -
-
3
Processing of a command triggers an RTC step and produces only the "Trg-Ack " (acknowledgement of the specific ``). -
-
4
Immediately after sending the ``, the *test script* enters an implicit expect state, in which it waits for the "Trg-Ack " output from the Target. The processing of the `` ends when the next output received from the Target matches exactly the expected output. -
-
-
- - -@section qutest_complex Complex Commands -Complex *test script* commands might produce some output from the Target, not just the "Trg-Ack" (acknowledgement). Examples of `` include dispatch(), post() and tick(), - -![Complex command processing](qutest_complex.gif) - -
-
1
A *test script* sends a `` to the *test fixture*. -
-
2
The *test fixture* receives the command and immediately starts processing it. -
-
3
Processing of a command triggers an RTC step and produces only the "Trg-Ack " (acknowledgement of the specific ``). -
-
4
The `` must be followed in the *test script* by the explicit expect() commands that concume any ouptu produced by the command. -
-
5-6
The *test fixture* produces some output. -
-
7
Each such ouput is consumed by the matching expect() command. -
-
8
The *test fixture* sends additional QS record "Trg-Done ", which explicitly delimits the output from this parricualr command. -
-
8
The *test script* must consume the "Trg-Done " record by an explicit expect() command. -
-
-
- - -@next{qutest_tut} -*/ - diff --git a/doxygen/qutest_ref.dox b/doxygen/qutest_ref.dox deleted file mode 100644 index ac1ea13..0000000 --- a/doxygen/qutest_ref.dox +++ /dev/null @@ -1,217 +0,0 @@ -/*###########################################################################*/ -/*! @page qutest_fixture QUTest™ Fixture Reference - -@tableofcontents - -

A QUTest *test fixture* is a regular C or C++ program that contains the @c %main() function as well as a few @ref qs "QS" callback functions (to implement test commands as well as test startup and teardown). The main job of a *test fixture* is to exercise the CUT (Code Under Test). -

- -The CUT called from a *test fixture* can be any code you wish to unit-test and does **not** need to be based on the [QP framework](https://www.state-machine.com/products/#QP). That way of applying QUTest is illustrated in the first lessons of the @ref qutest_tut "QUTest Tutorial". - -However, QUTest is particularly useful for testing QP applications, which is illustrated in the later lessons of the @ref qutest_tut "QUTest Tutorial". In this case, the *test fixture* needs to initialize all used QP services, such as event pools to dispatch/post events to your state machines and active objects. - - - -@section qutest_stub QUTest™ QP Stub -The QP API implementation linked with the *test fixture* is **not** the actual QP framework, but instead just a **QUTest QP Stub**, which differs from the real QP implementation in the following aspects: - -- the `QActive_start()` implementation initializes the event queue for the AO and registers it with the QP framework, but it does **not** start a new thread for the AO. -- the `QF_run()` implementation calls the `QS_onTestLoop()` to wait for the commands from the @ref qutest_script "test script" -- the stub provides `QActiveDummy` class for instantiating "dummy" active objects for testing - -@note -The **QUTest QP Stub** is implemented in the file qutest.c as well as Target-specific QUTest port `qutest_port.c`. - - - -@section qutest_fixture-callbacks QUTest™ Fixture Callbacks - -- QS_onTestSetup() -- QS_onTestTeardown() -- QS_onCommand() -- QS_onTestEvt() -- QS_onTestPost() -- QS_onFlush() -- QS_onTestLoop() - - - -@section qutest_fixture-pause Pausing Test Fixtures - -- QS_TEST_PAUSE() - - - -@section qutest_fixture-probe Test Probes -QUTest "Test Probes" are a very flexible mechanism to alter the behavior of code from the @ref qutest_script "test scripts". This alteration of behavior can be used for a variety of reasons: - -- to alter the flow of control to execute paths through the code otherwise hard to reach (to improve the test coverage of the code) -- to cause various error conditions -- to alter return values from functions -- many others - - -The "Test Probes" are just 32-bit values (`uint32_t`) sent from the test script to the Target (see the probe() command), where they are stored in the FIFO (First-In-First-Out) data structure. The "Test Probes" can be then retrieved from C or C++ code on the Target, by means of the following macros: - -- @ref QS_TEST_PROBE_DEF() "QS_TEST_PROBE_DEF( function_pointer )" -- @ref QS_TEST_PROBE() "QS_TEST_PROBE( code )" -- @ref QS_TEST_PROBE_ID() "QS_TEST_PROBE_ID( ID, code )" - -@note -The QUTest Test Probes macros can be used both in **production code** and in **test code** (intended for testing only). These macros are active only when #Q_UTEST is defined, and otherwise resolve to nothing, which means that you can **leave** the Test Probe macros in your production code. - -The typical use of the "Test Probe" macros is as follows: - -A C or C++ function calls the macro QS_TEST_PROBE_DEF(), which defines the test-probe variable `qs_tp_` of type `uint32_t`. If any test probes **for this function** have been sent from the test script, the test-probe is retrieved and assigned to the test-probe variable. Otherwise the test-probe variable is initialized to zero. - -Once the the test-probe variable is defined and initialized, it can be tested with the QS_TEST_PROBE() and QS_TEST_PROBE_ID() macros. The QS_TEST_PROBE() macro executes the code snippet specified as the parameter to the macro when the test probe is not zero. The QS_TEST_PROBE_ID() executes the specified code snippet only when the test-probe has a given ID value. - - -@next{qutest_script} -*/ - -/*###########################################################################*/ -/*! @page qutest_script QUTest™ Script Reference - -@tableofcontents - -

A QUTest *test script* contains a group of related tests (a *test group*). The basic job of these tests is to send commands to the @ref qutest_fixture "test fixture" running in the Target and to compare the @ref qspy_text "QSPY textual output" produced by the Target with the expectations of the tests. -

- -The QUTest *test scripts* are executed in the host by the "QUTest front-end" that communicates with the @ref qspy "QSPY" host application via the @ref qspy_udp "UDP interface". The "QUTest front-end" is itself implemented in [Python](https://www.python.org/) (Python 3.3+). - -![](logo_python3.gif) - - - -@section qutest_script-run Running the Test Scripts - -@note -To run any test script(s), you first need to make sure that the @ref qspy "QSPY" console application (version 6.x or higher) is running. Once QSPY is running, you can "attach" to the UDP socket and start communicating with the QSPY back-end or to the Target (through QSPY). - - -The Python test scripts are executed by the Python module qtools/qspy/py/qutest.py, with the following usage: - -@verbatim -python3 qutest.py [-x] [test-scripts] [host_exe] [qspy_host[:udp_port]] [qspy_tcp_port] -@endverbatim - -where:@n -`` is the directory with the `qutest.py` script@n - -@param [test_scripts] optional specification of the Python test scripts to run. - If not specified, qutest will try to run all *.py files - in the current directory as test scripts - -@param [host_exe] optional specification of the host executable to - launch for testing embedded code on the host computer. - If `host_exe` is **not** specified, or is specified as a - placeholder `""`, an embedded target is assumed. - The special value `DEBUG` means that `qutest.py` will start - in the **debug mode**, in which it will NOT launch the - host executables and it will wait for the Target reset - and other responses from the Target. - -@param [qspy_host[:udp_port]] optional host-name/IP-address:port for the host - running the QSpy utility. If not specified, the default - is localhost:7701. - -@param [tcp_port] optional the QSpy TCP port number for connecting - host executables. - -Usage examples (for Windows): - -@verbatim -python3 %QTOOLS%\qspy\py\qutest.py -python3 %QTOOLS%\qspy\py\qutest.py *.py -python3 %QTOOLS%\qspy\py\qutest.py *.py build\dpp.exe -python3 %QTOOLS%\qspy\py\qutest.py *.py build\dpp.exe 192.168.1.100:7705 -python3 %QTOOLS%\qspy\py\qutest.py *.py "" localhost:7701 6605 -python3 %QTOOLS%\qspy\py\qutest.py *.py DEBUG -python3 %QTOOLS%\qspy\py\qutest.py *.py DEBUG localhost:7701 6605 -@endverbatim - - -Usage examples (for Linux/MacOS): - -@verbatim -python3 $(QTOOLS)/qspy/py/qutest.py -python3 $(QTOOLS)/qspy/py/qutest.py *.py -python3 $(QTOOLS)/qspy/py/qutest.py *.py build/dpp -python3 $(QTOOLS)/qspy/py/qutest.py *.py build/dpp 192.168.1.100:7705 -python3 $(QTOOLS)/qspy/py/qutest.py *.py "" localhost:7701 6605 -python3 $(QTOOLS)/qspy/py/qutest.py *.py DEBUG -python3 $(QTOOLS)/qspy/py/qutest.py *.py DEBUG localhost:7701 6605 -@endverbatim - - - -@section qutest_dsl QUTest™ Testing DSL -The Python module qtools/qspy/py/qutest.py defines a small Domain Specific Language (DSL) for writing test scripts in Python. The structure of this DSL is very simple. Each test script consists of two sections: - - -@subsection qutest_dsl-preamble Preamble -The "preamble" section of a test script file specifies include scripts and defines callback functions common to all tests in this file. It can contain the following functions: - -- include() -- on_reset() -- on_setup() -- on_teardown() - -The `on_...()` callback functions can call any of the @ref qutest_dsl-commands "test commands". - - -@subsection qutest_dsl-tests Tests -The "tests" section of a test script file contains the actual tests. Each test starts with the test() command and can contain any number of the @ref qutest_dsl-commands "test commands". The test continues until another test() command, or the skip() command. - -- test() -- skip() - - -@subsection qutest_dsl-commands Commands -The commands that you can place in the tests (as well as inside the callback functions) are: - -- expect() -- glb_filter() -- loc_filter() -- ao_filter() -- current_obj() -- query_curr() -- tick() -- expect_pause() -- continue_test() -- command() -- init() -- dispatch() -- post() -- publish() -- probe() -- peek() -- poke() -- fill() -- pack() -- test_file() -- test_dir() -- last_rec() - - - -@section qutest_qspy Categories of QSPY Output -To write effective *test scripts* you need to understand the main categories of QSPY output, which are illustrated in the picture below: - -![Categories of QSPY output](qspy_cat.png) - -
-
0
Information output generated internally by QSPY. This output is *not* sent to *test scripts*. -
-
1
Dictionary trace records generated by the Target. This output is *not* forwarded to *test scripts*. -
-
2
Acknowledgement trace records generated by the Target. This output *is* forwarded to *test scripts*, but is checked automatically and implicitly by the *test commands*. -
-
3
Trace records generated by the Target. This output *is* forwarded to *test scripts* and must be checked **explicitly** by test expectations. -
-
-
- -@next{qview} -*/ diff --git a/doxygen/qutest_tut.dox b/doxygen/qutest_tut.dox deleted file mode 100644 index 2b3dff0..0000000 --- a/doxygen/qutest_tut.dox +++ /dev/null @@ -1,1386 +0,0 @@ -/*! @page qutest_tut QUTest™ Tutorial - -

This Tutorial describes how to use the QUTest™ unit test harness in a series of progressively advancing examples. The first couple of examples pertain to generic C code completely unrelated to the QP frameworks. These examples are adaptations of tests shipping with the Unity test framework. Later examples in this Tutorial show how to test hierarchical state machines and active objects. It is highly recommended to study the simpler examples before the more advanced ones, as the basic information won't be repeated in the later tests. -

- -As mentioned in the Section \"@ref qutest_how "How it works?"\", testing with QUTest™ always involves two components: (1) a @ref qutest_fixture "test fixture" code written in C (or C++) that runs on the target and (2) one or more @ref qutest_script "test scipts" that are written in Python and run on the host. This Tutorial starts each example with the description of how to run the tests and then explains the *test fixture* and the *test scripts* comprising the test. - -@note -This Tutorial should run on any host computer (Windows, Linux, or MacOS), where both QTools™ and [QP/C framework](/qpc) have been installed and also that the **QTOOLS** environment variable has been defined. Please refer to the @ref gs_obtain "QTools Installation" section for more information about downloading and installing QTools™. - - -This Tutorial consists of the following lessons: - -- @subpage qutest_unity -- @subpage qutest_mock -- @subpage qutest_qhsm -- @subpage qutest_blinky -- @subpage qutest_dpp - -@next{qutest_unity} -*/ - -/*###########################################################################*/ -/*! @page qutest_unity Basic Unity Example - -@tableofcontents - -

This example is based on the simple `example_1` that ships with the Unity unit testing framework. This simplest example of Unity has nothing to do with the QP frameworks. The purpose is to illustrate that QUTest™ can be used with generic C code and to compare QUTest™ with Unity. -

- -@remark -This simple example runs QUTest tests on the host (Windows, Linux, or MacOS) for both Unity and QUTest. The QUTest version also runs on embedded boards (TivaC LaunchPad from Texas Instruments and EFM32 Pearl-Gecko board from Silicon Labs). The instructions for building and running the code on the embedded boards are located at the end of this lesson. -@n -@image html platforms.png - - -@section qutest_unity-cut Code Under Test (CUT) - -@note -Because it uses pure C code, the Basic Unity example is only available in the [QP/C framework](https://www.state-machine.com/qpc) (and is **not** available in the [QP/C++ framework](https://www.state-machine.com/qpcpp)). - - -The CUT in this example is the file `ProductionCode.c` located in the directory `C:\qp\qpc\examples\qutest\unity_basic\src`. The CUT contains just two functions with some fairly obvious errors. The purpose of the example is to find these errors by unit-testing this "production code": - -@anchor qutest_tut_basic-cut -@includelineno ProductionCode.c - - - -@section qutest_unity-run0 Running the Test with Unity -The complete code for the basic Unity example is provided in the QP/C framework, directory `C:\qp\qpc\examples\qutest\unity_basic\test_unity`. To run the basic Unity test (on Windows), open a command-prompt and type: -@verbatim -cd C:\qp\qpc\examples\qutest\unity_basic\test_unity -make -@endverbatim - -@note -The provided `Makefile` will also work on Linux and MacOS. The only difference from Winows is that you open a terminal window and change directory to `~/qp/qpc/examples/qutest/unity_basic/test_unity`. - - -This will build the @ref qutest_unity-fixture "test fixture" as a host executable and then it will run it. The screen shot below shows the output produced from the make command. - -@image html unity_basic_unity.png "Unity example_1 test build and run with Unity" - - -@remark -As you can see, two out of five Unity tests **fail**. This is intentional, because the CUT is faulty. - - - -@section qutest_unity-run Running the Test with QUTest -The complete code for the basic Unity example is provided in the QP/C framework, directory `C:\qp\qpc\examples\qutest\unity_basic\test`. To run the basic test (on Windows), open a command prompt and type: - -@verbatim -qspy -@endverbatim - -This will start the @ref qspy "QSPY host utility" with the TCP/IP connection to the Target. - -Next, open a **second** command prompt window and type: - -@verbatim -cd C:\qp\qpc\examples\qutest\unity_basic\test -make -@endverbatim - -@note -The provided `Makefile` will also work on Linux and MacOS. The only difference from Windows is that you open a terminal window and change directory to `~/qp/qpc/examples/qutest/unity_basic/test`. - - -This will build the @ref qutest_unity-fixture "test fixture" as a host executable and then it will run the @ref qutest_unity-script "test script" (in Python). The screen shot below shows the output produced in these two command-prompt windows. - -@image html unity_basic_qutest.png "Unity example_1 test build and run with QUTest (left) and QSPY output (right)." - - -@remark -As you can see, two out of five QUTest tests **fail**. These are the same tests (adapted for QUTest) that failed during testing with Unity above. - - - -@section qutest_unity-fixture Test Fixture -The job of a @ref qutest_fixture "test fixture" is to exercise the CUT (`ProductionCode.c` in this case) and report the results back to the @ref qspy "QSPY host application". Note that a *test fixture* in QUTest™ is **not** supposed to perform any checks whether the CUT operates "correctly". Instead, your *test fixture* should only provide facilities to thoroughly exercise the **CUT** remotely from the @ref qutest_unity-script "test script"(s). A properly written test fixture can be typically used for many tests (implemented in multiple test scripts). - -@remark -Coming up with a "good" *test fixture* requires some practice, but when you study the examples in this Tutorial, you will see some instances of flexible *test fixtures* that allow you to to run a wide variety of tests on them. - - -The following listing shows the complete QUTest *test fixture* for the basic tests (file `test_ProductionCode.c` in the directory `C:\qp\qpc\examples\qutest\unity_basic\test`). The explanation section following the listing clarifies the interesting lines of code (lines starting with `[xx]` labels). - -@code - [1] #include "qpc.h" /* QUTest interface */ - [2] #include "ProductionCode.h" /* CUT interface */ - - [3] Q_DEFINE_THIS_FILE - - /*--------------------------------------------------------------------------*/ - // sometimes you may want to get at local data in a module. - // for example: If you plan to pass by reference, this could be useful - // however, it should often be avoided - [4] extern int Counter; - - /*--------------------------------------------------------------------------*/ - [5] int main(int argc, char *argv[]) { - - [6] QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - [7] Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* dictionaries... */ - [8] QS_FUN_DICTIONARY(&FindFunction_WhichIsBroken); - [9] QS_FUN_DICTIONARY(&FunctionWhichReturnsLocalVariable); -[10] QS_OBJ_DICTIONARY(&Counter); - - /* filter setup... */ -[11] QS_FILTER_ON(QS_ALL_RECORDS); - -[12] return QF_run(); /* run the tests */ - } - - /*--------------------------------------------------------------------------*/ -[13] void QS_onTestSetup(void) { - } - /*..........................................................................*/ -[14] void QS_onTestTeardown(void) { - } - - /*..........................................................................*/ -[15] void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) - { - switch (cmdId) { - case 0: { /* call the CUT: FindFunction_WhichIsBroken */ -[16] int ret = FindFunction_WhichIsBroken((int)param1); -[17] QS_BEGIN(QS_USER + cmdId, (void *)0) /* user-specific record */ -[18] QS_FUN(&FindFunction_WhichIsBroken); /* function called */ -[19] QS_I32(0, (int32_t)ret); /* returned value */ -[20] QS_I16(0, (int16_t)param1); /* parameter */ -[21] QS_END() - break; - } - case 1: { /* call the CUT: FunctionWhichReturnsLocalVariable */ -[22] int ret = FunctionWhichReturnsLocalVariable(); -[23] QS_BEGIN(QS_USER + cmdId, (void *)0) /* user-specific record */ -[24] QS_FUN(&FunctionWhichReturnsLocalVariable); /* function called */ -[25] QS_U32_HEX(0, (uint32_t)ret); /* returned value */ -[26] QS_END() - break; - } - default: - break; - } - - /* unused parametrers... */ - //(void)param1; - (void)param2; - (void)param3; - } - /*..........................................................................*/ - /* host callback function to "massage" the event, if necessary */ -[27] void QS_onTestEvt(QEvt *e) { - (void)e; - #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ - #else /* this test is compiled for an embedded Target system */ - #endif - } - /*..........................................................................*/ - /*! callback function to output the posted QP events (not used here) */ -[28] void QS_onTestPost(void const *sender, QActive *recipient, - QEvt const *e, bool status) - { - (void)sender; - (void)recipient; - (void)e; - (void)status; - } -@endcode - - -
-
1
The `"qpc.h"` header file contains the [QP/C framework](https://www.state-machine.com/qpc/) API, which includes the QUTest interface. Typically, you need to include this header file in QUTest test doubles. -> **NOTE:** for test fixtures based on the [QP/C++ framework](https://www.state-machine.com/qpcpp/), you need to include the `"qpcpp.h"` header file. -
-
2
You also need to include the interface to the CUT, which is `ProductionCode.h` in this case. -
-
3
The macro `Q_DEFINE_THIS_FILE` is needed for DbC assertions (they have nothing to do with test assertions). Later in this file, a DbC assertion is used to guard against failure in the initialization of the @ref qs "QS" target-resident component (see step [7]). -
-
4
The variable `Counter` is used to control the return value from the CUT (see @ref qutest_tut_basic-cut "ProductionCode.c" line 4). - > NOTE: this approach breaks encapsulation of the CUT, but it is copied here from the original Unity test. -
-
5
A QUTest *test fixture* code needs the `main()` function. This `main()` function can be in a separate file, but in this simple example it is placed in `test_ProductionCode.c`. Either way, the `main()` function has the usual structure of a QP/C application (and in fact in the more advanced tests it can be *the same* function as used by the actual QP/C application). But here, it contains the bare minimum function calls, as described below. -
-
6
The `main()` function must start with calling `QF_init()` to initialize the QP framework. -
-
7
Next, you need to initialize the @ref qs "QS" target-resident component (QS_INIT()). This macro is wrapped with the Q_ALLEGE() assertion, which will fire if the QS initialization fails. (In which case continuationon of the test makes no sense). -
-
8-10
Next, you produce @ref qs_dict "QS dictionaries" for all functions you wish to test as well as objects you might need to inspect. -> NOTE: you need to do this, so that the test scripts can refer to the functions and objects by the same symbolic names as the CUT/test-fixture. -
-
11
The QS_FILTER_ON() macro sets the @ref qs_global "global filter" in the Target. Here all output is enabled (::QS_ALL_RECORDS). -
-
12
Finally, at the end of `main()` you need to call `QF_run()` to run the tests. -
-
13
The callback function `QS_onTestSetup()` allows you to include code that will be run at the beginning of each test. Here this simple CUT does not need any setup, but you still need to provide (an empty) implementation to satisfy the linker. -
-
14
The callback function `QS_onTestTeardown()` allows you to include code that will be run at the end of each test. Here this simple CUT does not need any teardown, but you still need to provide (an empty) implementation to satisfy the linker. -
-
15
The callback function `QS_onCommand()` allows you to remotely execute commands inside the Target. Here is where you execute the CUT and report results back to QSPY. -
-
16
The command with `cmdId==0` will be used to call the `FindFunction_WhichIsBroken()` CUT. -> NOTE: You can use other `cmdId`s to call other pieces of CUT or to provide different variants of calling the same CUT, as you see fit. Much of the art of writing *test fixtures* lies in constructing flexible remote commands that exercise your CUT. -
-
17
The `QS_BEGIN()` macro starts the @ref qs_app "application-specific" trace record that will report results of calling the `FindFunction_WhichIsBroken()` CUT to the test script. -
-
18
The `QS_FUN()` macro sends the address of the function to the test script. This address will be converted to the name of the function, because the dictionary for this function has been generated in setp 8. -
-
19
The `QS_I32()` macro sends a 32-bit signed integer (`int32_t`) to the test script. Here you output the return value from `FindFunction_WhichIsBroken()`. -
-
20
The `QS_I16()` macro sends a 16-bit signed integer (`int16_t`) to the test script. Here you output the argument passed to `FindFunction_WhichIsBroken()`. -
-
21
The `QS_END()` macro ends the @ref qs_app "application-specific" trace record. -
-@n -
22
The command with `cmdId==1` will be used to call the `FunctionWhichReturnsLocalVariable()` CUT. -
-
23-26
Again, the @ref qs_app "application-specific" trace record gets generated that reports the function address and the return value from this function call. -
-@n -
27
The `QS_onTestEvt()` callback function is not used in this test, but needs to be provided to satisfy the linker. -
-
28
The `QS_onTestPost()` callback function is not used in this test, but needs to be provided to satisfy the linker. -
-
-
- - -@section qutest_unity-script Test Script -A **test script** contains a group of related tests (a "test group"). The basic job of these tests is to send inputs to the *test fixture* running in the Target and to compare the produced @ref qspy_text "QSPY textual output" with the expectations of the test. The following listing shows the *test script* (Python) for the Unity basic tests (file `test_ProductionCode.py`). The explanation section following the listing clarifies the interesting lines of code (lines starting with `[xx]` labels). - -@remark -Even though a *test script* uses Python under the hood, you don"t need to be a Python expert to write effective test scripts. The actual set of commands that you use and need to know about forms a small @ref qutest_script "Domain Specific Language (DSL) for unit testing", which just happens to be implemented with Python as a command interpreter. - - -@note -The following test script performs the same tests as the Unity test fixture `TestProductionCode.c` in the directory `qpc\examples\qutest\unity_basic\test_unity`. - - -@code{py} - [1] # QUTEST script corresponding to the test_ProductionCode.c test fixture. - # This test fixture corresponds to ../test_unity/TestProductionCode.c fixture. - # see https://www.state-machine.com/qtools/qutest.html - - # preamble... - [2] def on_setup(): - # This is run before EACH TEST - [3] current_obj(OBJ_AP, "Counter") - [4] poke(0, 4, pack(" -
1
Lines starting with a pound sign ('#') or empty lines are comments which are ignored by QUTest. -
- -
- - -"preamble" defines the startup code common to all tests in the group: -
-
2
The function on_setup() is executed at the beginning of each test in the group (see test()), including both tests that reset and do not reset the Target. -
-
3
The current_obj() command sets the "current object" of the application-specific kind (`OBJ_AP`) in the Target. Subsequent commands (such as poke() in the next step) will act on this "current object". -
-
4
The poke() command pokes the specified "Application Current Object" starting with the specified offset from the beginning of the object in memory (here 0) with the data elements of size 4 (the second argument) with the data provided in the third argument `pack()` "pack(" -
-
- - -Test: "FindFunction_WhichIsBroken() Should Return Zero..." checks that the CUT returns 0 when a given number is not found: -
-
5
The test() command starts a test and gives it a name (in double quotes). The name of test will be displayed as the test is executed and should be a quick reminder about the objective of this test. This test command also @ref qutest_reset "resets the Target", which brings the Target into a well-defined initial state and produces the @ref qs_dict "QS dictionary records" (see @ref qutest_unity-fixture "test-fixture"[12]) -> NOTE: The ability to perform the full Target reset is a unique feature of QUTest. Other unit testing frameworks, including Unity and CppUTest, don't reset the Target. They merely call the test `setup()/tearDown()` functions at the beginning and end of the test, respectively. QUTest also calls `onReset()/onSetup()/onTeardown()`, but obviously the full Target reset is a much better guarantee that the Target starts in exactly the same state. -
-
6
The command() command causes the invocation of the `QS_onCommand()` callback inside the Target. The argument 0 is the `cmdId` parameter (see @ref qutest_unity-fixture "test-fixture"[16]) -> **NOTE:** The first parameter of command() "command" here is just a number (0), but it is also possible to use a **symbolic name** for the first parameter. This symbolic name will be looked up in the user dictionary (QS_USR_DICTIONARY()) -
-
7
The expect() command represents an expectation of this test (a.k.a. test assertion). This is the expected output generated by the `command(0)` command from the previous step. You need to consult the test fixture to determine what you should expect in this case. -> NOTE: the expected string starts with a number `0000000001`, which is the @ref qs_tstamp "Target Time-Stamp". In QUTest, the "timestamp" simply counts all the QS trace records produced, so that you know that no entries have been lost. In the later tests you will see how you can count the steps automatically with the `@timestamp` placeholder. -
-
8
The test finishes with the expectation for the `Trg-Done QS_RX_COMMAND` trace record, which means that all output generated by command() has been generated. -
-
9
This expect() command illustrate the use of the `@timestamp` placeholder to account for the test steps automatically. -
-
10
This command() illustrates how to pass **negative numbers** as arguments. As you can see, you need to binary-and the number with the all-bits-on bitmask `0xFFFFFFFF`. -
-
-
- - -Test: "FindFunction_WhichIsBroken() Should Return The Index..." checks that the CUT fails to return the expected index, because of the internal bug: -
-
11
The test() command starts a next test. -
-
12
This `command(0, 34)` should cause the function `FindFunction_WhichIsBroken()` to return index `1`, because the number `34` is actually in the list. -
-
13
This expect() command codifies the expected result of the function call. - > NOTE: Due to the bug in the CUT, however, the expectation will fail, in which case the rest of the test is skipped until the **next** test() command. -
-
-
- - -Test: "FunctionWhichReturnsLocalVariable() Should Return The Current Counter Value": -
-
14
The test() command starts a next test. -
-
15
This `command(1)` runs the second function `FunctionWhichReturnsLocalVariable()` in the CUT. -
-
16
This poke() command changes the value of the `Counter` variable, because this is the "current AP object" established in the on_setup() callback in step [3]. -
-
-
- -@attention -The QSPY host application limits the @ref qs_dict "QS dictionaries" to the **first 63 characters**. This means that longer names of functions or objects will be **truncated** to this limit. Please keep this limit in mind when choosing various names in your application. - - -Test: "FunctionWhichReturnsLocalVariable() Should Return The Current Counter..." checks whether `FunctionWhichReturnsLocalVariable()` CUT returns the value poked into the `Counter` variable: -
-
17
The test() command starts a next test. -> NOTE: Unlike all previous tests so far, this test does **not** reset the Target (argument @ref qutest_reset "NORESET") -
-
-
- -@remark -As an exercise you should modify the file `ProductionCode.c` to fix the bug and make the tests pass. - - - -@section qutest_unity-embed Running the Test on Embedded Targets -As mentioned at the initial description of this example, the directory `C:\qp\qpc\examples\qutest\unity_basic\test` contains makefiles to build the code and run the tests on the embedded boards (TivaC LaunchPad from Texas Instruments and EFM32 Pearl-Gecko board from Silicon Labs). Both these boards open a virtual COM port on the machine they are attached to via the USB cable. This virtual COM port provides an ideal connection for the @ref qs "QS communication" with the @ref qspy "QSPY host utility". - -@image html platforms.png "Targets for running QUTests. From the left: host computer, TivaC LaunchPad and EFM32 Pearl-Gecko" - - -For example, to test the EFM32 Pearl-Gecko board (ARM Cortex-M4), open a command prompt (on Windows) and type: - -@verbatim -qspy -c COM6 -@endverbatim - - -This will start the QSPY host utility with com-port connection to the embedded board. Of course, you need to adjust the serial port number to the actual number of the virtual COM port on your machine. - -Next, open a **second** command prompt window and type: - -@verbatim -cd C:\qp\qpc\examples\qutest\unity_basic\test -make -f make_efm32 -@endverbatim - -The rest of the test is then exactly the same as with the host executable described @ref qutest_unity-run "above", except that the @ref qutest_unity-fixture "test fixture" runs on the embedded board. - -To run the tests on the TivaC LaunchPad (TM4C123 board), you use the `make_tm4c123` in the last step. - - -@next{qutest_mock} -*/ - -/*###########################################################################*/ -/*! @page qutest_mock Unity Mock Example - -@tableofcontents - -

This example is loosely based on Matt Chernosky's video blog post "Test-driving with mocks instead of hardware". In this video blog, Matt presents a technique called the mock object, which in the traditional unit testing approach is needed to verify complex, multi-stage interactions between the CUT and the collaborator impersonated by the mock object. -

- -@note -To better understand this QUTest example, it is highly recommended to watch the Chernosky's video blog. - - -The main purpose of this example is to show the traditional approach (with the mock object) and contrast it with the much simpler solution enabled by the QUTest approach. Of course, to make comparisons meaningfull, both approaches test the @ref qutest_mock-cut "same CUT". - -@note -Because of the different design philosophy of QUTest, which is *not* based on xUnit, the classic "mock object" is actually not needed and can be replaced with a simpler "spy" test double. To dynamically alter the behavior of this "spy" test double, this example applies @ref qutest_fixture-probe "QUTest Test Probes". Test Probes can be changed interactively from the @ref qutest_mock-script "test script". - - -@remark -Since the @ref qutest_mock-cut "CUT" is in C, the Mock Unity example is only available in the [QP/C framework](https://www.state-machine.com/qpc) (and is **not** available in the [QP/C++ framework](https://www.state-machine.com/qpcpp)).@n -@n -This example runs QUTest tests on the host (Windows, Linux, or MacOS) for both Unity and QUTest. The QUTest version also runs on embedded boards (TivaC LaunchPad from Texas Instruments and EFM32 Pearl-Gecko board from Silicon Labs). The instructions for building and running the code on the embedded boards are located at the end of this lesson. -@n -@image html platforms.png - - - -@section qutest_mock-cut Code Under Test (CUT) - -The CUT in this example implements a simple bar of 5 LEDs that display percentage, as shown in the animation below. The "LedBar device" interacts with the discrete LEDs by turning them on and off, to achieve the desired effect. The main objective of this example is to demonstrate how to verify the **collaboration** with the discrete LEDs, even without the actual hardware. - -@image html ledbar5.gif "Bar of 5 LEDs displaying the percentage." - - -The LedBar CUT is located in the file `LedBar.c` in the directory `qpc\examples\qutest\unity_mock\src`. The CUT consists of just one function `LedBar_setPercent()`, which turns the individual LEDs on and off such that they display the desired `percent` parameter. The function `LedBar_setPercent()` returns the total power consumption (in microwatts) of all LEDs that are turned on. - -@anchor qutest_tut_mock-cut -@includelineno LedBar.c -@caption{file LedBar.c} - - -The low-level interface to the LEDs is defined below (`Led.h`). The individual LEDs are selected by an `index` parameter. Each individual LED can be turned on by means of the `LED_on()` function. The `LED_on()` function returns a value, which corresponds to power consumption of this LED while on. The LED can be turned off by the `LED_off()` function, which returns `void`. - -@includelineno Led.h -@caption{file Led.c} - - -The diagram below shows the relationships between the CUT and the test code: Unity case on the left and QUTest case on the right. In both cases, the `LedBar` CUT interacts with the hardware through the `Led.h` interface. The explanation section below the diagram clarifies the interesting elements of the diagram. - -@image html qutest_mock.gif "Components of the Unity Mock test: Unity left and QUTest right" - - -Center: Code Under Test - -
-
1
The `LedBar.c` file contains the @ref qutest_mock-cut "Code Under Test (CUT)". -
-
2
The CUT interacts with the hardware through the `Led.h` interface. This interface abstracts the LEDs and is all that the CUT needs to "know" about the hardware. -
-
-
- - -@anchor qutest_mock-unity -Left: Unity testing framework (traditional approach) -
- -
3
The `TestLedBar.c` file implements the Unity test fixture, which calls the CUT and verifies that it performs as expected. - -> NOTE: A Unity test fixture for a mock requires a special "test runner", which initializes and cleans up after the mock. This "test runner" must typically be generated automatically, as it is too complex to code manually. -
-
4
-The Unity test fixture uses the `MockLed.c` implementation of the `Led.h` interface. The mock object implemented in `MockLed.c` needs to be "programmed" for each expected scenario **before** calling the CUT. Thus the structure of conventional tests with a mock is "backwards", meaning that you first specify the expectations and the test ends with a call to the CUT. - -> NOTE: This mock-object must typically be generated automatically, as it is too complex to code manually. Here, the mock- object was generated by means of the CMock tool. -
-
-
- - -Right: QUTest testing framework (simplified approach) -
-
5
-The `test_LedBar.c` file implements the @ref qutest_mock-fixture "QUTest test fixture", which calls the CUT, but it does **NOT** check whether it performs as expected. -
-
6
-The QUTest test fixture uses the `spy_Led.c` implementation of the `Led.h` interface. This spy test double is much simpler than mock-object used by Unity, so it can easily be @ref qutest_mock-spy "coded manually". -
-
7
-The QUTest test is driven by the `test_LedBar.py` @ref qutest_mock-script "test script". This test script sends commands to the `test_LedBar.c` fixture and verifies the generated output against the expectations of the test. -
-
-
- - -@section qutest_mock-run0 Running the Test with Unity -The complete code for the mock Unity example is provided in the QP/C framework, directory `C:\qp\qpc\examples\qutest\unity_mock\test_unity`. To run the mock Unity test (on Windows), open a command-prompt and type: -@verbatim -cd C:\qp\qpc\examples\qutest\unity_mock\test_unity -make -@endverbatim - -@note -The provided `Makefile` will also work on Linux and MacOS. The only difference from Winows is that you open a terminal window and change directory to `~/qp/qpc/examples/qutest/unity_mock/test_unity`. - - -This will build the @ref qutest_mock-fixture "test fixture" as a host executable and then it will run it. The screen shot below shows the output produced from the make command. - -@image html unity_mock_unity.png "Unity mock test build and run with Unity" - - - -@section qutest_mock-run Running the Test with QUTest -The complete code for the mock Unity example is provided in the QP/C framework, directory `C:\qp\qpc\examples\qutest\unity_mock\test`. To run the mock test (on Windows), open a command prompt and type: - -@verbatim -qspy -@endverbatim - -This will start the @ref qspy "QSPY host utility" with the TCP/IP connection to the Target. - -Next, open a **second** command prompt window and type: - -@verbatim -cd C:\qp\qpc\examples\qutest\unity_mock\test -make -@endverbatim - -@note -The provided `Makefile` will also work on Linux and MacOS. The only difference from Windows is that you open a terminal window and change directory to `~/qp/qpc/examples/qutest/unity_mock/test`. - - -This will build the @ref qutest_mock-fixture "test fixture" as a host executable and then it will run the @ref qutest_mock-script "test script" (in Python). The screen shot below shows the output produced in these two command-prompt windows. - -@image html unity_mock_qutest.png "Unity mock test build and run with QUTest (left) and QSPY output (right)." - - - -@section qutest_mock-spy Spy Object (Mock Replacement) -The following listing shows the "spy-object" (file `spy_Led.c`) test-double for the low-level LED module. The explanation section following the listing clarifies the interesting lines of code (lines starting with [xx] labels). - -@code - [1] #include "qpc.h" /* QUTest interface */ - [2] #include "Led.h" /* original interface */ - - //Q_DEFINE_THIS_FILE - - enum { - [3] LED_MOD = QS_USER1 /* QS app-specific record for the LED module */ - }; - - [4] static uint32_t led_power[MAX_LED] = { - 10, 20, 10, 20, 10 - }; - - /*--------------------------------------------------------------------------*/ - [5] void Led_DICTIONARY(void) { - QS_FUN_DICTIONARY(&Led_on); - QS_FUN_DICTIONARY(&Led_off); - QS_USR_DICTIONARY(LED_MOD); - QS_OBJ_DICTIONARY(&led_power); - } - - /*--------------------------------------------------------------------------*/ - /* turns a given LED off */ - [6] void Led_off(uint8_t index) { - QS_BEGIN(LED_MOD, (void *)0) /* user-specific record */ - QS_FUN(&Led_off); /* function called */ - QS_U8 (0, index); /* parameter */ - QS_END() - } - - /* turns a given LED on and retruns the power drawn by it in uW */ - [7] uint32_t Led_on(uint8_t index) { - [8] uint32_t ret = led_power[index]; /* assume default power */ - [9] QS_TEST_PROBE_DEF(&Led_on) - - /* tweak the returned power draw from the test probe */ -[10] QS_TEST_PROBE( -[11] ret = (uint32_t)qs_tp_; - ) - -[12] QS_BEGIN(LED_MOD, (void *)0) /* user-specific record */ - QS_FUN(&Led_on); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, index); /* parameter */ - QS_END() - -[13] return ret; - } -@endcode - -
-
1
The `"qpc.h"` header file includes the QP/C framework, which contains the QUTest interface. Typically, you need to include this header file in QUTest test doubles. -
-
2
The `"Led.h"` header file specifies the interface to the code being impersonated by this "spy-object". The whole purpose of the spy-object is to implement this interface such that the CUT can call use it as its collaborator. - -> NOTE: The CUT does not "know" that it is collaborating with a _test double_ (the spy-object in this case). -
3
This enumeration lists the @ref qs_app "application-specific QS trace records" that will be produced by the fake LED operations. The enumeration starts with #QS_USER1 offset, which is the second group of user-specific records. The first group (#QS_USER0 offset) is used by the main @ref qutest_mock-fixture "test fixture". -
-
4
The `led_power[]` array contains the default power ratings for the individual LEDs in the LED-bar. These values will be returned from the fake `Led_on()` implementation (if not overridden by the "Test Probe"). -
-
5
The `Led_DICTIONARY()` function produced the dictionaries for the spy-object. This function is not part of the real LED interface (see `Led.h` in the `src` directory), but is needed only for testing. -
-
6
This is a fake `Led_off()` implementation, which generates an @ref qs_app "application-specific QS trace record" to report the call and the parameter to QSPY. -
-
7
This is a fake `Led_on()` implementation. -
-
8
The `ret` variable will be the power rating for this LED returned from this function. The variable is initialized from the `led_power[]` array, which contains the default power rating for the LEDs. -
-
9
The macro `QS_TEST_PROBE_DEF()` defines a @ref qutest_fixture-probe "Test Probe" for this function (notice the @c &Led_on function-pointer parameter). This Test Probe retreives a value set for this function from the test-script. (If no value has been set, the `QS_TEST_PROBE_DEF()` retreives value 0). -
-
10
The `QS_TEST_PROBE()` macro executes the enclosed snipped of code only if the Test Probe (defined at label [9]) is not zero. -
-
11
If the Test Probe is not zero (it has been set from the test script), the `ret` value is updated from the value of the Test Probe `qs_tp_`. - -> NOTE: this demonstrates how to program a **return value** in a spy-object. This corresponds directly to the same capability of traditional mock-objects. - - -> NOTE: Test Probe is just one way in which a pre-programmed value can be returned from a fake function. This option is illustrated in @ref qutest_mock-script25 "test script [25]". Another way in QUTest is to use the poke() test command to alter the values in the `led_power[]` array. This option is illustrated in @ref qutest_mock-script21 "test script [21]" -
-
12
An @ref qs_app "application-specific QS trace record" is generated to report the call, the parameter, and the return value to QSPY. -
-
13
The `ret` value is returned to the caller (CUT). -
-
-
- - - -@section qutest_mock-fixture Test Fixture -The following listing shows the test fixture for the LedBar tests (file `test_LedBar.c`). The explanation section following the listing clarifies the interesting lines of code (lines starting with [xx] labels). - -@code - [1] #include "qpc.h" /* QUTest interface */ - [2] #include "LedBar.h" /* CUT interface */ - - Q_DEFINE_THIS_FILE - - /*--------------------------------------------------------------------------*/ - [3] void Led_DICTIONARY(void); /* dictionaries for the Led "spy " test double */ - - /*--------------------------------------------------------------------------*/ - int main(int argc, char *argv[]) { - - [4] QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - [5] Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* dictionaries... */ - [6] Led_DICTIONARY(); - [7] QS_FUN_DICTIONARY(&LedBar_setPercent); - - /* filter setup... */ - [8] QS_FILTER_ON(QS_ALL_RECORDS); - - [9] return QF_run(); /* run the tests */ - } - - /*--------------------------------------------------------------------------*/ - void QS_onTestSetup(void) { - } - /*..........................................................................*/ - void QS_onTestTeardown(void) { - } - - /*..........................................................................*/ - void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) - { - switch (cmdId) { -[10] case 0: { /* call the CUT: LedBar_setPercent */ -[11] uint32_t ret = LedBar_setPercent((uint8_t)param1); -[12] QS_BEGIN(QS_USER + cmdId, (void *)0) /* user-specific record */ -[13] QS_FUN(&LedBar_setPercent); /* function called */ -[14] QS_U32(0, ret); /* value returned */ -[15] QS_U8 (0, (uint8_t)param1); /* parameter */ - QS_END() - break; - } - default: - break; - } - - /* unused parametrers... */ - //(void)param1; - (void)param2; - (void)param3; - } - /*..........................................................................*/ - /* host callback function to "massage" the event, if necessary */ - void QS_onTestEvt(QEvt *e) { - (void)e; - #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ - #else /* this test is compiled for an embedded Target system */ - #endif - } - /*..........................................................................*/ - /*! callback function to output the posted QP events (not used here) */ - void QS_onTestPost(void const *sender, QActive *recipient, - QEvt const *e, bool status) - { - (void)sender; - (void)recipient; - (void)e; - (void)status; - } -@endcode - -
-
1
The `"qpc.h"` header file includes the [QP/C framework](https://www.state-machine.com/qpc/), which contains the QUTest interface. Typically, you need to include this header file in QUTest test doubles. -> **NOTE:** for test fixtures based on the [QP/C++ framework](https://www.state-machine.com/qpcpp/), you need to include the `"qpcpp.h"` header file. -
-
2
The `"LedBar.h"` header file specifies the interface to the CUT. -
-
3
The `Led_DICTIONARY()` function prototype is declared directly in the test fixture. This is the only extension from the `"Led.h"` interface implemented in the @ref qutest_mock-spy "spy-object". -
-
4
As usual the `main()` funciton of the test fixture initialzies the QF framework. -
-
5
As usual the `main()` funciton of the test fixture initalizes the QS software tracing. -
-
6
The call to the `Led_DICTIONARY()` funciton outputs the @ref qs_dict "QS dictionaries" for the @ref qutest_mock-spy "spy-object". -
-
7
The @ref qs_dict "QS dictionary" for the `LedBar_setPercentn()` CUT is produced as well. -
-
8
The @ref qs_global "QS global filter" is set up to output all QS records. -
-
9
The `QF_run()` funciton enters the event loop to wait for commands from the @ref qutest_mock-script "test script". -
-
-
- - - -@section qutest_mock-script Test Script -The following listing shows the *test script* for the LedBar tests (file `test_LedBar.py`). The explanation section following the listing clarifies the interesting lines of code (lines starting with `[xx]` labels). - -@note -The following test script performs the same tests as the `TestLedBar.c` Unity test fixture. Compared to the mock-object approach, however, the QUTest test script has the more intuitive structure in which a command triggering CUT is **followed** by the expecations. In contrast, the traditional @ref qutest_mock-unity "Unity tests with mock-object" were structured "backwards" (the expectations **preceeded** the call to CUT). - -@code{py} - [1] # preambe... - - # tests... - [2] test("LedBar 0% all off") - [3] command(0, 0) - [4] expect("@timestamp LED_MOD Led_off 0") - expect("@timestamp LED_MOD Led_off 1") - expect("@timestamp LED_MOD Led_off 2") - expect("@timestamp LED_MOD Led_off 3") - expect("@timestamp LED_MOD Led_off 4") - [5] expect("@timestamp USER+000 LedBar_setPercent 0 0") - [6] expect("@timestamp Trg-Done QS_RX_COMMAND") - - [7] test("LedBar 100% all on", NORESET) - [8] command(0, 100) - [9] expect("@timestamp LED_MOD Led_on 10 0") - expect("@timestamp LED_MOD Led_on 20 1") - expect("@timestamp LED_MOD Led_on 10 2") - expect("@timestamp LED_MOD Led_on 20 3") - expect("@timestamp LED_MOD Led_on 10 4") -[10] expect("@timestamp USER+000 LedBar_setPercent 70 100") -[11] expect("@timestamp Trg-Done QS_RX_COMMAND") - -[12] test("LedBar 19% all off", NORESET) -[13] command(0, 19) -[14] expect("@timestamp LED_MOD Led_off 0") - expect("@timestamp LED_MOD Led_off 1") - expect("@timestamp LED_MOD Led_off 2") - expect("@timestamp LED_MOD Led_off 3") - expect("@timestamp LED_MOD Led_off 4") -[15] expect("@timestamp USER+000 LedBar_setPercent 0 19") - expect("@timestamp Trg-Done QS_RX_COMMAND") - -[16] test("LedBar 20% one on", NORESET) -[17] command(0, 20) - expect("@timestamp LED_MOD Led_on 10 0") - expect("@timestamp LED_MOD Led_off 1") - expect("@timestamp LED_MOD Led_off 2") - expect("@timestamp LED_MOD Led_off 3") - expect("@timestamp LED_MOD Led_off 4") -[18] expect("@timestamp USER+000 LedBar_setPercent 10 20") - expect("@timestamp Trg-Done QS_RX_COMMAND") - -[19] test("LedBar 50% two on", NORESET) -[20] current_obj(OBJ_AP, "led_power") -[21] poke(0, 4, pack(" -
1
The preamble is empty, because no special actionas are needed on reset/setup/teardown. -
- -
- - -Test: "LedBar 0% all off" checks that that all LEDs are turned off to display 0% -
-
2
The test() command starts the test -
-
3
The @ref command() "command(0, 0)" calls the `LedBar_setPercent()` CUT with the 0 percent argument. -
-
4
This expect() command verifies the output produced by calling the `LED_off()` function from the spy-object. -
-
5
This expect() command verifies the output produced by calling the `LedBar_setPercent()` function from the CUT. Note that the returned total power consumption is zero. -
-
6
This expect() command verifies that all output from the origianl @ref command() "command(0, 0)" has been produced. -
-
-
- - -Test: "LedBar 100% all on" checks that that all LEDs are turned on to display 100% -
-
8
The test() command starts the test -
-
9
The @ref command() "command(0, 100)" calls the `LedBar_setPercent()` CUT with the 100 percent argument. -
-
10
This expect() command verifies the output produced by calling the `LedBar_setPercent()` function from the CUT. Note that the returned total power consumption is 70. -
-
11
This expect() command verifies that all output from the origianl @ref command() "command(0, 100)" has been produced. -
-
-
- - -Test: "LedBar 19% all off" checks that that all LEDs are turned off to display 19% -
-
12
The test() command starts the test (NOTE: this is a NORESET test) -
-
13
The @ref command() "command(0, 19)" calls the `LedBar_setPercent()` CUT with the 19 percent argument. -
-
14
This expect() command verifies the output produced by calling the `LED_off()` function from the spy-object. -
-
15
This expect() command verifies the output produced by calling the `LedBar_setPercent()` function from the CUT. Note that the returned total power consumption is 0. -
-
-
- - -Test: "LedBar 20% one on" checks that that all LEDs are turned off to display 20% -
-
16
The test() command starts the test (NOTE: this is a NORESET test) -
-
17
The @ref command() "command(0, 20)" calls the `LedBar_setPercent()` CUT with the 20 percent argument. -
-
18
This expect() command verifies the output produced by calling the `LedBar_setPercent()` function from the CUT. Note that the returned total power consumption is 10. -
-
-
- - -Test: "LedBar 50% two on" checks that that two LEDs is turned on to display 50% -
-
19
The test() command starts the test (NOTE: this is a NORESET test) -
-
20
The @ref current_obj() "current_obj(OBJ_AP, "led_power")" command sets the "current application object" to "led_power" (see @ref qutest_mock-spy "spy-object"[4]). -
-
21
-@anchor qutest_mock-script21 -
The @ref poke() "poke(0, 4, pack(" -
22
The @ref command() "command(0, 50)" calls the `LedBar_setPercent()` CUT with the 50 percent argument. -
-
23
This expect() command verifies the output produced by calling the `LedBar_setPercent()` function from the CUT. Note that the returned total power consumption is 40, which is due to poking the data into the `led_power` array. -
-
-
- - -Test: "LedBar 99% two on" checks that that two LEDs is turned on to display 99% -
-
24
The test() command starts the test (NOTE: this is a NORESET test) -
-
25
-@anchor qutest_mock-script25 -
The @ref probe() "probe("Led_on", 17)" command sends the @ref qutest_fixture-probe "test-probe" value 17 for function `Led_on` -
-
26
The @ref probe() "probe("Led_on", 13)" command sends another the @ref qutest_fixture-probe "test-probe" value 13 for function `Led_on` -
-
27
The @ref command() "command(0, 99)" calls the `LedBar_setPercent()` CUT with the 99 percent argument. -
-
28
This expect() command verifies the test-probe sent at step [25] has been retreived. -
-
29
This expect() command verifies the function `Led_on` has been called, and that it returned 17. -
-
30
This expect() command verifies the test-probe sent at step [26] has been retreived. -
-
31
This expect() command verifies the function `Led_on` has been called, and that it returned 13. -
-
32
This expect() command verifies the output produced by calling the `LedBar_setPercent()` function from the CUT. Note that the returned total power consumption is 60, which is due to using test-probes to alter the return values returned from `Led_on()`. -
-
-
- -@next{qutest_qhsm} -*/ - -/*###########################################################################*/ -/*! @page qutest_qhsm Hierarchical State Machine Example - -@tableofcontents -

This example shows how to apply QUTest for unit-testing [Hierarchical State Machines](https://www.state-machine.com/doc/concepts.php#HSM). This example illustrates two testing strategies for state machines: -

- -- **Functional tests** focus on the *actions* performed by the state machine. - -> NOTE: As described in the @ref qutest_mock, testing of complex, multi-stage interactions (such as a state machine) typically requires application of a "mock object" test double. However, the QUTest design philosophy allows you to use much simpler "spy object" test double instead. The **functional testing** strategy illustrates this approach. - -- **Structural tests** focus on the state machine structure, such as entering/exiting *states* and executing *state transitions*. - -> NOTE: Unlike the previous examples (@ref qutest_unity "Unity-basic" and @ref qutest_mock "Unity-mock"), which pertained to generic C code, the **structural testing** of state machine makes use of the specific state machine instrumentation that is provided in QP. - -@remark -In practice, unit-testing of state machines typically involves a mixture of functional and structural testing strategies. - - - -@section qutest_qhsm-cut Code Under Test (CUT) -This example is available in both [QP/C](https://www.state-machine.com/qpc) as well as in [QP/C++](https://www.state-machine.com/qpcpp) frameworks.The complete code for the `qhsm` example is provided in the directory `\examples\qutest\qhsmtst`. - -The hierarchical state machine used in this example is artificial, but it has been specifically designed to contain all possible state transition topologies for up to 4 levels of state nesting. The code representing this state machine (the CUT here), has been generated automatically by the [QM modeling tool](https://www.state-machine.com/qm/) from the model shown in the screen-shot below: - -@image html qhsmtst_qm.png "QHsmTst state machine in QM" - -The state machine executes actions on every entry/exit to states, on state transitions and on internal state transitions. These actions are all implemented by calling the `BSP_display()` function that outputs a succinct message about the location of the action within the state machine. For example, the entry action to state "s2" calls `BSP_display("s2-ENTRY;")` and the exit action from state "s2" calls `BSP_display("s2-EXIT;")`. These actions then are used for @ref qutest_qhsm-funct-script "functional testing" of the state machine. - - - -@section qutest_qhsm-run Running the Test -To run the `qhsm` tests (on Windows), open a command prompt and type: - -@verbatim -qspy -@endverbatim - -This will start the @ref qspy "QSPY" host application with the TCP/IP connection to the Target. - -Next, open another command prompt window and type: - -@verbatim -cd C:\qp\\examples\qutest\qhsmtst\test -make -@endverbatim - -This will build the @ref qutest_qhsm-fixture "test fixture" as a Windows executable and then it will run the @ref qutest_qhsm-funct-script "test script". The screen shot below shows the output produced in these two command-prompt windows. - -@image html test_qhsm.png "QUTest QHsm test run" - - - -@section qutest_qhsm-fixture Test Fixture -The following listing shows the test fixture for the QHsm tests (file `test_qhsm.c`). This test fixture is used in both @ref qutest_qhsm-funct-script "functional" and @ref qutest_qhsm-struct-script "structural" tests. The explanation section following the listing clarifies the interesting lines of code (lines starting with [xx] labels). - -@code - #include "qpc.h" /* QUTest interface */ - #include "qhsmtst.h" /* CUT */ - - Q_DEFINE_THIS_FILE - - enum { - [1] BSP_DISPLAY = QS_USER, - }; - - /*--------------------------------------------------------------------------*/ - int main(int argc, char *argv[]) { - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* dictionaries... */ - [2] QS_FUN_DICTIONARY(&QHsm_top); - [3] QS_OBJ_DICTIONARY(the_hsm); - [4] QS_USR_DICTIONARY(BSP_DISPLAY); - - [5] QHsmTst_ctor(); /* instantiate the QHsmTst object */ - - return QF_run(); - } - - /*--------------------------------------------------------------------------*/ - [6] void BSP_display(char const *msg) { - [7] QS_BEGIN(BSP_DISPLAY, (void *)0) /* application-specific record */ - [8] QS_STR(msg); - QS_END() - } - - /*..........................................................................*/ - void BSP_exit(void) { - } - - /*--------------------------------------------------------------------------*/ - void QS_onTestSetup(void) { - } - /*..........................................................................*/ - void QS_onTestTeardown(void) { - } - /*..........................................................................*/ - void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) - { - (void)param1; - (void)param2; - (void)param3; - - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } - } - - /*..........................................................................*/ - #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ - /*! host callback function to "massage" the event, if necessary */ - void QS_onTestEvt(QEvt *e) { - (void)e; - } - #else /* this test is compiled for an embedded Target system */ - void QS_onTestEvt(QEvt *e) { - (void)e; - } - #endif -@endcode -
-
1
The `BSP_DISPLAY` enumeration will be used as the record-ID for the @ref qs_app "application-specific trace record". -
-> **NOTE:** The record-ID is offset by #QS_USER. -
2
This line produces a @ref qs_dict "function dictionary" for the [QHsm_top() function](https://www.state-machine.com/qpc/qep_8h.html#ac8ae4728dfab5ce26a907fc624f6e104). -
-
3
This line produces a @ref qs_dict "object dictionary" for the `l_hsm` state machine object to test. -
-
4
This line produces a @ref qs_dict "user dictionary" for the application-specific trace record defined at label [1]. -
-
5
The "constructor" of the state machine object is called. -
-> **NOTE:** The explicit "constructor" call is needed only in C. In C++ static constructors are called automatically as part of the startup sequence. - -
-
- - -@subsection qutest_qhsm-act Action Functions Test Doubles -For functional testing, which is focused on the **actions** performed by a state machine, the actions must generate some QS output. This QS instrumentation can be added either directly to the state machine model, or indirectly to the functions called from the state machine actions. The test fixture above illustrates the second option, because it was more convenient in this case (see `BSP_display()` implementation starting at label [6] above). - -
-
6
The function `BSP_display()` is called from all actions of the state machine. Inside the test fixture, this function is defined to produce QS output. This is a classic example of a "spy" test double. -
-
7
The QS output is produced with an @ref qs_app "application-specific trace record" enumerated at label [1]. The second argument to the QS_BEGIN() macro is zero, which means that this record does not use any @ref qs_local "local filter". -
-
8
The QS_STR() data element outputs the message string. -
-
-
-@n - -@remark -In practice, you will likely use both functional and structural testing at the same time. Simple actions that do not perform any hardware-specific operations could be instrumented (with @ref qs_app "QS application-specific trace records") directly in the CUT (your state machines). The hardware-specific actions need to be abstracted anyway (in the BSP for "dual targeting"), in which case you can place the QS instrumentation in the BSP only. - - - -@section qutest_qhsm-funct-script Test Script (Functional Testing) -The following listing shows the *test script* for the QHsm tests (file `test_qhsm-funct.py`). The explanation section following the listing clarifies the interesting lines of code (lines starting with `[xx]` labels). - -@code - # preamble... - [1] def on_reset(): - [2] glb_filter(GRP_UA) - [3] current_obj(OBJ_SM, "the_hsm") - - # tests... - [4] test("QHsmTst init") - [5] init() - [6] expect("@timestamp BSP_DISPLAY top-INIT;") - expect("@timestamp BSP_DISPLAY s-ENTRY;") - expect("@timestamp BSP_DISPLAY s2-ENTRY;") - expect("@timestamp BSP_DISPLAY s2-INIT;") - expect("@timestamp BSP_DISPLAY s21-ENTRY;") - expect("@timestamp BSP_DISPLAY s211-ENTRY;") - expect("@timestamp Trg-Done QS_RX_EVENT") - - #------------------ - [7] test("QHsmTst dispatch", NORESET) - [8] dispatch("A_SIG") - [9] expect("@timestamp BSP_DISPLAY s21-A;") - expect("@timestamp BSP_DISPLAY s211-EXIT;") - expect("@timestamp BSP_DISPLAY s21-EXIT;") - expect("@timestamp BSP_DISPLAY s21-ENTRY;") - expect("@timestamp BSP_DISPLAY s21-INIT;") - expect("@timestamp BSP_DISPLAY s211-ENTRY;") -[10] expect("@timestamp Trg-Done QS_RX_EVENT") - - dispatch("B_SIG") - expect("@timestamp BSP_DISPLAY s21-B;") - expect("@timestamp BSP_DISPLAY s211-EXIT;") - expect("@timestamp BSP_DISPLAY s211-ENTRY;") - expect("@timestamp Trg-Done QS_RX_EVENT") - - ~ ~ ~ -@endcode - -
-
1
The script procedure `on_reset()` is executed after each reset of the target. This is in contrast to the procedure `on_setup()`, which is executed at the begin of all tests, including tests that don't reset the target. -
-
2
The @ref qs_global "global filter" is set to `GRP_UA`, which means «group-user-all» trace records. This filter setting determines the character of the test to be a **functional** test, because the focus is on the trace records produced by actions (@ref qs_app "user-defined" records) rather than the @ref qs_pre "pre-defined records" generated by executing a state machine. -
-
3
The command current_obj() sets the current state machine object to `"the_hsm"`. Because this is performed in the on_reset() callack, this current object will be set before every test (except the NORESET-tests, which do not call on_reset()). -
-
-
- - -Test: "QHsmTst init" tests the top-most initial transition -
-
4
The test() command starts the test. -
-
5
The init() command triggers the initial transition in the current state-machine object (see label [3]). -
-
6
The following expect() commands verify that all steps of the top-most initial transition are taken in the right order. -
-
-
- - -Test: "QHsmTst dispatch" tests dispatching various events to the state machine -
-
7
The test() command starts the test. -
-
8
The dispatch() command dispatches a given event to the state machine -
-
9
The expect() commands verify that the state machine **actions** (`BSP_display()` function) happened. -
-
10
This expect() command verifies that the processing of the event (see dispatch() at label [8]) has completed. -
-
-
- - - - -@section qutest_qhsm-struct-script Test Script (Structural Testing) -The following listing shows the *test script* for the QHsm tests (file `test_qhsm-struct.py`). The explanation section following the listing clarifies the interesting lines of code (lines starting with `[xx]` labels). - -@code - # preamble... - [1] def on_reset(): - [2] glb_filter(GRP_SM) - [3] current_obj(OBJ_SM, "the_hsm") - - - # tests... - [4] test("QHsmTst init") - [5] init() - [6] expect("===RTC===> St-Init Obj=the_hsm,State=QHsm_top->QHsmTst_s2") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") - expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - expect("@timestamp Init===> Obj=the_hsm,State=QHsmTst_s211") - expect("@timestamp Trg-Done QS_RX_EVENT") - - #------------------ - [7] test("QHsmTst dispatch", NORESET) - [8] dispatch("A_SIG") - [9] expect("@timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s211") - expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - expect("@timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s21->QHsmTst_s211") -[10] expect("@timestamp Trg-Done QS_RX_EVENT") - - dispatch("B_SIG") - expect("@timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s211") - expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - expect("@timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s21->QHsmTst_s211") - expect("@timestamp Trg-Done QS_RX_EVENT") - - ~ ~ ~ -@endcode - -
-
1
The script procedure `on_reset()` is executed after each reset of the target. This is in contrast to the procedure `on_setup()`, which is executed at the begin of all tests, including tests that don't reset the target. -
-
2
The @ref qs_global "global filter" is set to `GRP_SM`, which means «group-state-machine» trace records. This filter setting determines the character of the test to be a **structural** test, because the focus is on the @ref qs_pre "pre-defined records" generated by executing a state machine, rather than trace records produced by actions (user trace records). -
-
3
The command current_obj() sets the current state machine object to `"the_hsm"`. Because this is performed in the on_reset() callack, this current object will be set before every test (except the NORESET-tests, which do not call on_reset()). -
-
-
- - -Test: "QHsmTst init" tests the top-most initial transition -
-
4
The test() command starts the test. -
-
5
The init() command triggers the initial transition in the current state-machine object (see label [3]). -
-
6
The following expect() commands verify that all steps of the top-most initial transition are taken in the right order. -
-
-
- - -Test: "QHsmTst dispatch" tests dispatching various events to the state machine -
-
7
The test() command starts the test. -
-
8
The dispatch() command dispatches a given event to the state machine -
-
9
The expect() commands verify that the state machine RTC (Run-To-Completion) steps have been executed. -
-
10
This expect() command verifies that the processing of the event (see dispatch() at label [8]) has completed. -
-
-
- -@next{qutest_blinky} -*/ - -/*###########################################################################*/ -/*! @page qutest_blinky Blinky Example - -@tableofcontents - -

This example shows how to unit-test a simple active object (AO) called "Blinky". This Blinky AO turns on and off an LED, which is driven by a [QP time event](https://www.state-machine.com/qpc/qf_8h.html#struct_q_time_evt). -

- - - -@section qutest_blinky-cut Code Under Test (CUT) -This example is available in both [QP/C](https://www.state-machine.com/qpc) as well as in [QP/C++](https://www.state-machine.com/qpcpp) frameworks. The complete code for the Blinky example is provided in the directory `\examples\qutest\blinky\test`. - -@image html qutest_blinky_qm.png "Blinky model in QM." - - - -@section qutest_blinky-run Running the Test with QUTest -To run the `Blinky` test (on Windows), open a command prompt and type: - -@verbatim -qspy -@endverbatim - -This will start the @ref qspy "QSPY host utility" with the TCP/IP connection to the Target. - -Next, open a **second** command prompt window and type: - -@verbatim -cd C:\qp\\examples\qutest\blinky\test -make -@endverbatim - -@note -The provided `Makefile` will also work on Linux and MacOS. The only difference from Windows is that you open a terminal window and change directory to `~/qp//examples/qutest/blinky/test`. - - -This will build the @ref qutest_fixture "test fixture" as a host executable and then it will run the @ref qutest_script "test script" (in Python). The screen shot below shows the output produced in these two command-prompt windows. - -@image html test_blinky.png "Blinky test build and run with QUTest (left) and QSPY output (right)." - - - -@next{qutest_dpp} -*/ - -/*###########################################################################*/ -/*! @page qutest_dpp DPP Example - -@tableofcontents - -

The DPP (Dining Philosopher Problem) example shows how to use QUTest in various stages of application development, including not only unit testing, but also **integration testing** as well. -

- - - -@section qutest_dpp-cut Code Under Test (CUT) -This example is available in both [QP/C](https://www.state-machine.com/qpc) as well as in [QP/C++](https://www.state-machine.com/qpcpp) frameworks. The complete code for the DPP example is provided in the directory `\examples\qutest\dpp\test`. - - - -@section qutest_dpp-run Running the Test with QUTest -To run the DPP test (on Windows), open a command prompt and type: - -@verbatim -qspy -@endverbatim - -This will start the @ref qspy "QSPY host utility" with the TCP/IP connection to the Target. - -Next, open a **second** command prompt window and type: - -@verbatim -cd C:\qp\\examples\qutest\dpp\test_philo -make -@endverbatim - -@note -The provided `Makefile` will also work on Linux and MacOS. The only difference from Windows is that you open a terminal window and change directory to `~/qp//examples/qutest/blinky/test`. - - -This will build the @ref qutest_fixture "test fixture" as a host executable and then it will run the @ref qutest_script "test script" (in Python). The screen shot below shows the output produced in these two command-prompt windows. - -@image html test_dpp.png "DPP test build and run with QUTest (left) and QSPY output (right)." - - -@next{qutest_rtc} -*/ - diff --git a/doxygen/qview.dox b/doxygen/qview.dox deleted file mode 100644 index bd6c4b9..0000000 --- a/doxygen/qview.dox +++ /dev/null @@ -1,718 +0,0 @@ -/*! @page qview QView™ Visualization & Monitoring - -![](qview_banner.jpg) - -@subpage qview_ui " " -@subpage qview_cust " " - - -@section qview_about About QView™ - -@htmlonly - -@endhtmlonly - -

QView™ is a powerful **Visualization and Monitoring** facility, which allows embedded developers to rapidly create **remote graphical user-interfaces** to monitor and control their embedded devices from a host (desktop) computer. The interfaces created by QView™ can visualize the tracing data produced by @ref qpspy "QP/Spy" and can also **interact with the target** by sending commands and injecting events to the embedded target. -

- -As you can see in the screen shots below, a QView™ user interface consists of the text box with extensible menus plus a **customizable canvas** that can serve as a remote graphical user-interface to your embedded device. The canvas can contain various "widgets", such as buttons, sliders, guages, graphs, animations etc. The actual functionality of the _virtual GUI_ obviously depends on the target system and the embedded code it is running. Therefore, the QView™ provides only a skeleton, which is then @ref qview_cust "customized" by user-supplied scripts written in Python (version 3). - -
- -@image html qview_ex.gif "Example of a QView™ session on an embedded board (Windows host)" - -@n -@image html qview_dpp-fedora.gif "Example of a QView™ session (Linux host)" - - -@subsection qview_special What's Special About It? - -QView™ has been specifically designed for extensibility, so that you can quickly @ref qview_cust "customize its GUI and behavior" to your specific embedded project, so that you can use QView™ as a powerful custom Human-Machine Interface (HMI) for your projects. The cusomization is accomplished in Python (version 3), which means that it is naturally platform-neutral and runs without any changes on Windows, Linux, or macOS. - -Out of the box, QView™ supports the following @ref qview_ui "commands" (NOTE: This basic functionality can be extended in the @ref qview_cust "QView™ customization"): - -- Set @ref qs_global "global QS filters" inside the Target -- Set @ref qs_local "local QS filters" inside the Target -- Inject an arbitrary event to the Target (direct post or publish) -- Execute a user-defined command function inside the Target with arguments supplied from QView™ -- Peek data inside the Target and send to QView™ -- Poke data (supplied from QView™) into the Target -- Execute clock tick inside the Target -- Remotely reset the Target - -@note -A visualization and monitoring system like QView™ can be used in all stages of development, manufacturing, and after the deployment, for in-field servicing of embedded devices. - - - -@section qview_struct QView™ Structure -The sequence diagram below shows the general structure of QView™. The embedded Target is running an instrumented code that communicates with the @ref qspy "QSPY Host application" over the @ref qspy_link "Target data link" (red arrows). This communication is based on the @ref qpspy_proto "QP/Spy Protocol". - -@attention -The Target must be running the "Spy" build configuration, in which the @ref qpspy is enabled. Additionally, the QP/Spy implementation in the Target must support the @ref qpspy_rx "bi-directional" communication with @ref qspy "QSPY". - - -The QView™ (Python script) attaches to the QSPY host application by means of the @ref qspy_udp "UDP socket" that QSPY opens specifically for attaching various "front-ends". This communication (blue arrows) uses the same packet structure as the @ref qpspy_proto "QP/Spy Protocol", but without the HDLC framing, without transparency (escaping), and without the checksum. - - -@image html qspy_qview.gif "Communication between Target, QSPY, and QView" - -
-
A
A Target produces QS trace records, which the @ref qspy "QSPY Back-End" forwards to the @ref qpspy_udp "UDP Socket", so that any attached Front-End (such as QView™) receives all this data. -
- -
B
The Front-End (QView™) sends commands as @ref qpspy_udp "UDP packets to QSPY". For some of those packets, the @ref qspy "QSPY Back-End" supplies additional information (e.g., translation between symbolic names and binary addresses according to the @ref qs_dict "QS dictionaries" collected from the Target). -
- -
C
The @ref qspy "QSPY Back-End" then forwards the modified packets to the Target. -
-
-
- -@remark -Why UDP? The @ref qspy_udp "communication between QSPY and QView" is based on UDP, because UDP is inherently packet-oriented (as opposed to TCP, which is stream-oriented) and preserves the packet boundaries. - - - -@section qview_use Installation & Use -The qview.py script can be used standalone, without any installation in your Python system (see @ref qview_run below). - -@note -The qview.py script is included in the @ref qtools_about "QTools™ collection". Also, the @ref qtools_win "QTools™ collection for Windows" already includes Python (3.8), so you don't need to install anything extra. - - -Alternatively, you can use *your own Python** installation, into which you can install the latest QView™ with `pip` from the [PyPi index](https://pypi.org/project/qview/) by executing the following command: - -@verbatim -pip install qview -@endverbatim - - -@subsection qview_run Running QView™ -If you are using QView™ as a standalone Python script, you invoke it as follows: - -@verbatim -python3 /qview.py [ [ []]] -@endverbatim - -Alternatively, if you've installed QView™ with `pip`, you invoke it as follows: - -@verbatim -qview [cust_script] [qspy_host[:udp_port]] [local_port] -@endverbatim - - - -@subsection qview_command Command-line Options - -- `cust_script` - optional @ref qview_cust "customization Python script" for your specific target system. If not specified, qview will provide only the @ref qview_ui "generic user interface" for interacting with the target (e.g., reset, setting QS filters, posting events, etc.) - -- `qspy_host[:udp_port]` - optional host-name/IP-address:port for the host running the QSPY host utility. If not specified, the default is 'localhost:7701'. - -- `local_port` - optional the local UDP port to be used by "qview". If not specified, the default is '0', which means that the operating system will choose an open port. - - -@subsection qview_exa Examples - - - -@verbatim -python3 %QTOOLS%\qview\qview.py -@endverbatim - -opens the generic (not customized) "qview". - -@verbatim -python3 %QTOOLS%\qview\qview.py dpp.py -@endverbatim - -opens "qview" with the customization provided in the dpp.py script located in the current directory. - -@verbatim -qview ..\qview\dpp.py localhost:7701 -@endverbatim - -opens "qview" (**installed with pip**) with the customization provided in the dpp.py script located in the directory ..\qview. The "qview" will attach to the QSPY utility running at localhost:7701. - -@verbatim -qview dpp.py 192.168.1.100:7705 -@endverbatim - -opens "qview" (**installed with pip**) with the customization provided in the dpp.py script located in the current directory. The "qview" will attach to the QSPY utility running remotely at IP address 192.168.1.100:7705. - - - - -@verbatim -python3 $(QTOOLS)/qview/qview.py -@endverbatim - -opens the generic (not customized) "qview". - -@verbatim -python3 $(QTOOLS)/qview/qview.py dpp.py -@endverbatim - -opens "qview" with the customization provided in the dpp.py script located in the current directory. - -@verbatim -qview *.py ../qview/dpp.py localhost:7701 -@endverbatim - -opens "qview" (**installed with pip**) with the customization provided in the dpp.py script located in the directory ../qview. The "qview" will attach to the QSPY utility running at localhost:7701. - -@verbatim -qview dpp.py 192.168.1.100:7705 -@endverbatim - -opens "qview" (**installed with pip**) with the customization provided in the dpp.py script located in the current directory. The "qview" will attach to the QSPY utility running remotely at IP address 192.168.1.100:7705. - - -@note -In practice, the easiest way to launch QView™ is to define a shortcut, like the one provided with the DPP example:@n@n -@image html qview_shortcut.gif "qview shortcut properties" - - - -@section qview_attaching Attaching QView to QSPY -In contrast to TCP, which is stream-oriented, UDP is packet-oriented, so the only way to "attach" two ends of communication is to exchange packets. Consequently, immediately after QView™ is launched, it tries to **attach** by sending the @ref udp_ATTACH "ATTACH" packet to QSPY. If QSPY responds with the @ref udp_in_ATTACH "ATTACH" response, QView™ considers that it is "attached". - -However, if the @ref udp_in_ATTACH "ATTACH" response does not arrive within a second or two (because perhaps QSPY is not running), QView™ opens a modal dialog box that reminds you to run QSPY, as shown in the screen-shot below: - -@image html qview_attach.gif "Attach to QSPY dialog box" -qview_before.gif -Depending how you start @ref qspy "QSPY", the dialog box might close automatically, which means that QView has successfully **attached** to QSPY. However, if the dialog box does not close, you need to click the **Attach** button to send @ref udp_ATTACH "ATTACH" packet to QSPY, until QView™ receives the @ref udp_in_ATTACH "ATTACH" response from QSPY. If you can't "attach", you can click the **Close** button to close QView™. - -@note -Because UDP works over networks, the QSPY Back-End can run on a **different machine** (e.g., a lab computer) that the the QView™ Front-End (e.g., office computer). These two machines can even run different operating systems, for example Linux on the lab computer and Windows in the office, or vice versa. All you need to do is to provide the host-name parameter as the third command-line argument to the qview.py script (e.g., `python3 qview.py dpp.py 192.168.1.101`). - - -@subsection qview_tstamp Recognizing the Target -Before QView™ can correctly interpret any data from the Target, it needs to obtain certain information about the Target, such as the sizes of object pointers, function pointers, event signals, etc. This information is provided in the ::QS_TARGET_INFO trace record coming from the Target. - -To inform you about the Target status, QView™ displays the **Target: UNKNOWN** in the status bar when the target is "unknown": - -@image html qview_unknown.gif "Target UNKNOWN status" - -If this happens, you can explicitly request the Target information by means of the "Commands->Query Target Info" menu: - -@image html qview_known.gif "Target KNOWN status (build time-stamp)" - -After the Target information is received, the QView™ status bar shows the build time-stamp of the Target image. - -@next{qview_ui} -*/ -/*###########################################################################*/ -/** -@page qview_ui QView User Interface - -

The qview.py script provides a Graphical User Interface (GUI) consisting of the main menu, the text view, the status bar, and the customizable canvas view. -

- -@image html qview.jpg "QView user interface" - -The **main menu** includes several useful commands, which are quickly reviewed and the following sections. The main menu might subsequently be augmented in your own @ref qview_cust "customizations". - - - -@section qview_file File Menu -The File menu provides interface to the @ref qspy_saving "QSPY saving files" feature. This menu allows you to trigger QSPY to save @ref qspy_dict "dictionaries", as well as to open/close all other file formats supported by QSPY. - -@image html qview_file.gif - - - -@section qview_view View Menu -The View menu allows you to toggle (show/hide) the Canvas view. - -@image html qview_view.gif "Text-view and Canvas-view menus" - -@image html qview_canvas.gif "Canvas-view enabled" - -@note -The provided screen shot of the Canvas-view is specific to the DPP example application (see @ref qview_cust). - - - -@section qview_glob Global Filters Menu -The Filters menu opens dialog boxes through which you can set the @ref qs_global "QS Global Filter" for QS Record-Types. - -The Global Filter menu opens dialog boxes for each *group* of global filters. For example, the screen shot below shows the "SM Group" (State Machine Group). In this "SM Group" dialog box you can check/uncheck the individual filters, or you can "Select ALL" or "Clear ALL" filters in the group. - -@image html qview_glob_dlg.gif "Global Filter SM-Group Dialog Box" - - -@note -The Global-Filters menu reflects the status of the whole group by the following status-indicators: -- `[-]`- no filters in the group selected -- `[+-]` - some filters in the group selected -- `[+]` - all filters in the group selected - - - -@section qview_loc Local Filters Menu -The Filters menu opens dialog boxes through which you can set the @ref qs_local "QS Local Filter" for QS QS-IDs. - -The Local Filter menu opens dialog boxes for each *group* of local filters. For example, the screen shot below shows the "AO-IDs" (Active Object Group). In this "AO-IDs" dialog box you can check/uncheck the individual QS-IDs (which are AO priorities in this case), or you can "Select ALL" or "Clear ALL" filters in the group. - -@image html qview_loc_dlg.gif "Local Filter AO_OBJ Dialog Box" - -@note -The Local-Filters menu reflects the status of the whole group by the following status-indicators: -- `[-]`- no filters in the group selected -- `[+-]` - some filters in the group selected -- `[+]` - all filters in the group selected - - - -@section qview_curr Current-Obj Menu -The Curr-Obj menu opens dialog boxes through which you can set the @ref qs_curr "QS Current Objects". - -The Curr-Obj menu opens dialog boxes for each local current object. For example, the screen shot below shows the "AO_OBJ" (current Active Object). In this "Curr-Obj" dialog box you can specify the object either by its name (must match the QS dictionary), or as addresses of the objects in decimal and in hexadecimal (with the `0x` prefix). - -@image html qview_curr_dlg.gif "Current Object AO_OBJ Dialog Box" - -@note -The Curr-Obj menu reflects the selected current objects, which are listed to the right of the filter (e.g. `Table_inst`). - - -@section qview_commands Commands Menu -The Commands menu allows you to execute simple commands (without parameters) in the Target, such as Reset the Target, Query the Target, and clock Tick at rate 0 and rate 1. Also, this menu allows you to execute commands with parameters, which are quickly discussed below - -@image html qview_cmd.gif "Commands Menu" - - -@subsection qview_user Executing User Command -The "User Command..." menu allows you to invoke a command in the Target and pass up to three parameters to this command. (**NOTE:** a command is an application-specific callback function that the QS-RX component executes in the Target). - -@image html qview_cmd_dlg.gif "Command Dialog Box" - -The screen shot above shows how to execute User Command number `0` with the parameters: `12345`, `0xDEADBEEF` and `0` (default). Both the command number and the parameters can be specified in hexadecimal (with the `0x` prefix). - - -@subsection qview_peek Peek Command -The Peek Obj/Addr... command opens a dialog box, in which you can provide the Target object or address (RAM or ROM) (**NOTE:** You can provide either the object name, which must be known by its object-dictionary, or numerical address, which **must** be a valid RAM/ROM address, or the Target might crash.) - -@attention -The "Peek..." menu requires the "Current-Obj AP_OBJ" to be set in the @ref qview_curr, because this is the object within the Target which will be "peeked". The "Peek..." menu is **inactive** (grayed-out) when the "Current-Obj AP_OBJ" is not specified. - - -@note -The Peek Command can be used to view any **readable** address, such as ROM, RAM, and also **peripheral registers** in your Target. - - -As shown in the screen shot below, the PEEK command takes additionally the offset into the object [bytes] (offset of 0 is default if not specified), the size of the item [8-bit, 16-bit, 32-bit] and the number of units (n-units) [1..255] you wish to "peek". - -@image html qview_cmd_peek.gif "Peek Command Dialog Box" -@n - -The Target responds with a #QS_PEEK_DATA trace record, which you can view in QSPY human-readable output (the packet is also sent to QView, where you can react to it in your @ref qview_cust "customization".) - -@verbatim -4294965703 Trg-Peek Offs=0,Size=4,Num=4,Data=<20000D2C,20000D2C,20000D74,000A0008> -@endverbatim - - - -@subsection qview_poke Poke Command -The "Poke Obj/Addr..." command allows you to write data to the specified object or address in Target's RAM (**NOTE:** You can provide either the object name, which must be known by its object-dictionary, or numerical address, which **must** be a valid RAM address, or the Target might crash.) - -@attention -The "Poke..." menu requires the "Current-Obj AP_OBJ" to be set in the @ref qview_curr, because this is the object within the Target which will be "poked". The "Poke..." menu is **inactive** (grayed-out) when the "Current-Obj AP_OBJ" is not specified. - - -@note -The Poke Command can be used to change any **writable** address, such as RAM, but also **peripheral registers** in your Target. - - -As shown in the screen shot below, the POKE command takes additionally the offset into the object [bytes], the size of the item [8-bit, 16-bit, 32-bit], and the data to "poke", which can be either decimal or hexadecimal (`0x` prefix). - -@image html qview_cmd_poke.gif "Poke Command Dialog Box" -@n - -The Target responds with `Trg-Ack QS_RX_POKE`: - -@verbatim - Trg-Ack QS_RX_POKE -@endverbatim - - -@section qview_events Events Menu -The "Events" menu allows you to Publish, Post, or Dispatch an event to the Target. Additionally, you can also "Initialize" a state machine by triggering the top-most initial transition in it. - -@attention -The "Post..." menu requires the "Current-Obj AO_OBJ" to be set in the @ref qview_curr, because this is the Ative Object within the Target which will be "posted". The "Dispatch..." and "Init SM..." menus require the "Current-Obj SM_OBJ" to be set in the @ref qview_curr, because this is the State Machine within the Target which will be "dispatched" or "initialized". These menus are **inactive** (grayed-out) when the expected "Current-Objects" are not specified. - -@image html qview_evt_dlg.gif "Events Menu with Post-Event Dialog Box" - - -As shown in the screen-shot above, you define the custom event by providing the sig (signal), which can be either symbolic name (must correspond to the Signal Dictionary) or a numerical value. - -The signal is followed by up to 9 optional event parameters par1..par9. Each parameter is specified as a pair of the size of the parameter [8-bit, 16-bit, 32-bit], and the value of the parameter, which can be either decimal or hexadecimal (`0x` prefix). - -@attention -The parameters are sent using the **endianness** reported by the Target. Also, all the specified parameters are packed in the exact order without any "alignment". If the event structure is represented in the Target memory with some **padding**, you need to provide such padding explicitly (as one of the parameters). - - -@section qview_custom Custom Menu -This top-level menu is provided for your customization. It's intent is to let you add your own commands in your script. - -@image html qview_cust.gif - - -@section qview_help Help Menu -This menu allows you to access the online Q-SPY help in HTML, and also allows you to open the "About" dialog box. - -@image html qview_help.gif - - -@next{qview_cust} -*/ -/*###########################################################################*/ -/** -@page qview_cust Customizing & Extending QView™ - -@tableofcontents - -QView™ has been specifically designed for extensibility, so that you can customize its behavior to your specific project. In fact, as mentioned in the section about @ref qview_run "running QView", the qview.py script takes the `` @ref qview_command "command-line parameter", which is another Python script designed specifically to extend and customize the basic functionality. This section describes how to write this @ref qview_script "customization script", so that you can turn QView™ into a powerful remote **Human-Machine Interface** (HMI) for your embedded system. - -@remark -You don't need to change the qview.py script to customize and extend it for your project. The customization you make go into a separate script, which is specific to your project. That way, you can have many different customization scripts and you don't pollute (and possibly break) the original code. - - -@section qview_cust_menu Custom Menu -The simple way of customizing QView™ is to add **custom menus**. - -@image html qview_cust.gif - - -@section qview_canvas Custom Canvas -The main part of the QView™ interface that you customize for your specific embedded system is the **custom Canvas**. The custom Canvas can show a complete custom Human-Machine Interface (HMI) to your embedded Target. The Canvas can display the changing status of the application and also it can provide **actuators**, like buttons, sliders, etc. to **interact** with the embedded Target. The following animation shows the custom Canvas for the DPP example (dpp.py script explained later). Please note that the button in the center of the screen allows you to interact with the Target by posting events to it. Please refer to this script code for the details of how various effects have been achieved. - -@image html qview_canv_dpp.gif "Custom Canvas for the DPP Application" - -@n -@note -QView™ GUI is based on the [Tkinter](https://docs.python.org/3/library/tkinter.html) and therefore it is highly recommended that you get familiar with this Python library. Specifically of interest for customizing QView™ is the [Tkinter Canvas](https://www.tutorialspoint.com/python/tk_canvas.htm).@n -@n -Many Python widget libraries (e.g. [tk_tools](https://github.com/slightlynybbled/tk_tools), etc.) are available to aid you in developing your custom canvas. With such widget libraries, you can display the data in an attractive form: as gauges, bars, graphs, and sliders. The attractiveness of the GUI is limited only by your creativity. - - -@section qview_script Customization Script -The easiest way to customize QView is to copy the provided example script (dpp.py located in /examples/workstation/dpp/qview folder), rename it, and add your own extensions. The explanation section following the listing clarifies the interesting lines of code (lines starting with `[xx]` labels). - -@code{py} -[1] class DPP: -[2] def __init__(self): - - # request target reset on startup... -[3] reset_target() - - # add commands to the Custom menu... -[4] QView.custom_menu.add_command(label="Custom command", - command=self.cust_command) - - # configure the custom QView.canvas... -[5] QView.show_canvas() # make the canvas visible -[6] QView.canvas.configure(width=400, height=260) - - # tuple of activity images (correspond to self._philo_state) -[7] self._act_img = ( -[8] PhotoImage(file=HOME_DIR + "/img/thinking.gif"), - PhotoImage(file=HOME_DIR + "/img/hungry.gif"), - PhotoImage(file=HOME_DIR + "/img/eating.gif"), - ) - # tuple of philo canvas images (correspond to self._philo_obj) - self._philo_img = (\ - QView.canvas.create_image(190, 57, image=self._act_img[0]), - QView.canvas.create_image(273, 100, image=self._act_img[0]), - QView.canvas.create_image(237, 185, image=self._act_img[0]), - QView.canvas.create_image(146, 185, image=self._act_img[0]), - QView.canvas.create_image(107, 100, image=self._act_img[0]) - ) - - # button images for UP and DOWN - self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") - self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") - - # images of a button for pause/serve - self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) -[9] QView.canvas.tag_bind(self.btn, "", self.cust_pause) - - - # on_reset() callback -[10] def on_reset(self): - # clear the lists -[11] self._philo_obj = [0, 0, 0, 0, 0] - self._philo_state = [0, 0, 0] - - # on_run() callback -[20] def on_run(self): -[21] glb_filter("QS_USER_00") - - # NOTE: the names of objects for loc_filter() and current_obj() - # must match the QS Object Dictionaries produced by the application. -[22] current_obj(OBJ_AO, "Table_inst") -[23] loc_filter(IDS_AO) - - # turn lists into tuples for better performance -[24] self._philo_obj = tuple(self._philo_obj) - self._philo_state = tuple(self._philo_state) - - - # example of a custom command -[30] def cust_command(self): -[31] command(1, 12345) - - # example of a custom interaction with a canvas object (pause/serve) -[40] def cust_pause(self, event): -[41] if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): -[42] QView.canvas.itemconfig(self.btn, image=self.img_UP) -[43] post("SERVE_SIG") -[44] QView.print_text("Table SERVING") - else: - QView.canvas.itemconfig(self.btn, image=self.img_DWN) - post("PAUSE_SIG") - QView.print_text("Table PAUSED") - - # intercept the QS_USER_00 application-specific packet - # this packet has the following structure (see bsp.c:displayPhilStat()): - # record-ID, seq-num, Timestamp, format-byte, Philo-num, - # format-bye, Zero-terminated string (status) -[50] def QS_USER_00(self, packet): - # unpack: Timestamp->data[0], Philo-num->data[1], status->data[3] -[51] data = qunpack("xxTxBxZ", packet) - i = data[1] - j = ("t", "h", "e").index(data[2][0]) # the first letter - - # animate the given philo image according to its activity - QView.canvas.itemconfig(self._philo_img[i], image=self._act_img[j]) - - # print a message to the text view - QView.print_text("%010d Philo %1d is %s"%(data[0], i, data[2])) - - #============================================================================= -[60] QView.customize(DPP()) # set the QView customization - -@endcode - -@subsection qview_cust_init Initialization - -
-
1
Every QView™ customization consists of a Python __class__, which does not extend any other class and can be called with any name you see fit. -
-
2
The constructor of your customization class sets up the GUI and optionally resets the target. -
-
3
The reset_target() command allows you to remotely reset the embedded Target. -> **NOTE:** Normally, for an embedded application you would like to start with resetting the Target, to start clean with @ref qs_dict "QS dictionaries", etc. However, if you run your application on the **host** (e.g., `/examples/workstation/dpp`), you typically don't want to reset the target. Instead, you simply launch the host executable *after* opening QView™, so that it will "see" all the QS dictionaries, etc. This alternative is shown in the DPP example for the host located in `/examples/workstation/dpp`). -
-
4
The @ref qview.QView.custom_menu "QView.custom_menu" object allows you to extend the @ref qview_custom "Custom Menu" with your own commands. Here, you just add the command "Custom command". Later you will write the function that handles this menu item. -> **NOTE:** The @ref qview.QView.custom_menu "QView.custom_menu" object uses the [Tkinter Menu interface](https://www.tutorialspoint.com/python/tk_menu.htm) -
-
-
- - -@subsection qview_cust_canvas Setting Up the Canvas -The Custom Canvas is setup in the **constructor** of the customization clss `__init__(self)`) using the @ref qview.QView.canvas "QView.canvas" object: - -
-
5
The @ref qview.QView.show_canvas() "QView.show_canvas()" function lets you @ref show the canvas from the beginning. This corresponds to setting the Canvas checkbox in the @ref qview_view. -
-
6
The @ref qview.QView.canvas "QView.canvas" object can be configured to the desired size using the standard tkinter functionality. -> **NOTE:** The @ref qview.QView.canvas "QView.canvas" object uses the [Tkinter Canvas interface](https://www.tutorialspoint.com/python/tk_canvas.htm) -
-
7-8
You need to organize the GUI elements for the canvas, so that they easily map to your specific customization. Here, the images representing the Dining Philosophers activities and Philosophers themselves sitting around the table are represented as [Python tuples](https://www.tutorialspoint.com/python/python_tuples.htm). -> **NOTE:** The proper design of the data structures for your application can vastly simplify the customization script. Please remember to take advantage of the rich Python data structures, such as lists, tuples, dictionaries and arrays. -
-
9
This line demonstrates how to provide a **keyboard binding** to a canvas element (the center button `self.btn` in this case). -
-
-
- - -@subsection qview_cust_reset The on_reset() Callback -The main qview.py script calls the on_reset() callback function in your customization script when it receives the @ref #QS_TARGET_INFO "reset packet" from the Target. This gives you an opportunity to clear your internal data structures to get them ready for new data coming from the Target (e.g. @ref qs_dict). - -
-
10
The @ref on_reset() callback must be member of the customization class (note the `self` parameter). -
-
11
Here, the callback clears the internal lists used by customization. -
-
-
- - -@subsection qview_cust_run The on_run() Callback -The main qview.py script calls the on_run() callback function in your customization script when it receives the @ref #QS_QF_RUN trace record from the Target. This record typically marks the end of the Target initialization and, specifically, the completion of the @qs_dict. This gives you an opportunity to set the @ref qs_filters, @ref qs_curr, using their **symbolic names**. - -@note -The **symbolic names** inside the Target are known to QSPY only *after* the Target produces the @ref qs_dict. - - -
-
20
The @ref on_run() callback must be member of the customization class (note the `self` parameter). -
-
21
Here, the callback sets the @ref qs_global "Global Filter" by means of the glb_filter() facility provided in the qview.py script. -
-
22
Here, the callback sets the @ref qs_curr "Current Objects" by means of the current_obj() facility provided in the qview.py script. -
-
23
Here, the callback sets the @ref qs_local "Local Filter" by means of the loc_filter() facility provided in the qview.py script. -
-
-
- -@note -The glb_filter(), current_obj(), and loc_filter() facilities in QView™ are **identical** as in the @ref qutest "QUTest". This commonality between @ref qview "QView™" and @ref qutest "QUTest™" is intentional. - - -@subsection qview_cust_cmd Custom Commands -The Custom Command added either to the @ref qview.QView.custom_menu "QView.custom_menu" or attached to the Canvas elements need to be implemented as a member functions of the customization class: - -
-
30
The function name must match the `command=self.cust_command` parameter in the `menu.add_command()` (see step [4] of the script) -
-
31
Here, the function invokes the command() facility provided in the qview.py script. -
-
  -
-
40
The function name must match the `...tag_bind(... self.cust_pause)` parameter (see step [9] of the script) -
-
41
Here, the function **checks the Canvas elements** (using the standard Tkinter functionality). -
-
42
Here, the function **configures the Canvas elements** (using the standard Tkinter functionality). -
-
43
Here, the function **posts an event** to the Target by means of the post() facility provided in the qview.py script. -
-
43
Here, the function **prints text** to the @ref qview_ui "Text View" by means of the @ref qview.QView.print_text() "QView.print_text()" facility provided in the qview.py script. -
-
-
- -@note -The command() and post() facilities in QView™ are **identical** as in the @ref qutest "QUTest". This commonality between @ref qview "QView™" and @ref qutest "QUTest™" is intentional. - - -@subsection qview_cust_handler Custom Packet Handlers -The most important feature of QView™ is that it can display the **live** status of the embedded system. QView™ achieves it by receiving the QS software tracing packets from the Target. Consequently, one of the most important activities of the customization script is to intercept and parse the incoming packets. - -To this end, the qview.py script provides special accumulations: - -- the qview.py script provides a **packet-specific callback** for every QS trace record from the Target. The name of the callback is identical to the enumerated names of the #QSpyRecords of the trace records. For example, the packet-handler for the QS trace record #QS_QEP_TRAN is named `QS_QEP_TRAN()`. - -- the qview.py script provides the qunpack() facility, specifically designed to parse and unpack the QS trace records. - - -
-
50
The packet-handler name must match the enumeration #QSpyRecords. Here, the packet-handler is for the #QS_USER_00 trace record -
-
51
Here, the packet-handler calls the qunpack() facility to "unpack" the binary data form the received packet into the Python tuple `data`. Each element in this tuple corresponds to the explicitly specified format. For example, with the format "xxTxBxZ": the "T" format (timestamp) is unpacked into `data[0]`, the "B" format (byte) is unpacked into `data[1]`, and the "Z" format (zero-terminated ASCII string) is unpacked into `data[2]`. Subsequently, in the body of the function the `data[]` elements are used according to their meaning. -
-
-
- -@note -The qunpack() facility "understands" all formats supported by the Python `struct.unpack()` plus formats specific to the QP/Spy, such as: "T" for timestamp, "S" for event signal, "" - - -@subsection qview_cust_set Registering Customization in QView™ - -
-
60
Every QView™ customization script must end with a call to @ref qview.QView.customize() "QView.customize()" function, to which you need to pass the instance of your Customization class (here your `DPP` class). -
-
-
- - -@subsection qview_pre App-Specific Vs. Predefined Trace Records -The customization script discussed in the previous section was based on the @ref qs_app "application-specific trace record" (`QS_USER_00`), which was specifically produced by the DPP application. This trace record delivered the information abou the changing status of the Dining Philosophers, which allowed the customization script to animate the Philosopher images on the custom canvas. - -However, it is also possible to use a different strategy based on the @ref qs_pre "predefined QS trace records". The advantage is that **no additional instrumentation** is needed in the application, because the information is already produced by the framework. All you need to do is to enable (in the global filter) the appropriate QS trace record. - -This alternative strategy is illustrated in the dpp1.py script (located in the same directory as the dpp.py script discussed earlier). The dpp1.py script is based on the predefined QS record #QS_QEP_TRAN, which provides the information about the **state changes** in the Philo objects in the application. - -The most tricky part in this approach is to correctly unpack the predefined record. And here, the biggest challenge is to translate the binary addresses of the objects to their **symbolic names**. For that, the dpp1.py script intercepts the @ref qs_dict "QS dictionary" records #QS_OBJ_DICT and #QS_FUN_DICT, from which the script retrieves the binary addresses of the specific objects. Below are the relevant snippets from the dpp.py script. Please note the use of Python lists, tuples, and dictionaries to organize the data for easy access by the index number of the Philo objects or by the state name. - -@code{py} -class DPP: - . . . - # intercept the QS_OBJ_DICT stadard packet - # this packet has the following structure: - # record-ID, seq-num, Object-ptr, Zero-terminated string - def QS_OBJ_DICT(self, packet): - data = qunpack("xxOZ", packet) - try: - # NOTE: the names of objects must match the QS Object Dictionaries - # produced by the application. - i = ("Philo_inst[0]", - "Philo_inst[1]", - "Philo_inst[2]", - "Philo_inst[3]", - "Philo_inst[4]").index(data[1]) - self._philo_obj[i] = data[0] - except: - pass # dictionary for a different object - - # intercept the QS_FUN_DICT stadard packet - # this packet has the following structure: - # record-ID, seq-num, Function-ptr, Zero-terminated string - def QS_FUN_DICT(self, packet): - data = qunpack("xxFZ", packet) - try: - # NOTE: the names of states must match the QS Object Dictionaries - # produced by the application. - j = ("Philo_thinking", - "Philo_hungry", - "Philo_eating").index(data[1]) - self._philo_state[j] = data[0] - except: - pass # dictionary for a different state - - # intercept the QS_QEP_TRAN stadard packet - # this packet has the following structure: - # record-ID, seq-num, Timestamp, Signal, Object-ptr, - # Function-ptr (source state), Function-ptr (new active state) - def QS_QEP_TRAN(self, packet): - data = qunpack("xxTSOFF", packet) - try: - i = self._philo_obj.index(data[2]) - j = self._philo_state.index(data[4]) - - # animate the given philo image according to its activity - QView.canvas.itemconfig(self._philo_img[i], - image=self._act_img[j]) - # print a message to the text view - QView.print_text("%010d Philo %d is %s"\ - %(data[0], i, ("thinking", "hungry", "eating")[j])) - except: - pass # state-entry in a different object - . . . -@endcode - -@n -@note -The presented strategy of intercepting the @ref qs_dict "QS dictionary" records #QS_OBJ_DICT and #QS_FUN_DICT is quite generic and can be easily adapted in your own customization scripts. - - -@subsection qview_dsl-commands QView Script Commands -Here is the summary of commands that you can use in the QView scripts: - -- reset_target() -- command() -- peek() -- poke() -- tick() -- glb_filter() -- loc_filter() -- ao_filter() -- current_obj() -- query_curr() -- post() -- publish() -- init() -- dispatch() -- qunpack() - -@next{qwin} -*/ - diff --git a/doxygen/qwin.dox b/doxygen/qwin.dox deleted file mode 100644 index 5d61d57..0000000 --- a/doxygen/qwin.dox +++ /dev/null @@ -1,55 +0,0 @@ -/*! @page qwin QWin™ GUI Prototyping Toolkit - -@htmlonly - -@endhtmlonly - -

When developing embedded code for devices with non-trivial user interfaces, it often pays off to build a prototype (virtual prototype) of the embedded system on a PC. The strategy is called "dual targeting", because you develop software on one machine (e.g., Windows PC) and run it on a deeply embedded target, as well as on the PC. Dual targeting is the main strategy for avoiding the "target system bottleneck" in the agile embedded software development. - -@note -Please note that dual targeting does not mean that the embedded device has anything to do with the PC or Windows. Neither it means that the simulation must be cycle-exact with the embedded target CPU. Instead, dual targeting simply means that from day one, your embedded code (typically in C or C++) is designed to run on at least two platforms: the final target hardware and your PC. All you really need for this is two C/C++ compilers: one for the PC and another for the embedded device. - - - -

QWin™ GUI Prototyping Toolkit

-QWin™ is a free GUI toolkit for prototyping embedded systems on Windows in the C or C++ programming language, including building realistic embedded front panels consisting of LCD displays (both graphic and segmented), LEDs, buttons, knobs, sliders, etc. The implementation is based on the **raw Win32 API** to provide simple direct mapping to C/C++ for easy integration with your embedded code. - -@image html qwin_ani.gif "Example of a QWIN Prototype with graphic LCD, buttons, LEDs, and segmented display" -@n - -@remark -The problem of building GUI prototypes of embedded devices on the desktop is very common, yet it seems that most developers try to use C#, .NET, VisualBasic or other such environments to build prototypes of their embedded devices. The main shortcoming of all such solutions is that they don't provide direct binding to C/C++, which complicates the build process and the **debugging of the C/C++ code** on the host. - - - -@section qwin_usage QWin™ Usage -QWin™ is included in the QTools™ Collection in the sub-directory qtools/qwin/ and consists of just two files: qwin_gui.h containing the interface and qwin_gui.c providing the implementation. You use QWin™ by including these files in your projects. - -@note -QWin™ is also already included in the [QP/C](https://www.state-machine.com/qpc/), [QP/C++](https://www.state-machine.com/qpcpp/), and [QP-nano](https://www.state-machine.com/qpn/) frameworks (in the `\ports\win32` and `\ports\win32-qv` directories), so if you use any of these frameworks, you don't need to take QWin™ from the QTools Collection. - - - -@section qwin_features QWin™ Features -Currently QWin™ provides the following facilities: - -- Graphic displays (pixel-addressable) such as graphical LCDs, OLEDs, etc. with up to 24-bit color -- Segmented displays such as segment LCDs, and segment LEDs with generic, custom bitmaps for -the segments. -- Owner-drawn buttons with custom “depressed” and “released” bitmaps and capable of generating -separate events when depressed and when released. -Additionally, the provided code shows how to handle input sources: -- Keyboard events -- Mouse move events and mouse-wheel events - - - -@section qwin_doc QWin™ Documentation -QWin™ GUI Prototyping Toolkit is described in the Application Note: Application Note: QWIN GUI Kit for Prototyping Embedded Systems on Windows. - -@image html qwin.png "Application Note: QWIN GUI Kit for Prototyping Embedded Systems on Windows" - -Regarding the size and complexity of the “QWin™ GUI Toolkit“, the implementation of the aforementioned GUI elements takes only about 250 lines of C. The example with all sources of input and a lot of comments amounts to some 300 lines of C. The toolkit has been tested with the free MinGW compiler (included in the @ref qtools_win "QTools™ Collection for Windows"), the free Visual C++ Express, and the free ResEdit resource editor. - -@next{qclean} -*/ diff --git a/doxygen/snippets/Led.h b/doxygen/snippets/Led.h deleted file mode 100644 index 246c36a..0000000 --- a/doxygen/snippets/Led.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef LED_H -#define LED_H - -enum { MAX_LED = 5 }; - -/* turns a given LED on and retruns the power drawn by it in uW */ -uint32_t Led_on(uint8_t index); - -/* turns a given LED off */ -void Led_off(uint8_t index); - -#endif /* LED_H */ \ No newline at end of file diff --git a/doxygen/snippets/LedBar.c b/doxygen/snippets/LedBar.c deleted file mode 100644 index 174dfe2..0000000 --- a/doxygen/snippets/LedBar.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include "LedBar.h" -#include "Led.h" - -/* - Example sequence diagram for the LedBar_setPercent() implementation: - - +----------+ +------+ +------+ +------+ +------+ +------+ - | LedBar | |LED[0]| |LED[1]| |LED[2]| |LED[3]| |LED[4]| - +----------+ +------+ +------+ +------+ +------+ +------+ - | | | | | | - +-+ Led_on() | | | | | - | |------------->| | | | | - | | | | | | | - | | Led_on() | | | | | - | |----------------------->| | | | - | | | | | | | - | | Led_on() | | | | | - | |--------------------------------->| | | - | | | | | | | - | | Led_off() | | | | | - | |------------------------------------------->| | - | | | | | | | - | | Led_off() | | | | | - | |----------------------------------------------------->| - | | | | | | | - +-+ | | | | | - | | | | | | -*/ -uint32_t LedBar_setPercent(uint8_t percent) { - uint8_t n = (uint8_t)((percent * MAX_LED) / 100); - uint8_t i; - uint32_t p = 0U; /* power draw in uW */ - for (i = 0U; i < n; ++i) { - p += Led_on(i); - } - for (i = n; i < MAX_LED; ++i) { - Led_off(i); - } - return p; -} diff --git a/doxygen/snippets/ProductionCode.c b/doxygen/snippets/ProductionCode.c deleted file mode 100644 index db128e5..0000000 --- a/doxygen/snippets/ProductionCode.c +++ /dev/null @@ -1,24 +0,0 @@ - -#include "ProductionCode.h" - -int Counter = 0; -int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; /* some obnoxious array to search that is 1-based indexing instead of 0. */ - -/* This function is supposed to search through NumbersToFind and find a particular number. - * If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since - * NumbersToFind is indexed from 1. Unfortunately it's broken - * (and should therefore be caught by our tests) */ -int FindFunction_WhichIsBroken(int NumberToFind) -{ - int i = 0; - while (i < 8) /* Notice I should have been in braces */ - i++; - if (NumbersToFind[i] == NumberToFind) /* Yikes! I'm getting run after the loop finishes instead of during it! */ - return i; - return 0; -} - -int FunctionWhichReturnsLocalVariable(void) -{ - return Counter; -} diff --git a/doxygen/snippets/ao_filter.py b/doxygen/snippets/ao_filter.py deleted file mode 100644 index fde94db..0000000 --- a/doxygen/snippets/ao_filter.py +++ /dev/null @@ -1,7 +0,0 @@ -ao_filter(6) # enables AO of priority 6 in the Target - -ao_filter(-6) # disables AO of priority 6 in the Target - -ao_filter("AO_Table") # enables "AO_Table" in the Target - -ao_filter("-AO_Table") # disables "AO_Table" in the Target diff --git a/doxygen/snippets/command.py b/doxygen/snippets/command.py deleted file mode 100644 index 62605d7..0000000 --- a/doxygen/snippets/command.py +++ /dev/null @@ -1,5 +0,0 @@ -test("...") -... -command(0, 78) # <=== -expect("...") -... diff --git a/doxygen/snippets/continue_test.py b/doxygen/snippets/continue_test.py deleted file mode 100644 index ed2bc3c..0000000 --- a/doxygen/snippets/continue_test.py +++ /dev/null @@ -1,6 +0,0 @@ -def on_reset(): - expect_pause() - glb_filter(GRP_UA) - current_obj(OBJ_SM_AO, "AO_MyAO") - continue_test() # <==== - expect_run() diff --git a/doxygen/snippets/current_obj.py b/doxygen/snippets/current_obj.py deleted file mode 100644 index bf6e67f..0000000 --- a/doxygen/snippets/current_obj.py +++ /dev/null @@ -1,9 +0,0 @@ -current_obj(OBJ_SM, "my_state_machine") - -current_obj(OBJ_MP, "EvtPool1") - -current_obj(OBJ_AP, "my_object") - -current_obj(OBJ_SM_AO, "Philo[2]") - -current_obj(OBJ_AP, 0x20001234) diff --git a/doxygen/snippets/ensure.py b/doxygen/snippets/ensure.py deleted file mode 100644 index 56a7b51..0000000 --- a/doxygen/snippets/ensure.py +++ /dev/null @@ -1,10 +0,0 @@ -test("Ensure") -command("COMMAND_B", 123, 23456, 3456789) -expect("@timestamp COMMAND_B *") -last = last_rec().split() -p1 = int(last[2]) -p2 = int(last[4]) - -ensure(123 == p1) # <--- -ensure(3456789 == p2) # <--- - diff --git a/doxygen/snippets/expect.py b/doxygen/snippets/expect.py deleted file mode 100644 index 79ea0e0..0000000 --- a/doxygen/snippets/expect.py +++ /dev/null @@ -1,7 +0,0 @@ -expect("0000000001 USER+000 FindFunction_WhichIsBroken 0 78") - -expect("@timestamp Trg-Done QS_RX_COMMAND") - -expect(" Tick<0> Ctr=*") - -expect("@timestamp IO_CALL IO_Write %d %d" %(CommandReg, ProgramCmd)) diff --git a/doxygen/snippets/expect_pause.py b/doxygen/snippets/expect_pause.py deleted file mode 100644 index da13159..0000000 --- a/doxygen/snippets/expect_pause.py +++ /dev/null @@ -1,6 +0,0 @@ -def on_reset(): - expect_pause() # <==== - glb_filter(GRP_UA) - current_obj(OBJ_SM_AO, "AO_MyAO") - continue_test() - expect_run() diff --git a/doxygen/snippets/expect_run.py b/doxygen/snippets/expect_run.py deleted file mode 100644 index 39482cf..0000000 --- a/doxygen/snippets/expect_run.py +++ /dev/null @@ -1,6 +0,0 @@ -def on_reset(): - expect_pause() - glb_filter(GRP_UA) - current_obj(OBJ_SM_AO, "AO_MyAO") - continue_test() - expect_run() # <==== diff --git a/doxygen/snippets/glb_filter.py b/doxygen/snippets/glb_filter.py deleted file mode 100644 index f31dbdc..0000000 --- a/doxygen/snippets/glb_filter.py +++ /dev/null @@ -1,11 +0,0 @@ -glb_filter() # clears all global filters - -glb_filter(GRP_ALL) # sets all global filters - -glb_filter(GRP_SM, GRP_AO) # sets SM-group and AO-group - -glb_filter(GRP_ALL, -GRP_SC) # sets all global filters, but clears the SC-group - -glb_filter(GRP_QF, "-QS_QF_TICK") # sets the QF-group, but clears the QS_QF_TICK filter - -glb_filter(GRP_AO, 78)` # sets the AO-group and the QS record 78 diff --git a/doxygen/snippets/inc_file.py b/doxygen/snippets/inc_file.py deleted file mode 100644 index 11e3ecd..0000000 --- a/doxygen/snippets/inc_file.py +++ /dev/null @@ -1,11 +0,0 @@ -# file test_inc.pyi (include file) - -# common on_reset() callback -def on_reset(): - expect_pause() - glb_filter(GRP_ALL) - continue_test() - -def my_test_snippet(): - query_curr(OBJ_SM) - expect("@timestamp Query-SM Obj=Blinky::inst,State=Blinky::off") diff --git a/doxygen/snippets/inc_test.py b/doxygen/snippets/inc_test.py deleted file mode 100644 index 2f3cec5..0000000 --- a/doxygen/snippets/inc_test.py +++ /dev/null @@ -1,7 +0,0 @@ -# file test_blinky.py (actual test script) - -include("test_inc.pyi") #<--- include common code - -test("my test xyz") -my_test_snippet() -... diff --git a/doxygen/snippets/loc_filter.py b/doxygen/snippets/loc_filter.py deleted file mode 100644 index dfbe702..0000000 --- a/doxygen/snippets/loc_filter.py +++ /dev/null @@ -1,13 +0,0 @@ -loc_filter(IDS_ALL) # enables all QS-IDs - -loc_filter(-IDS_ALL) # disables all QS-IDs - -loc_filter(IDS_AO) # enables all active objcts - -loc_filter(IDS_AO, -6) # enables all active objcts, - # but disables AO with priority 6 - - -loc_filter(IDS_AO, IDS_EP) # enables all active objects and event pools - -loc_filter(IDS_AP) # enables all app-specific QS_IDs diff --git a/doxygen/snippets/qs_ap.c b/doxygen/snippets/qs_ap.c deleted file mode 100644 index 0f349a9..0000000 --- a/doxygen/snippets/qs_ap.c +++ /dev/null @@ -1,24 +0,0 @@ -enum UserSpyRecords { - . . . - PHILO_STAT = QS_USER, /* define a user QS record types */ - . . . -}; - -void displyPhilStat(uint8_t n, char const *stat) { - . . . - - /* application-specific record */ - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio); - QS_U8(0, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_U8(QS_HEX_FMT, 0xABU); /* test */ - QS_U16(QS_HEX_FMT, 0xDEADU); /* test */ - QS_U32(QS_HEX_FMT, 0xDEADBEEFU); /* test */ - QS_U64(QS_HEX_FMT, 0xDEADBEEF12345678LL); /* test */ - QS_END(); -} - -QSPY ouptut produced: - -4294954639 PHILO_STAT 3 thinking 0xAB 0xDEAD 0xDEADBEEF 0xDEADBEEF12345678 - diff --git a/doxygen/snippets/qunpack.py b/doxygen/snippets/qunpack.py deleted file mode 100644 index a40427a..0000000 --- a/doxygen/snippets/qunpack.py +++ /dev/null @@ -1,6 +0,0 @@ -data = qunpack("xxTxBxZ", packet) - -# returns: -# data[0], corresponds to 'T' format (QP/Spy timestamp) -# data[1], corresponds to 'B' format (standard struct.unpack()) -# data[2], corresponds to 'Z' format (QP/Spy zero-terminated string) diff --git a/doxygen/snippets/tick.py b/doxygen/snippets/tick.py deleted file mode 100644 index c042edb..0000000 --- a/doxygen/snippets/tick.py +++ /dev/null @@ -1,7 +0,0 @@ -# tests... -test("tick") -glb_filter(GRP_ALL) -current_obj(OBJ_TE, "l_philo<2>.timeEvt") -tick() # <==== -expect("...") -... diff --git a/qcalc/qcalc.py b/qcalc/qcalc.py index a7ee863..0628bed 100644 --- a/qcalc/qcalc.py +++ b/qcalc/qcalc.py @@ -1,32 +1,36 @@ -#----------------------------------------------------------------------------- -# Product: QCalc in Python (requires Python 3.3+) -# Last updated for version 6.9.4 -# Last updated on 2021-09-12 +#============================================================================= +# QCalc programmer's Calculator +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software +# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# This software is dual-licensed under the terms of the open source GNU +# General Public License version 3 (or any later version), or alternatively, +# under the terms of one of the closed source Quantum Leaps commercial +# licenses. # -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# The terms of the open source GNU General Public License version 3 +# can be found at: # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# The terms of the closed source Quantum Leaps commercial licenses +# can be found at: # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Redistributions in source code must retain this top-level comment block. +# Plagiarizing this software to sidestep the license obligations is illegal. # # Contact information: # # -#----------------------------------------------------------------------------- +#============================================================================= +## +# @date Last updated on: 2022-01-27 +# @version Last updated for version: 7.0.0 +# +# @file +# @brief QCalc programmer's Calculator +# @ingroup qtools +import os import traceback from math import * @@ -38,7 +42,7 @@ class QCalc: ## current version of QCalc - VERSION = 694 + VERSION = 700 @staticmethod def _print(result): @@ -49,7 +53,7 @@ def _print(result): if isinstance(ans, int): # outside the 64-bit range? if ans < -0xFFFFFFFFFFFFFFFF or 0xFFFFFFFFFFFFFFFF < ans: - print("! out of range") + print("\x1b[41m\x1b[1;37m! out of range\x1b[0m") return #inside the 32-bit range? @@ -93,13 +97,16 @@ def _print(result): #============================================================================= # main entry point to QCalc def main(): + if os.name == "nt": + os.system("color") + print("QCalc Programmer's Calculator {0:d}.{1:d}.{2:d} " \ "running on Python {3}".format( QCalc.VERSION//100, (QCalc.VERSION//10) % 10, QCalc.VERSION % 10, python_version())) - print("(c) 2005-2021 Quantum Leaps, www.state-machine.com\n") + print("(c) 2005-2022 Quantum Leaps, www.state-machine.com\n") # "batch mode": expression provided in command-line arguments if len(argv) > 1: @@ -122,7 +129,9 @@ def main(): except: traceback.print_exc(2) else: + print("\x1b[47m\x1b[30m", end = "") QCalc._print(result) + print("\x1b[0m", end = "") else: break diff --git a/qcalc/setup.py b/qcalc/setup.py index 888e5a7..80ff6eb 100644 --- a/qcalc/setup.py +++ b/qcalc/setup.py @@ -9,7 +9,7 @@ setup( name="qcalc", - version="6.9.4", + version="7.0.0", author="Quantum Leaps", author_email="info@state-machine.com", description="qcalc programmer's calculator", diff --git a/qspy/include/be.h b/qspy/include/be.h index 2436a8a..e9e90c6 100644 --- a/qspy/include/be.h +++ b/qspy/include/be.h @@ -1,41 +1,34 @@ -/** -* @file -* @brief Back-End connection point for the external Front-Ends -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.8.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2020 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief Back-End connection point for the external Front-Ends +* @ingroup qpspy */ #ifndef be_h #define be_h @@ -57,4 +50,3 @@ void BE_sendLine(void); /* send the QSPY parsed line to the Front-End */ #endif #endif /* be_h */ - diff --git a/qspy/include/getopt.h b/qspy/include/getopt.h index 75cdfbe..e874a6c 100644 --- a/qspy/include/getopt.h +++ b/qspy/include/getopt.h @@ -4,7 +4,7 @@ * Copyright (c) 2002-2003, Mark K. Kim * Copyright (c) 2012-2017, Kim Grasman * -* Modified by Quantum Leaps 2018 +* Modified by Quantum Leaps 2018 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/qspy/include/pal.h b/qspy/include/pal.h index 14dfeb4..8179e30 100644 --- a/qspy/include/pal.h +++ b/qspy/include/pal.h @@ -1,41 +1,34 @@ -/** -* @file -* @brief Platform Abstraction Layer (PAL) -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2022-01-12 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief Platform Abstraction Layer (PAL) +* @ingroup qpspy */ #ifndef pal_h #define pal_h @@ -44,19 +37,6 @@ extern "C" { #endif -QSpyStatus PAL_openBE(int portNum); /* open Back-End socket */ -void PAL_closeBE(void); /* close Back-End socket */ -void PAL_send2FE(unsigned char const *buf, uint32_t nBytes); /* to Front-End */ -void PAL_detachFE(void); /* detach Front-End */ -void PAL_clearScreen(void); - -QSpyStatus PAL_openTargetSer(char const *comName, int baudRate); -QSpyStatus PAL_openTargetTcp(int portNum); -QSpyStatus PAL_openTargetFile(char const *fName); - -QSpyStatus PAL_openKbd(bool kbd_inp); -void PAL_closeKbd(void); - /* events for the QSPY event loop... */ typedef enum { QSPY_NO_EVT, @@ -67,12 +47,6 @@ typedef enum { QSPY_ERROR_EVT } QSPYEvtType; -/* QP/Spy protocol constants */ -#define QS_FRAME 0x7EU -#define QS_ESC 0x7DU -#define QS_ESC_XOR 0x20U -#define QS_GOOD_CHKSUM 0xFFU - /* The PAL "virtual table" contains operations that are dependent * on the choice of target connection. This connection is chosen * by command-line options and is established by calling one of the @@ -86,6 +60,29 @@ typedef struct { extern PAL_VtblType PAL_vtbl; +/* typedefs needed for qpc_qs.h */ +typedef int int_t; +typedef int enum_t; +typedef float float32_t; +typedef double float64_t; + +QSpyStatus PAL_openBE(int portNum); /* open Back-End socket */ +void PAL_closeBE(void); /* close Back-End socket */ +void PAL_send2FE(unsigned char const *buf, uint32_t nBytes); /* to Front-End */ +void PAL_detachFE(void); /* detach Front-End */ +void PAL_clearScreen(void); + +QSpyStatus PAL_openTargetSer(char const *comName, int baudRate); +QSpyStatus PAL_openTargetTcp(int portNum); +QSpyStatus PAL_openTargetFile(char const *fName); + +QSpyStatus PAL_openKbd(bool kbd_inp, bool color); +void PAL_closeKbd(void); + +QSPYEvtType PAL_receiveBe (unsigned char *buf, uint32_t *pBytes); +QSPYEvtType PAL_receiveKbd(unsigned char *buf, uint32_t *pBytes); +void PAL_updateReadySet(int targetConn); + #ifdef __cplusplus } #endif diff --git a/qspy/include/qs_copy.h b/qspy/include/qpc_qs.h similarity index 81% rename from qspy/include/qs_copy.h rename to qspy/include/qpc_qs.h index 92170ab..ffd10eb 100644 --- a/qspy/include/qs_copy.h +++ b/qspy/include/qpc_qs.h @@ -1,41 +1,34 @@ -/** -* @file -* @brief QS/C platform-independent public interface. -* @ingroup qs qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.2 -* Last updated on 2021-01-12 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2002-2020 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QS/C platform-independent public interface. +* @ingroup qs qpspy */ #ifndef QS_H #define QS_H @@ -44,9 +37,8 @@ #error "Q_SPY must be defined to include qs.h" #endif -/****************************************************************************/ -/*! Quantum Spy record types. */ -/** +/*==========================================================================*/ +/*! QS pre-defined record types (TX channel) * @description * This enumeration specifies the record types used in the QP components. * You can specify your own record types starting from ::QS_USER offset. @@ -161,39 +153,17 @@ enum QSpyRecords { QS_ASSERT_FAIL, /*!< assertion failed in the code */ QS_QF_RUN, /*!< QF_run() was entered */ - /* [71] Reserved QS records */ - QS_RESERVED_71, - QS_RESERVED_72, - QS_RESERVED_73, - QS_RESERVED_74, - QS_RESERVED_75, - QS_RESERVED_76, - QS_RESERVED_77, - QS_RESERVED_78, - QS_RESERVED_79, - QS_RESERVED_80, - QS_RESERVED_81, - QS_RESERVED_82, - QS_RESERVED_83, - QS_RESERVED_84, - QS_RESERVED_85, - QS_RESERVED_86, - QS_RESERVED_87, - QS_RESERVED_88, - QS_RESERVED_89, - QS_RESERVED_90, - QS_RESERVED_91, - QS_RESERVED_92, - QS_RESERVED_93, - QS_RESERVED_94, - QS_RESERVED_95, - QS_RESERVED_96, - QS_RESERVED_97, - QS_RESERVED_98, - QS_RESERVED_99, - - /* [100] Application-specific (User) QS records */ - QS_USER /*!< the first record available to QS users */ + QS_MAX, /*!< the number of reserved signals */ +}; + +/*! QS user record group offsets for QS_GLB_FILTER() */ +enum QSpyUserOffsets { + QS_USER = 100, /*!< the first record available to QS users */ + QS_USER0 = (enum_t)QS_USER, /*!< offset for User Group 0 */ + QS_USER1 = (enum_t)QS_USER0 + 5, /*!< offset for User Group 1 */ + QS_USER2 = (enum_t)QS_USER1 + 5, /*!< offset for User Group 2 */ + QS_USER3 = (enum_t)QS_USER2 + 5, /*!< offset for User Group 3 */ + QS_USER4 = (enum_t)QS_USER3 + 5 /*!< offset for User Group 4 */ }; /*! QS record groups for QS_GLB_FILTER() */ @@ -214,15 +184,6 @@ enum QSpyRecordGroups { QS_UA_RECORDS /*!< All User records */ }; -/*! QS user record group offsets for QS_GLB_FILTER() */ -enum QSpyUserOffsets { - QS_USER0 = (enum_t)QS_USER, /*!< offset for User Group 0 */ - QS_USER1 = (enum_t)QS_USER0 + 5, /*!< offset for User Group 1 */ - QS_USER2 = (enum_t)QS_USER1 + 5, /*!< offset for User Group 2 */ - QS_USER3 = (enum_t)QS_USER2 + 5, /*!< offset for User Group 3 */ - QS_USER4 = (enum_t)QS_USER3 + 5 /*!< offset for User Group 4 */ -}; - /*! QS ID offsets for QS_LOC_FILTER() */ enum QSpyIdOffsets { QS_AO_ID = 0, /*!< offset for AO priorities */ @@ -240,12 +201,13 @@ enum QSpyIdGroups { QS_AP_IDS = (0x80 + (enum_t)QS_AP_ID), /*!< Application-specific IDs */ }; +/*! QSpy ID type for applying local filtering */ +typedef struct { uint8_t prio; } QSpyId; + #ifndef QS_TIME_SIZE /*! The size [bytes] of the QS time stamp. Valid values: 1U, 2U, or 4U; * default 4U. - */ - /** * @description * This macro can be defined in the QS port file (qs_port.h) to * configure the ::QSTimeCtr type. Here the macro is not defined so the @@ -272,87 +234,137 @@ enum QSpyIdGroups { #error "QS_TIME_SIZE defined incorrectly, expected 1, 2, or 4" #endif +/*==========================================================================*/ +/*! QS software tracing facilities +* @description +* This class groups together QS services. It has only static members and +* should not be instantiated. +*/ +typedef struct { + uint8_t dummy; +} QS; -/****************************************************************************/ -/* QS services. */ - -/*! Initialize the QS data buffer. */ +/*! Initialize the QS data buffer. +* @static @public @memberof QS +*/ void QS_initBuf(uint8_t sto[], uint_fast16_t stoSize); -/*! Set/clear the global Filter for a given QS record or group of records. */ +/*! Set/clear the global Filter for a given QS record or group of records. +* @static @private @memberof QS +*/ void QS_glbFilter_(int_fast16_t const filter); -/*! Set/clear the local Filter for a given object-id or group of object-ids.*/ +/*! Set/clear the local Filter for a given object-id or group of object-ids. +* @static @private @memberof QS +*/ void QS_locFilter_(int_fast16_t const filter); -/*! Mark the begin of a QS record @p rec */ +/*! Mark the begin of a QS record @p rec +* @static @private @memberof QS +*/ void QS_beginRec_(uint_fast8_t rec); -/*! Mark the end of a QS record @p rec */ +/*! Mark the end of a QS record @p rec +* @static @private @memberof QS +*/ void QS_endRec_(void); /* unformatted (raw) data elements output ..................................*/ -/*! output raw uint8_t data element (without format information) */ +/*! output raw uint8_t data element (without format information) +* @static @private @memberof QS +*/ void QS_u8_raw_(uint8_t d); -/*! output two raw uint8_t data elements (without format information) */ +/*! output two raw uint8_t data elements (without format information) +* @static @private @memberof QS +*/ void QS_2u8_raw_(uint8_t d1, uint8_t d2); -/*! Output raw uint16_t data element (without format information) */ +/*! Output raw uint16_t data element (without format information) +* @static @private @memberof QS +*/ void QS_u16_raw_(uint16_t d); -/*! Output raw uint32_t data element (without format information) */ +/*! Output raw uint32_t data element (without format information) +* @static @private @memberof QS +*/ void QS_u32_raw_(uint32_t d); -/*! Output raw zero-terminated string element (without format information) */ -void QS_str_raw_(char_t const *str); +/*! Output raw zero-terminated string element (without format information) +* @static @private @memberof QS +*/ +void QS_str_raw_(char const *str); /* formatted data elements output ..........................................*/ -/*! Output uint8_t data element with format information */ +/*! Output uint8_t data element with format information +* @static @private @memberof QS +*/ void QS_u8_fmt_(uint8_t format, uint8_t d); -/*! output uint16_t data element with format information */ +/*! output uint16_t data element with format information +* @static @private @memberof QS +*/ void QS_u16_fmt_(uint8_t format, uint16_t d); -/*! Output uint32_t data element with format information */ +/*! Output uint32_t data element with format information +* @static @private @memberof QS +*/ void QS_u32_fmt_(uint8_t format, uint32_t d); -/*! Output 32-bit floating point data element with format information */ +/*! Output 32-bit floating point data element with format information +* @static @private @memberof QS +*/ void QS_f32_fmt_(uint8_t format, float32_t f); -/*! Output 64-bit floating point data element with format information */ +/*! Output 64-bit floating point data element with format information +* @static @private @memberof QS +*/ void QS_f64_fmt_(uint8_t format, float64_t d); -/*! Output obj pointer data element without format information */ +/*! Output obj pointer data element without format information +* @static @private @memberof QS +*/ void QS_obj_raw_(void const * const obj); -/*! Output zero-terminated ASCII string element with format information */ -void QS_str_fmt_(char_t const *str); +/*! Output zero-terminated ASCII string element with format information +* @static @private @memberof QS +*/ +void QS_str_fmt_(char const *str); -/*! Output memory block of up to 255-bytes with format information */ +/*! Output memory block of up to 255-bytes with format information +* @static @private @memberof QS +*/ void QS_mem_fmt_(uint8_t const *blk, uint8_t size); -/*! Output raw uint64_t data element without format information */ +/*! Output raw uint64_t data element without format information +* @static @private @memberof QS +*/ void QS_u64_raw_(uint64_t d); -/*! Output uint64_t data element with format information */ +/*! Output uint64_t data element with format information +* @static @private @memberof QS +*/ void QS_u64_fmt_(uint8_t format, uint64_t d); /* QS buffer access *********************************************************/ -/*! Byte-oriented interface to the QS data buffer. */ +/*! Byte-oriented interface to the QS data buffer. +* @static @public @memberof QS +*/ uint16_t QS_getByte(void); /*! Constant for End-Of-Data condition returned from QS_getByte() */ #define QS_EOD ((uint16_t)0xFFFFU) -/*! Block-oriented interface to the QS data buffer. */ +/*! Block-oriented interface to the QS data buffer. +* @static @public @memberof QS +*/ uint8_t const *QS_getBlock(uint16_t *pNbytes); /* platform-specific callback functions, need to be implemented by clients */ -/*! Callback to startup the QS facility */ -/** +/*! Callback to startup the QS facility +* @static @public @memberof QS * @description * This is a platform-dependent "callback" function invoked through the macro * QS_INIT(). You need to implement this function in your application. @@ -370,8 +382,8 @@ uint8_t const *QS_getBlock(uint16_t *pNbytes); */ uint8_t QS_onStartup(void const *arg); -/*! Callback to cleanup the QS facility */ -/** +/*! Callback to cleanup the QS facility +* @static @public @memberof QS * @description * This is a platform-dependent "callback" function invoked through the macro * QS_EXIT(). You need to implement this function in your application. @@ -380,8 +392,8 @@ uint8_t QS_onStartup(void const *arg); */ void QS_onCleanup(void); -/*! Callback to flush the QS trace data to the host */ -/** +/*! Callback to flush the QS trace data to the host +* @static @public @memberof QS * @description * This is a platform-dependent "callback" function to flush the QS trace * buffer to the host. The function typically busy-waits until all the data @@ -390,8 +402,8 @@ void QS_onCleanup(void); */ void QS_onFlush(void); -/*! Callback to obtain a timestamp for a QS record. */ -/** +/*! Callback to obtain a timestamp for a QS record. +* @static @public @memberof QS * @description * This is a platform-dependent "callback" function invoked from the macro * QS_TIME_PRE_() to add the time stamp to a QS record. @@ -410,12 +422,10 @@ void QS_onFlush(void); */ QSTimeCtr QS_onGetTime(void); - -/****************************************************************************/ +/*==========================================================================*/ /* Macros for adding QS instrumentation to the client code */ -/*! Initialize the QS facility. */ -/** +/*! Initialize the QS facility. * @description * This macro provides an indirection layer to invoke the QS initialization * routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. @@ -423,8 +433,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_INIT(arg_) (QS_onStartup(arg_)) -/*! Cleanup the QS facility. */ -/** +/*! Cleanup the QS facility. * @description * This macro provides an indirection layer to invoke the QS cleanup * routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. @@ -432,8 +441,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_EXIT() (QS_onCleanup()) -/*! Flush the QS trace data to the host */ -/** +/*! Flush the QS trace data to the host. * @description * This macro invokes the QS_flush() platform-dependent callback function * to flush the QS trace buffer to the host. The function typically @@ -442,8 +450,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_FLUSH() (QS_onFlush()) -/*! Global Filter for a given record type @p rec. */ -/** +/*! Global Filter for a given record type @p rec * @description * This macro provides an indirection layer to call QS_glbFilter_() * if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. @@ -453,8 +460,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_))) -/*! Local Filter for a given object-id @p qs_id. */ -/** +/*! Local Filter for a given object-id @p qs_id * @description * This macro provides an indirection layer to call QS_locFilter_() * if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. @@ -464,8 +470,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_LOC_FILTER(qs_id_) (QS_locFilter_((int_fast16_t)(qs_id_))) - -/****************************************************************************/ +/*==========================================================================*/ /* Facilities for QS ciritical section */ /* QS-specific critical section */ @@ -485,8 +490,7 @@ QSTimeCtr QS_onGetTime(void); #ifndef QF_CRIT_STAT_TYPE /*! This is an internal macro for defining the critical section - * status type. */ - /** + * status type. * @description * The purpose of this macro is to enable writing the same code for the * case when critical section status type is defined and when it is not. @@ -497,8 +501,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_CRIT_STAT_ - /*! This is an internal macro for entering a critical section. */ - /** + /*! This is an internal macro for entering a critical section. * @description * The purpose of this macro is to enable writing the same code for the * case when critical section status type is defined and when it is not. @@ -509,8 +512,7 @@ QSTimeCtr QS_onGetTime(void); */ #define QS_CRIT_E_() QF_CRIT_ENTRY(dummy) - /*! This is an internal macro for exiting a critical section. */ - /** + /*! This is an internal macro for exiting a critical section. * @description * The purpose of this macro is to enable writing the same code for the * case when critical section status type is defined and when it is not. @@ -531,8 +533,7 @@ QSTimeCtr QS_onGetTime(void); #endif /* separate QS critical section not defined */ - -/****************************************************************************/ +/*==========================================================================*/ /* Macros to generate application-specific (user) QS records */ /*! Begin a QS user record without entering critical section. */ @@ -562,8 +563,7 @@ QSTimeCtr QS_onGetTime(void); & ((uint_fast8_t)1U << ((uint_fast8_t)(qs_id_) & 7U))) != 0U) /*! Begin an application-specific (user) QS record with object-id - * for the local filter. */ -/** + * for the local filter. * @usage * The following example shows how to build a user QS record using the * macros QS_BEGIN_ID(), QS_END(), and the formatted output macros: @@ -578,8 +578,8 @@ QSTimeCtr QS_onGetTime(void); QS_beginRec_((uint_fast8_t)(rec_)); \ QS_TIME_PRE_(); { -/*! End a QS record with exiting critical section. */ -/** @sa example for QS_BEGIN_ID() +/*! End a QS record with exiting critical section. +* @sa example for QS_BEGIN_ID() * @note Must always be used in pair with QS_BEGIN_ID() */ #define QS_END() } \ @@ -587,8 +587,7 @@ QSTimeCtr QS_onGetTime(void); QS_CRIT_X_(); \ } -/*! formats for application-specific data elements */ -/** +/*! formats for application-specific data elements * @description * QS uses this enumeration is used only internally for the formatted user * data elements. @@ -659,7 +658,7 @@ enum { #define QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_))) -#if (QS_OBJ_PTR_SIZE == 1U) +#if (!defined QS_OBJ_PTR_SIZE || (QS_OBJ_PTR_SIZE == 1U)) #define QS_OBJ(obj_) (QS_u8_fmt_(QS_OBJ_T, (uint8_t)(obj_))) #elif (QS_OBJ_PTR_SIZE == 2U) #define QS_OBJ(obj_) (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_))) @@ -673,7 +672,7 @@ enum { #endif -#if (QS_FUN_PTR_SIZE == 1U) +#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 1U)) #define QS_FUN(fun_) (QS_u8_fmt_(QS_FUN_T, (uint8_t)(fun_))) #elif (QS_FUN_PTR_SIZE == 2U) #define QS_FUN(fun_) (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_))) @@ -686,7 +685,7 @@ enum { #define QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) #endif -#if (Q_SIGNAL_SIZE == 1) +#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1)) #define QS_SIG(sig_, obj_) \ QS_u8_fmt_(QS_SIG_T, (sig_)); \ @@ -714,12 +713,10 @@ enum { #endif - -/****************************************************************************/ +/*==========================================================================*/ /* Dictionary trace records */ -/*! Output signal dictionary record */ -/** +/*! Output signal dictionary record * @description * A signal dictionary record associates the numerical value of the signal * and the binary address of the state machine that consumes that signal @@ -762,8 +759,7 @@ enum { #define QS_SIG_DICTIONARY(sig_, obj_) \ (QS_sig_dict_pre_((sig_), (obj_), #sig_)) -/*! Output object dictionary record */ -/** +/*! Output object dictionary record * @description * An object dictionary record associates the binary address of an object * in the target's memory with the human-readable name of the object. @@ -779,8 +775,7 @@ enum { #define QS_OBJ_DICTIONARY(obj_) \ (QS_obj_dict_pre_((obj_), #obj_)) -/*! Output function dictionary record */ -/** +/*! Output function dictionary record * @description * A function dictionary record associates the binary address of a function * in the target's memory with the human-readable name of the function. @@ -795,8 +790,7 @@ enum { #define QS_FUN_DICTIONARY(fun_) \ (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) -/*! Output user QS-record dictionary record */ -/** +/*! Output user QS-record dictionary record * @description * A user QS-record dictionary record associates the numerical value of a * user record with the human-readable identifier. @@ -804,52 +798,65 @@ enum { #define QS_USR_DICTIONARY(rec_) \ (QS_usr_dict_pre_((rec_), #rec_)) -/*! Output predefined signal-dictionary record */ +/*! Output predefined signal-dictionary record +* @static @private @memberof QS +*/ void QS_sig_dict_pre_(enum_t const sig, void const * const obj, - char_t const *name); + char const *name); -/*! Output predefined object-dictionary record */ +/*! Output predefined object-dictionary record +* @static @private @memberof QS +*/ void QS_obj_dict_pre_(void const * const obj, - char_t const *name); + char const *name); -/*! Output predefined function-dictionary record */ +/*! Output predefined function-dictionary record +* @static @private @memberof QS +*/ void QS_fun_dict_pre_(void (* const fun)(void), - char_t const *name); + char const *name); -/*! Output predefined user-dictionary record */ +/*! Output predefined user-dictionary record +* @static @private @memberof QS +*/ void QS_usr_dict_pre_(enum_t const rec, - char_t const * const name); - + char const * const name); -/****************************************************************************/ +/*==========================================================================*/ /* Miscellaneous pre-formatted trace records used in applications */ -/*! Output the assertion failure trace record */ -/** +/*! Output the assertion failure trace record * @description * This trace record is intended to use from the Q_onAssert() callback. */ -void QS_ASSERTION(char_t const * const module, +void QS_ASSERTION(char const * const module, int_t const loc, uint32_t delay); -/*! Output the critical section entry */ +/*! Output the critical section entry +* @static @private @memberof QS +*/ void QF_QS_CRIT_ENTRY(void); -/*! Output the critical section exit */ +/*! Output the critical section exit +* @static @private @memberof QS +*/ void QF_QS_CRIT_EXIT(void); -/*! Output the interrupt entry record */ +/*! Output the interrupt entry record +* @static @private @memberof QS +*/ void QF_QS_ISR_ENTRY(uint8_t const isrnest, uint8_t const prio); -/*! Output the interrupt exit record */ +/*! Output the interrupt exit record +* @static @private @memberof QS +*/ void QF_QS_ISR_EXIT(uint8_t const isrnest, uint8_t const prio); /*! Execute an action that is only necessary for QS output */ #define QF_QS_ACTION(act_) (act_) - -/****************************************************************************/ +/*==========================================================================*/ /* QS private data (the TX channel) */ typedef uint_fast16_t QSCtr; /*!< QS ring buffer counter and offset type */ @@ -886,53 +893,47 @@ typedef struct { extern QSPrivAttr QS_priv_; - -/****************************************************************************/ +/*==========================================================================*/ /* QS receive channel */ -/*! Enumeration for the received Qs record types (RX channel). */ -enum QSpyRxRecords { - QS_RX_INFO, /*!< query Target info (ver, config, tstamp) */ - QS_RX_COMMAND, /*!< execute a user-defined command in the Target */ - QS_RX_RESET, /*!< reset the Target */ - QS_RX_TICK, /*!< call QF_TICK_X() in the Target */ - QS_RX_PEEK, /*!< peek Target memory */ - QS_RX_POKE, /*!< poke Target memory */ - QS_RX_FILL, /*!< fill Target memory */ - QS_RX_TEST_SETUP, /*!< test setup */ - QS_RX_TEST_TEARDOWN, /*!< test teardown */ - QS_RX_TEST_PROBE, /*!< set a Test-Probe in the Target */ - QS_RX_GLB_FILTER, /*!< set global filters in the Target */ - QS_RX_LOC_FILTER, /*!< set local filters in the Target */ - QS_RX_AO_FILTER, /*!< set local AO filter in the Target */ - QS_RX_CURR_OBJ, /*!< set the "current-object" in the Target */ - QS_RX_TEST_CONTINUE, /*!< continue a test after QS_TEST_PAUSE() */ - QS_RX_QUERY_CURR, /*!< query the "current object" in the Target */ - QS_RX_EVENT /*!< inject an event to the Target */ -}; - -/*! Initialize the QS RX data buffer. */ +/*! Initialize the QS RX data buffer. +* @static @public @memberof QS +*/ void QS_rxInitBuf(uint8_t sto[], uint16_t stoSize); -/*! Parse all bytes present in the QS RX data buffer */ +/*! Parse all bytes present in the QS RX data buffer +* @static @public @memberof QS +*/ void QS_rxParse(void); -/*! Put one byte into the QS RX lock-free buffer */ +/*! Put one byte into the QS RX lock-free buffer +* @static @public @memberof QS +*/ bool QS_RX_PUT(uint8_t const b); -/*! Obtain the number of free bytes in the QS RX data buffer */ +/*! Obtain the number of free bytes in the QS RX data buffer +* @static @public @memberof QS +*/ uint16_t QS_rxGetNfree(void); -/*! Set the "current object" in the Target */ +/*! Set the "current object" in the Target +* @static @public @memberof QS +*/ void QS_setCurrObj(uint8_t obj_kind, void *obj_ptr); -/*! Query the "current object" in the Target */ +/*! Query the "current object" in the Target +* @static @public @memberof QS +*/ void QS_queryCurrObj(uint8_t obj_kind); -/*! Callback function to reset the Target (to be implemented in the BSP) */ +/*! Callback function to reset the Target (to be implemented in the BSP) +* @static @public @memberof QS +*/ void QS_onReset(void); -/*! Callback function to execute user commands (to be implemented in BSP) */ +/*! Callback function to execute user commands (to be implemented in BSP) +* @static @public @memberof QS +*/ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3); @@ -946,32 +947,46 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, */ #define QS_RX_INPUT() (QS_rx_input()) -/****************************************************************************/ +/*==========================================================================*/ /* Facilities for use in QUTest only */ #ifdef Q_UTEST /*! callback to setup a unit test inside the Target */ void QS_onTestSetup(void); - /*! callback to teardown after a unit test inside the Target */ + /*! callback to teardown after a unit test inside the Target + * @static @public @memberof QS + */ void QS_onTestTeardown(void); - /*! callback to run the test loop */ + /*! callback to run the test loop + * @static @public @memberof QS + */ void QS_onTestLoop(void); - /*! callback to "massage" the test event before dispatching/posting it */ + /*! callback to "massage" the test event before dispatching/posting it + * @static @public @memberof QS + */ void QS_onTestEvt(QEvt *e); - /*! callback to examine an event that is about to be posted */ + /*! callback to examine an event that is about to be posted + * @static @public @memberof QS + */ void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status); - /*! QS internal function to process posted events during test */ + /*! QS internal function to process posted events during test + * @static @public @memberof QS + */ void QS_processTestEvts_(void); - /*! internal function to process armed time events during test */ + /*! internal function to process armed time events during test + * @static @public @memberof QS + */ void QS_tickX_(uint_fast8_t const tickRate, void const * const sender); - /*! QS internal function to get the Test-Probe for a given API */ + /*! QS internal function to get the Test-Probe for a given API + * @static @public @memberof QS + */ uint32_t QS_getTestProbe_(void (* const api)(void)); /*! QS macro to define the Test-Probe for a given @p fun_ */ @@ -987,11 +1002,12 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, if (qs_tp_ == (uint32_t)(id_)) { code_ } /*! QS macro to pause test execution and enter the test event loop */ - #define QS_TEST_PAUSE() do { \ - QS_beginRec_((uint_fast8_t)QS_TEST_PAUSED); \ - QS_endRec_(); \ - QS_onTestLoop(); \ - } while (false) + #define QS_TEST_PAUSE() (QS_test_pause_()) + + /*! QS internal function to pause test and enter the test event loop + * @static @private @memberof QS + */ + void QS_test_pause_(void); enum QUTestUserRecords { QUTEST_ON_POST = 124 @@ -1000,9 +1016,7 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, /* interrupt nesting up-down counter */ extern uint8_t volatile QF_intNest; - /************************************************************************/ - /*! QActiveDummy Object class */ - /** + /*! QActiveDummy Object class * @description * QActiveDummy is a test double for the role of collaborating active * objects in QUTest unit testing. @@ -1011,7 +1025,9 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, QActive super; /*< inherit QActive */ } QActiveDummy; - /*! Constructor of the QActiveDummy Active Object class */ + /*! Constructor of the QActiveDummy Active Object class + * @public @memberof QActiveDummy + */ void QActiveDummy_ctor(QActiveDummy * const me); #else /* Q_UTEST not defined */ @@ -1025,4 +1041,3 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, #endif /* Q_UTEST */ #endif /* QS_H */ - diff --git a/qspy/include/qpc_qs_pkg.h b/qspy/include/qpc_qs_pkg.h new file mode 100644 index 0000000..7dc864e --- /dev/null +++ b/qspy/include/qpc_qs_pkg.h @@ -0,0 +1,293 @@ +/*============================================================================ +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of open-source GPL 3.0 +* (or any later version), or alternatively, under the terms of one of the +* closed-source Quantum Leaps commercial licenses. +* +* The terms of the open source GPL 3.0 license can be found at: +* +* +* The terms of the closed-source Quantum Leaps commercial licenses +* can be found at: +* +* +* NOTE: Please do NOT plagiarize this software to sidestep the license +* obligations. This is both unfair and illegal. +* +* Contact information: +* +* +============================================================================*/ +/** +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @ingroup qs +* @brief Internal (package scope) QS/C interface. +*/ +#ifndef QS_PKG_H +#define QS_PKG_H + +/*==========================================================================*/ + +/*! QS received record types (RX channel) +* @description +* This enumeration specifies the record types for the QS receive channel +*/ +enum QSpyRxRecords { + QS_RX_INFO, /*!< query Target info (ver, config, tstamp) */ + QS_RX_COMMAND, /*!< execute a user-defined command in the Target */ + QS_RX_RESET, /*!< reset the Target */ + QS_RX_TICK, /*!< call QF_TICK_X() in the Target */ + QS_RX_PEEK, /*!< peek Target memory */ + QS_RX_POKE, /*!< poke Target memory */ + QS_RX_FILL, /*!< fill Target memory */ + QS_RX_TEST_SETUP, /*!< test setup */ + QS_RX_TEST_TEARDOWN, /*!< test teardown */ + QS_RX_TEST_PROBE, /*!< set a Test-Probe in the Target */ + QS_RX_GLB_FILTER, /*!< set global filters in the Target */ + QS_RX_LOC_FILTER, /*!< set local filters in the Target */ + QS_RX_AO_FILTER, /*!< set local AO filter in the Target */ + QS_RX_CURR_OBJ, /*!< set the "current-object" in the Target */ + QS_RX_TEST_CONTINUE, /*!< continue a test after QS_TEST_PAUSE() */ + QS_RX_QUERY_CURR, /*!< query the "current object" in the Target */ + QS_RX_EVENT /*!< inject an event to the Target */ +}; + +/*==========================================================================*/ +/*! Frame character of the QS output protocol */ +#define QS_FRAME (0x7EU) + +/*! Escape character of the QS output protocol */ +#define QS_ESC (0x7DU) + +/*! The expected checksum value over an uncorrupted QS record */ +#define QS_GOOD_CHKSUM (0xFFU) + +/*! Escape modifier of the QS output protocol */ +/** +* @description +* The escaped byte is XOR-ed with the escape modifier before it is inserted +* into the QS buffer. +*/ +#define QS_ESC_XOR (0x20U) + +/*==========================================================================*/ +/*! send the predefined target info trace record + * (object sizes, build time-stamp, QP version) */ +void QS_target_info_pre_(uint8_t isReset); + +/*==========================================================================*/ +/*! Private QS-RX attributes to keep track of the current objects and +* the lock-free RX buffer +*/ +typedef struct { + void *currObj[MAX_OBJ]; /*!< current objects */ + uint8_t *buf; /*!< pointer to the start of the ring buffer */ + QSCtr end; /*!< offset of the end of the ring buffer */ + QSCtr head; /*!< offset to where next byte will be inserted */ + QSCtr tail; /*!< offset of where next byte will be extracted */ +#ifdef Q_UTEST + QPSet readySet; /*!< QUTEST ready-set of active objects */ + bool inTestLoop; /*!< QUTEST event loop is running */ +#endif +} QSrxPrivAttr; + +extern QSrxPrivAttr QS_rxPriv_; /* QS-RX private attributes */ + +/*==========================================================================*/ +/*! Internal QS macro to begin a predefined QS record with +* entering critical section. */ +/** +* @note This macro is intended to use only inside QP components and NOT +* at the application level. +* @sa QS_BEGIN_ID() +*/ +#define QS_BEGIN_PRE_(rec_, qs_id_) \ + if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ + QS_CRIT_E_(); \ + QS_beginRec_((uint_fast8_t)(rec_)); + +/*! Internal QS macro to end a predefined QS record with +* exiting critical section. */ +/** +* @note This macro is intended to use only inside QP components and NOT +* at the application level. +* @sa QS_END() +*/ +#define QS_END_PRE_() \ + QS_endRec_(); \ + QS_CRIT_X_(); \ + } + +/*! Internal macro to begin a predefined QS record without +* entering critical section. */ +/** +* @note This macro is intended to use only inside QP components and NOT +* at the application level. +* @sa QS_BEGIN_NOCRIT() +*/ +#define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_) \ + if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ + QS_beginRec_((uint_fast8_t)(rec_)); + +/*! Internal QS macro to end a predefined QS record without +* exiting critical section. */ +/** +* @note This macro is intended to use only inside QP components and NOT +* at the application level. @sa #QS_END_NOCRIT +*/ +#define QS_END_NOCRIT_PRE_() QS_endRec_(); } + +/*! Internal QS macro to output a predefined uint8_t data element */ +#define QS_U8_PRE_(data_) (QS_u8_raw_((uint8_t)(data_))) + +/*! Internal QS macro to output 2 predefined uint8_t data elements */ +#define QS_2U8_PRE_(data1_, data2_) \ + (QS_2u8_raw_((uint8_t)(data1_), (uint8_t)(data2_))) + +/*! Internal QS macro to output an predefined uint16_t data element */ +#define QS_U16_PRE_(data_) (QS_u16_raw_((uint16_t)(data_))) + +/*! Internal QS macro to output a predefined uint32_t data element */ +#define QS_U32_PRE_(data_) (QS_u32_raw_((uint32_t)(data_))) + +/*! Internal QS macro to output a predefined zero-terminated string element */ +#define QS_STR_PRE_(msg_) (QS_str_raw_((msg_))) + + +#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U)) + /*! Internal macro to output an unformatted event signal data element */ + /** + * @note the size of the pointer depends on the macro #Q_SIGNAL_SIZE. + */ + #define QS_SIG_PRE_(sig_) (QS_u8_raw_((uint8_t)sig_)) +#elif (Q_SIGNAL_SIZE == 2U) + #define QS_SIG_PRE_(sig_) (QS_u16_raw_((uint16_t)sig_)) +#elif (Q_SIGNAL_SIZE == 4U) + #define QS_SIG_PRE_(sig_) (QS_u32_raw_((uint32_t)sig_)) +#endif + +#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) + +#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 1U)) + #define QS_FUN_PRE_(fun_) (QS_u8_raw_((uint8_t)(fun_))) +#elif (QS_FUN_PTR_SIZE == 2U) + #define QS_FUN_PRE_(fun_) (QS_u16_raw_((uint16_t)(fun_))) +#elif (QS_FUN_PTR_SIZE == 4U) + #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) +#elif (QS_FUN_PTR_SIZE == 8U) + #define QS_FUN_PRE_(fun_) (QS_u64_raw_((uint64_t)(fun_))) +#else + /*! Internal macro to output an unformatted function pointer */ + /** @note the size of the pointer depends on the macro #QS_FUN_PTR_SIZE. + * If the size is not defined the size of pointer is assumed 4-bytes. + */ + #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) +#endif + +/*==========================================================================*/ +#if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U)) + + /*! Internal QS macro to output an unformatted event queue counter + * data element. */ + /** + * @note the counter size depends on the macro #QF_EQUEUE_CTR_SIZE. + */ + #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) +#elif (QF_EQUEUE_CTR_SIZE == 2U) + #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) +#elif (QF_EQUEUE_CTR_SIZE == 4U) + #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) +#endif + + +#if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U)) + + /*! Internal QS macro to output an unformatted event size + * data element. */ + /** + * @note the event size depends on the macro #QF_EVENT_SIZ_SIZE. + */ + #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) +#elif (QF_EVENT_SIZ_SIZE == 2U) + #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) +#elif (QF_EVENT_SIZ_SIZE == 4U) + #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) +#endif + + +#if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U)) + + /*! Internal QS macro to output an unformatted memory pool + * block-size data element */ + /** + * @note the block-size depends on the macro #QF_MPOOL_SIZ_SIZE. + */ + #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) +#elif (QF_MPOOL_SIZ_SIZE == 2U) + #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) +#elif (QF_MPOOL_SIZ_SIZE == 4U) + #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) +#endif + +#if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U)) + + /*! Internal QS macro to output an unformatted memory pool + * block-counter data element. */ + /** + * @note the counter size depends on the macro #QF_MPOOL_CTR_SIZE. + */ + #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) +#elif (QF_MPOOL_CTR_SIZE == 2U) + #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) +#elif (QF_MPOOL_CTR_SIZE == 4U) + #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) +#endif + + +#if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U)) + + /*! Internal QS macro to output an unformatted time event + * tick-counter data element */ + /** + * @note the counter size depends on the macro #QF_TIMEEVT_CTR_SIZE. + */ + #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) +#elif (QF_TIMEEVT_CTR_SIZE == 2U) + #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) +#elif (QF_TIMEEVT_CTR_SIZE == 4U) + #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) +#endif + +/*==========================================================================*/ +/*! Internal QS macro to insert an un-escaped byte into the QS buffer */ +#define QS_INSERT_BYTE_(b_) \ + buf[head] = (b_); \ + ++head; \ + if (head == end) { \ + head = 0U; \ + } + +/*! Internal QS macro to insert an escaped byte into the QS buffer */ +#define QS_INSERT_ESC_BYTE_(b_) \ + chksum = (uint8_t)(chksum + (b_)); \ + if (((b_) != QS_FRAME) && ((b_) != QS_ESC)) { \ + QS_INSERT_BYTE_(b_) \ + } \ + else { \ + QS_INSERT_BYTE_(QS_ESC) \ + QS_INSERT_BYTE_((uint8_t)((b_) ^ QS_ESC_XOR))\ + ++QS_priv_.used; \ + } + +#endif /* QS_PKG_H */ diff --git a/qspy/include/qspy.h b/qspy/include/qspy.h index d725d56..e23cc0f 100644 --- a/qspy/include/qspy.h +++ b/qspy/include/qspy.h @@ -1,46 +1,39 @@ -/** -* @file -* @brief Host API -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief Host API +* @ingroup qpspy */ #ifndef QSPY_H #define QSPY_H -#define QSPY_VER "6.9.4" +#define QSPY_VER "7.0.0" #ifdef __cplusplus extern "C" { @@ -52,23 +45,6 @@ typedef enum { QSPY_SUCCESS } QSpyStatus; -/*! commands to QSPY; @sa "packet IDs" in qspy.tcl script */ -typedef enum { - QSPY_ATTACH = 128, /*!< attach to the QSPY Back-End */ - QSPY_DETACH, /*!< detach from the QSPY Back-End */ - QSPY_SAVE_DICT, /*!< save dictionaries to a file in QSPY */ - QSPY_SCREEN_OUT, /*!< toggle screen output to a file in QSPY */ - QSPY_BIN_OUT, /*!< toggle binary output to a file in QSPY */ - QSPY_MATLAB_OUT, /*!< toggle Matlab output to a file in QSPY */ - QSPY_SEQUENCE_OUT, /*!< toggle Sequence output to a file in QSPY */ - QSPY_SEND_EVENT, /*!< send event (QSPY supplying signal) */ - QSPY_SEND_AO_FILTER, /*!< send Local Filter (QSPY supplying addr) */ - QSPY_SEND_CURR_OBJ, /*!< send current Object (QSPY supplying addr) */ - QSPY_SEND_COMMAND, /*!< send command (QSPY supplying cmdId) */ - QSPY_SEND_TEST_PROBE /*!< send Test-Probe (QSPY supplying apiId) */ - /* ... */ -} QSpyCommands; - /*! QSPY record being processed */ typedef struct { uint8_t const *start; /*!< start of the record */ @@ -78,26 +54,6 @@ typedef struct { uint8_t rec; /*!< the record-ID (see enum QSpyRecords in qs.h) */ } QSpyRecord; -/*! QSPY configuration parameters. @sa QSPY_config() */ -typedef struct { - uint16_t version; - uint8_t endianness; - uint8_t objPtrSize; - uint8_t funPtrSize; - uint8_t tstampSize; - uint8_t sigSize; - uint8_t evtSize; - uint8_t queueCtrSize; - uint8_t poolCtrSize; - uint8_t poolBlkSize; - uint8_t tevtCtrSize; - uint8_t tstamp[6]; -} QSpyConfig; - -typedef uint64_t KeyType; -typedef uint32_t SigType; -typedef uint64_t ObjType; - /* limits */ enum { QS_RECORD_SIZE_MAX = 512, /* max QS record size [bytes] */ @@ -124,6 +80,26 @@ uint8_t const *QSpyRecord_getMem(QSpyRecord * const me, uint32_t *pNum); /* QSPY configuration and high-level interface .............................*/ +/*! QSPY configuration parameters. @sa QSPY_config() */ +typedef struct { + uint16_t version; + uint8_t endianness; + uint8_t objPtrSize; + uint8_t funPtrSize; + uint8_t tstampSize; + uint8_t sigSize; + uint8_t evtSize; + uint8_t queueCtrSize; + uint8_t poolCtrSize; + uint8_t poolBlkSize; + uint8_t tevtCtrSize; + uint8_t tstamp[6]; +} QSpyConfig; + +typedef uint64_t KeyType; +typedef uint32_t SigType; +typedef uint64_t ObjType; + void QSPY_config(QSpyConfig const *config, QSPY_CustParseFun custParseFun); void QSPY_configTxReset(QSPY_resetFun txResetFun); @@ -154,7 +130,15 @@ void QSPY_cleanup(void); /* cleanup after the run */ char const* QSPY_tstampStr(void); -/* last human-readable line of output from QSPY */ +void QSPY_onPrintLn(void); /* callback to print the last line of output */ + +/* prints information message to the QSPY output (without sending it to FE) */ +void QSPY_printInfo(void); + +/* prints error message to the QSPY output (sending it to FE) */ +void QSPY_printError(void); + +/* last human-readable line of output from QSPY ............................*/ #define QS_LINE_OFFSET 8 enum QSPY_LastOutputType { REG_OUT, INF_OUT, ERR_OUT }; typedef struct { @@ -164,19 +148,67 @@ typedef struct { int type; /* the type of the output */ } QSPY_LastOutput; -extern QSPY_LastOutput QSPY_output; - -void QSPY_onPrintLn(void); /* callback to print the last line of output */ +enum QSRreRecGroup { + GRP_ERR, + GRP_INF, + GRP_DIC, + GRP_TST, + GRP_SM, + GRP_AO, + GRP_EQ, + GRP_MP, + GRP_TE, + GRP_QF, + GRP_SC, + GRP_USR +}; -/* prints information message to the QSPY output (without sending it to FE) */ -void QSPY_printInfo(void); +typedef struct { + char const *name; /* name of the record, e.g. "QS_QF_PUBLISH" */ + int const group; /* group of the record (for rendering/coloring) */ +} QSpyRecRender; -/* prints error message to the QSPY output (sending it to FE) */ -void QSPY_printError(void); +/* last output generated */ +extern QSPY_LastOutput QSPY_output; /* begining of QSPY line to print */ extern char const * const QSPY_line; +/* rendering information for QSPY records */ +extern QSpyRecRender const QSPY_rec[]; + +#define SNPRINTF_LINE(format_, ...) do { \ + int n_ = SNPRINTF_S(&QSPY_output.buf[QS_LINE_OFFSET], \ + (QS_LINE_LEN_MAX - QS_LINE_OFFSET), \ + format_, ##__VA_ARGS__); \ + if ((0 < n_) && (n_ < QS_LINE_LEN_MAX - QS_LINE_OFFSET)) { \ + QSPY_output.len = n_; \ + } \ + else { \ + QSPY_output.len = QS_LINE_LEN_MAX - QS_LINE_OFFSET; \ + } \ +} while (0) + +#define SNPRINTF_APPEND(format_, ...) do { \ + int n_ = SNPRINTF_S(&QSPY_output.buf[QS_LINE_OFFSET + QSPY_output.len],\ + (QS_LINE_LEN_MAX - QS_LINE_OFFSET - QSPY_output.len), \ + format_, ##__VA_ARGS__); \ + if ((0 < n_) \ + && (n_ < QS_LINE_LEN_MAX - QS_LINE_OFFSET - QSPY_output.len)) { \ + QSPY_output.len += n_; \ + } \ + else { \ + QSPY_output.len = QS_LINE_LEN_MAX - QS_LINE_OFFSET; \ + } \ +} while (0) + +#define CONFIG_UPDATE(member_, new_, diff_) \ + if (QSPY_conf.member_ != (new_)) { \ + QSPY_conf.member_ = (new_); \ + (diff_) = 1U; \ + } else (void)0 + +/* Dictionaries ............................................................*/ typedef struct { KeyType key; char name[QS_DNAME_LEN_MAX]; @@ -228,10 +260,27 @@ SigType SigDictionary_findSig(SigDictionary* const me, void SigDictionary_reset(SigDictionary* const me); void QSPY_resetAllDictionaries(void); -/****************************************************************************/ +/*==========================================================================*/ /* facilities used by the QSPY host app only (but not for QSPY parser) */ #ifdef QSPY_APP +/*! commands to QSPY; @sa "packet IDs" in qspy.tcl script */ +typedef enum { + QSPY_ATTACH = 128, /*!< attach to the QSPY Back-End */ + QSPY_DETACH, /*!< detach from the QSPY Back-End */ + QSPY_SAVE_DICT, /*!< save dictionaries to a file in QSPY */ + QSPY_SCREEN_OUT, /*!< toggle screen output to a file in QSPY */ + QSPY_BIN_OUT, /*!< toggle binary output to a file in QSPY */ + QSPY_MATLAB_OUT, /*!< toggle Matlab output to a file in QSPY */ + QSPY_SEQUENCE_OUT, /*!< toggle Sequence output to a file in QSPY */ + QSPY_SEND_EVENT, /*!< send event (QSPY supplying signal) */ + QSPY_SEND_AO_FILTER, /*!< send Local Filter (QSPY supplying addr) */ + QSPY_SEND_CURR_OBJ, /*!< send current Object (QSPY supplying addr) */ + QSPY_SEND_COMMAND, /*!< send command (QSPY supplying cmdId) */ + QSPY_SEND_TEST_PROBE /*!< send Test-Probe (QSPY supplying apiId) */ + /* ... */ +} QSpyCommands; + extern QSpyConfig QSPY_conf; extern Dictionary QSPY_funDict; extern Dictionary QSPY_objDict; @@ -272,35 +321,4 @@ void QSEQ_dictionaryReset(void); } #endif -#define SNPRINTF_LINE(format_, ...) do { \ - int n_ = SNPRINTF_S(&QSPY_output.buf[QS_LINE_OFFSET], \ - (QS_LINE_LEN_MAX - QS_LINE_OFFSET), \ - format_, ##__VA_ARGS__); \ - if ((0 < n_) && (n_ < QS_LINE_LEN_MAX - QS_LINE_OFFSET)) { \ - QSPY_output.len = n_; \ - } \ - else { \ - QSPY_output.len = QS_LINE_LEN_MAX - QS_LINE_OFFSET; \ - } \ -} while (0) - -#define SNPRINTF_APPEND(format_, ...) do { \ - int n_ = SNPRINTF_S(&QSPY_output.buf[QS_LINE_OFFSET + QSPY_output.len],\ - (QS_LINE_LEN_MAX - QS_LINE_OFFSET - QSPY_output.len), \ - format_, ##__VA_ARGS__); \ - if ((0 < n_) \ - && (n_ < QS_LINE_LEN_MAX - QS_LINE_OFFSET - QSPY_output.len)) { \ - QSPY_output.len += n_; \ - } \ - else { \ - QSPY_output.len = QS_LINE_LEN_MAX - QS_LINE_OFFSET; \ - } \ -} while (0) - -#define CONFIG_UPDATE(member_, new_, diff_) \ - if (QSPY_conf.member_ != (new_)) { \ - QSPY_conf.member_ = (new_); \ - (diff_) = 1U; \ - } else (void)0 - #endif /* QSPY_H */ diff --git a/qspy/include/safe_std.h b/qspy/include/safe_std.h index 2cb5394..2d059ea 100644 --- a/qspy/include/safe_std.h +++ b/qspy/include/safe_std.h @@ -1,41 +1,34 @@ -/** -* @file -* @brief "safe" and facilities -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.0 -* Last updated on 2020-08-24 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Copyright (C) 2005-2020 Quantum Leaps, LLC. All rights reserved. +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief "safe" and facilities +* @ingroup qpspy */ #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/qspy/matlab/qspy.m b/qspy/matlab/qspy.m index 9f6c692..c98bc6d 100644 --- a/qspy/matlab/qspy.m +++ b/qspy/matlab/qspy.m @@ -1,37 +1,27 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Product: QSPY Matlab interface. -% Last Updated for Version: 4.5.01 -% Date of the Last Update: Jun 13, 2012 +%============================================================================= +% QSPY Matlab interface +% Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. % -% Q u a n t u m L e a P s -% --------------------------- -% innovating embedded systems +% SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial % -% Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved. +% This software is dual-licensed under the terms of the open source GNU +% General Public License version 3 (or any later version), or alternatively, +% under the terms of one of the closed source Quantum Leaps commercial +% licenses. % -% This program is open source software: you can redistribute it and/or -% modify it under the terms of the GNU General Public License as published -% by the Free Software Foundation, either version 2 of the License, or -% (at your option) any later version. +% The terms of the open source GNU General Public License version 3 +% can be found at: % -% Alternatively, this program may be distributed and modified under the -% terms of Quantum Leaps commercial licenses, which expressly supersede -% the GNU General Public License and are specifically designed for -% licensees interested in retaining the proprietary status of their code. +% The terms of the closed source Quantum Leaps commercial licenses +% can be found at: % -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this program. If not, see . +% Redistributions in source code must retain this top-level comment block. +% Plagiarizing this software to sidestep the license obligations is illegal. % % Contact information: -% Quantum Leaps Web sites: http://www.quantum-leaps.com -% http://www.state-machine.com -% e-mail: info@quantum-leaps.com -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +%============================================================================= % the string Q_FILE must be defined fid = fopen(Q_FILE, 'r'); diff --git a/qspy/posix/qspy_pal.c b/qspy/posix/qspy_pal.c index d24aed1..e761e65 100644 --- a/qspy/posix/qspy_pal.c +++ b/qspy/posix/qspy_pal.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief QSPY PAL implementation for POSIX -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-06-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Copyright (C) 2005-2020 Quantum Leaps, LLC. All rights reserved. +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2022-01-25 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QSPY PAL implementation for POSIX +* @ingroup qpspy */ #include /* for system() */ #include @@ -74,14 +67,6 @@ static QSPYEvtType file_getEvt(unsigned char *buf, uint32_t *pBytes); static QSpyStatus file_send2Target(unsigned char *buf, uint32_t nBytes); static void file_cleanup(void); -/* helper functions ........................................................*/ -static QSPYEvtType be_receive (fd_set const *pReadSet, - unsigned char *buf, uint32_t *pBytes); - -static QSPYEvtType kbd_receive(fd_set const *pReadSet, - unsigned char *buf, uint32_t *pBytes); -static void updateReadySet(int targetConn); - /*..........................................................................*/ enum PAL_Constants { /* local constants... */ INVALID_SOCKET = -1, @@ -120,10 +105,12 @@ static void sigExitHandler(int dummy) { exit(0); } -QSpyStatus PAL_openKbd(bool kbd_inp) { +QSpyStatus PAL_openKbd(bool kbd_inp, bool color) { struct sigaction sig_act; memset(&sig_act, 0, sizeof(sig_act)); + (void)color; /* unused parameter */ + /* install the SIGINT (Ctrl-C) signal handler */ sig_act.sa_handler = &sigExitHandler; sigaction(SIGINT, &sig_act, NULL); @@ -180,14 +167,16 @@ QSpyStatus PAL_openTargetSer(char const *comName, int baudRate) { l_serFD = open(comName, O_RDWR | O_NOCTTY | O_NONBLOCK);/* R/W,no-block */ if (l_serFD == -1) { - SNPRINTF_LINE(" ERROR Opening serial port Port=%s,Baud=%d", + SNPRINTF_LINE(" ERROR " + "Opening serial port Port=%s,Baud=%d", comName, baudRate); QSPY_printError(); return QSPY_ERROR; /* open failed */ } if (tcgetattr(l_serFD, &t) == -1) { - SNPRINTF_LINE(" ERROR cannot get serial attributes errno=%d", + SNPRINTF_LINE(" ERROR " + "cannot get serial attributes errno=%d", errno); QSPY_printError(); return QSPY_ERROR; /* getting attributes failed */ @@ -303,13 +292,13 @@ QSpyStatus PAL_openTargetSer(char const *comName, int baudRate) { return QSPY_ERROR; } - updateReadySet(l_serFD); /* Serial port to be checked in select() */ + PAL_updateReadySet(l_serFD); /* Serial port to be checked in select() */ return QSPY_SUCCESS; } /*..........................................................................*/ static QSPYEvtType ser_getEvt(unsigned char *buf, uint32_t *pBytes) { - QSPYEvtType evt; + QSPYEvtType evtType; fd_set readSet = l_readSet; /* block indefinitely until any input source has input */ @@ -325,15 +314,19 @@ static QSPYEvtType ser_getEvt(unsigned char *buf, uint32_t *pBytes) { } /* any input available from the keyboard? */ - evt = kbd_receive(&readSet, buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + if (l_kbd_inp && FD_ISSET(0, &readSet)) { + evtType = PAL_receiveKbd(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; + } } /* any input available from the Back-End socket? */ - evt = be_receive(&readSet, buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + if ((l_beSock != INVALID_SOCKET) && FD_ISSET(l_beSock, &readSet)) { + evtType = PAL_receiveBe(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; + } } /* any input available from the Serial port? */ @@ -368,7 +361,6 @@ static void ser_cleanup(void) { } } - /*==========================================================================*/ /* POSIX TCP/IP communication with the Target */ @@ -415,7 +407,7 @@ QSpyStatus PAL_openTargetTcp(int portNum) { return QSPY_ERROR; } - updateReadySet(l_serverSock); /* to be checked in select() */ + PAL_updateReadySet(l_serverSock); /* to be checked in select() */ return QSPY_SUCCESS; } @@ -427,7 +419,7 @@ static void tcp_cleanup(void) { } /*..........................................................................*/ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { - QSPYEvtType evt; + QSPYEvtType evtType; fd_set readSet = l_readSet; /* block indefinitely until any input source has input */ @@ -443,15 +435,19 @@ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { } /* any input available from the keyboard? */ - evt = kbd_receive(&readSet, buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + if (l_kbd_inp && FD_ISSET(0, &readSet)) { + evtType = PAL_receiveKbd(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; + } } - /* try to receive data from the Back-End socket... */ - evt = be_receive(&readSet, buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + /* any input available from the Back-End socket? */ + if ((l_beSock != INVALID_SOCKET) && FD_ISSET(l_beSock, &readSet)) { + evtType = PAL_receiveBe(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; + } } /* still waiting for the client? */ @@ -477,7 +473,7 @@ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { QSPY_printInfo(); /* re-evaluate the ready set and max FD for select() */ - updateReadySet(l_clientSock); + PAL_updateReadySet(l_clientSock); } } else { @@ -486,8 +482,7 @@ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { if (nrec <= 0) { /* the client hang up */ SNPRINTF_LINE(" TCP-IP Disconn from " - "Host=%s,Port=%d" - "\n----------------------------------------------------------", + "Host=%s,Port=%d", inet_ntoa(l_clientAddr.sin_addr), (int)ntohs(l_clientAddr.sin_port)); QSPY_printInfo(); @@ -497,7 +492,7 @@ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { l_clientSock = INVALID_SOCKET; /* re-evaluate the ready set and max FD for select() */ - updateReadySet(l_serverSock); + PAL_updateReadySet(l_serverSock); } else { *pBytes = (uint32_t)nrec; @@ -543,7 +538,7 @@ QSpyStatus PAL_openTargetFile(char const *fName) { QSPY_txReset(); /* reset the QSPY transmitter */ fd = fileno(l_file); /* FILE* to file-descriptor */ - updateReadySet(fd); /* fd to be checked in select() */ + PAL_updateReadySet(fd); /* fd to be checked in select() */ SNPRINTF_LINE(" File Opened File=%s", fName); QSPY_printInfo(); @@ -552,7 +547,7 @@ QSpyStatus PAL_openTargetFile(char const *fName) { } /*..........................................................................*/ static QSPYEvtType file_getEvt(unsigned char *buf, uint32_t *pBytes) { - QSPYEvtType evt; + QSPYEvtType evtType; uint32_t nBytes; fd_set readSet = l_readSet; @@ -568,16 +563,20 @@ static QSPYEvtType file_getEvt(unsigned char *buf, uint32_t *pBytes) { return QSPY_ERROR_EVT; } - /* try to receive data from keyboard... */ - evt = kbd_receive(&readSet, buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + /* any input available from the keyboard? */ + if (l_kbd_inp && FD_ISSET(0, &readSet)) { + evtType = PAL_receiveKbd(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; + } } - /* try to receive data from the Back-End socket... */ - evt = be_receive(&readSet, buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + /* any input available from the Back-End socket? */ + if ((l_beSock != INVALID_SOCKET) && FD_ISSET(l_beSock, &readSet)) { + evtType = PAL_receiveBe(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; + } } /* try to receive data from the File... */ @@ -647,7 +646,8 @@ QSpyStatus PAL_openBE(int portNum) { } flags |= O_NONBLOCK; if (fcntl(l_beSock, F_SETFL, flags) != 0) { - SNPRINTF_LINE(" ERROR UDP socket fcntl() set errno=%d", errno); + SNPRINTF_LINE(" ERROR " + "UDP socket fcntl() set errno=%d", errno); QSPY_printError(); return QSPY_ERROR; } @@ -657,7 +657,7 @@ QSpyStatus PAL_openBE(int portNum) { /* NOTE: * The Back-End socket l_beSock needs to be checked in select() just * like all other sources of input. However, the l_beSock socket is - * added automatically in the updateReadySet() function *later* in + * added automatically in the PAL_updateReadySet() function *later* in * the initialization phase. This assumes that PAL_openBE() is called * always *before* opening the specific Target link (see configure() in * main.c). @@ -684,7 +684,8 @@ void PAL_closeBE(void) { &writeSet, (fd_set *)0, &delay) == SOCKET_ERROR) { - SNPRINTF_LINE(" ERROR UDP socket select errno=%d", + SNPRINTF_LINE(" ERROR " + "UDP socket select errno=%d", errno); QSPY_printError(); } @@ -724,16 +725,12 @@ void PAL_clearScreen(void) { } /*--------------------------------------------------------------------------*/ -static QSPYEvtType be_receive(fd_set const *pReadSet, - unsigned char *buf, uint32_t *pBytes) -{ +QSPYEvtType PAL_receiveBe(unsigned char *buf, uint32_t *pBytes) { fe_addr feAddr; socklen_t feAddrSize; uint32_t nBytes; - if ((l_beSock == INVALID_SOCKET) /* Back-End socket not initialized? */ - || !FD_ISSET(l_beSock, pReadSet)) /* Front-End socket has no data? */ - { + if (l_beSock == INVALID_SOCKET) { /* Back-End socket not initialized? */ return QSPY_NO_EVT; } @@ -775,19 +772,15 @@ static QSPYEvtType be_receive(fd_set const *pReadSet, } /*..........................................................................*/ -static QSPYEvtType kbd_receive(fd_set const *pReadSet, - unsigned char *buf, uint32_t *pBytes) -{ - if (l_kbd_inp && FD_ISSET(0, pReadSet)) { - *pBytes = read(0, buf, 1); /* the key pressed */ - if (*pBytes > 0) { - return QSPY_KEYBOARD_EVT; - } +QSPYEvtType PAL_receiveKbd(unsigned char *buf, uint32_t *pBytes) { + *pBytes = read(0, buf, 1); /* the key pressed */ + if (*pBytes > 0) { + return QSPY_KEYBOARD_EVT; } return QSPY_NO_EVT; } /*..........................................................................*/ -static void updateReadySet(int targetConn) { +void PAL_updateReadySet(int targetConn) { FD_ZERO(&l_readSet); FD_SET(0, &l_readSet); /* terminal to be checked in select */ l_maxFd = 1; diff --git a/qspy/source/getopt.c b/qspy/source/getopt.c index e7ee7fb..0f9cb74 100644 --- a/qspy/source/getopt.c +++ b/qspy/source/getopt.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/*============================================================================ * getopt.c - competent and free getopt library. * * getopt() return values: @@ -32,7 +32,7 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ +============================================================================*/ #include #include "safe_std.h" /* "safe" and facilities */ diff --git a/qspy/source/qspy.c b/qspy/source/qspy.c index 184e04b..5009886 100644 --- a/qspy/source/qspy.c +++ b/qspy/source/qspy.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief QSPY host uility: main parser -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QSPY host uility: main parser +* @ingroup qpspy */ #include #include @@ -47,22 +40,10 @@ #include "qspy.h" /* QSPY data parser */ #include "pal.h" /* Platform Abstraction Layer */ -typedef char char_t; -typedef float float32_t; -typedef double float64_t; -typedef int enum_t; -typedef int int_t; -typedef unsigned uint_t; -typedef void QEvt; - -#ifndef Q_SPY -#define Q_SPY 1 -#endif - -#define QS_OBJ_PTR_SIZE 4 -#define QS_FUN_PTR_SIZE 4 -#define Q_SIGNAL_SIZE 2 -#include "qs_copy.h" /* copy of the target-resident QS interface */ +#define Q_SPY 1 /* this is QP implementation */ +#define QP_IMPL 1 /* this is QP implementation */ +#include "qpc_qs.h" /* QS target-resident interface */ +#include "qpc_qs_pkg.h" /* QS package-scope interface */ /* global objects ..........................................................*/ QSPY_LastOutput QSPY_output; @@ -74,10 +55,9 @@ Dictionary QSPY_objDict; Dictionary QSPY_usrDict; SigDictionary QSPY_sigDict; -/****************************************************************************/ - +/*==========================================================================*/ enum { - OLD_QS_USER = 70, /* old QS_USER used in before QS 6.6.0 */ + OLD_QS_USER = 70, /* old QS_USER used before QS 6.6.0 */ }; /*..........................................................................*/ @@ -92,143 +72,141 @@ static uint32_t l_userRec; static QSPY_CustParseFun l_custParseFun; static QSPY_resetFun l_txResetFun; -/* QS record names... NOTE: keep in synch with qs_copy.h */ -static char const * l_qs_rec[] = { - "QS_EMPTY", +/* QS record names... NOTE: keep in synch with qspy_qs.h */ +QSpyRecRender const QSPY_rec[QS_USER] = { + { "QS_EMPTY", GRP_INF }, /* [1] QEP records */ - "QS_QEP_STATE_ENTRY", - "QS_QEP_STATE_EXIT", - "QS_QEP_STATE_INIT", - "QS_QEP_INIT_TRAN", - "QS_QEP_INTERN_TRAN", - "QS_QEP_TRAN", - "QS_QEP_IGNORED", - "QS_QEP_DISPATCH", - "QS_QEP_UNHANDLED", - - /* [10] QF records */ - "QS_QF_ACTIVE_DEFER", - "QS_QF_ACTIVE_RECALL", - "QS_QF_ACTIVE_SUBSCRIBE", - "QS_QF_ACTIVE_UNSUBSCRIBE", - "QS_QF_ACTIVE_POST", - "QS_QF_ACTIVE_POST_LIFO", - "QS_QF_ACTIVE_GET", - "QS_QF_ACTIVE_GET_LAST", - "QS_QF_ACTIVE_RECALL_ATTEMPT", - - /* [19] Event Queue (EQ) records */ - "QS_QF_EQUEUE_POST", - "QS_QF_EQUEUE_POST_LIFO", - "QS_QF_EQUEUE_GET", - "QS_QF_EQUEUE_GET_LAST", - - /* [23] Framework (QF) records */ - "QS_QF_NEW_ATTEMPT", + { "QS_QEP_STATE_ENTRY", GRP_SM }, + { "QS_QEP_STATE_EXIT", GRP_SM }, + { "QS_QEP_STATE_INIT", GRP_SM }, + { "QS_QEP_INIT_TRAN", GRP_SM }, + { "QS_QEP_INTERN_TRAN", GRP_SM }, + { "QS_QEP_TRAN", GRP_SM }, + { "QS_QEP_IGNORED", GRP_SM }, + { "QS_QEP_DISPATCH", GRP_SM }, + { "QS_QEP_UNHANDLED", GRP_SM }, + + /* [10] QF (AP) records */ + { "QS_QF_ACTIVE_DEFER", GRP_AO }, + { "QS_QF_ACTIVE_RECALL", GRP_AO }, + { "QS_QF_ACTIVE_SUBSCRIBE", GRP_AO }, + { "QS_QF_ACTIVE_UNSUBSCRIBE", GRP_AO }, + { "QS_QF_ACTIVE_POST", GRP_AO }, + { "QS_QF_ACTIVE_POST_LIFO", GRP_AO }, + { "QS_QF_ACTIVE_GET", GRP_AO }, + { "QS_QF_ACTIVE_GET_LAST", GRP_AO }, + { "QS_QF_ACTIVE_RECALL_ATTEMPT", GRP_AO }, + + /* [19] QF (EQ) records */ + { "QS_QF_EQUEUE_POST", GRP_EQ }, + { "QS_QF_EQUEUE_POST_LIFO", GRP_EQ }, + { "QS_QF_EQUEUE_GET", GRP_EQ }, + { "QS_QF_EQUEUE_GET_LAST", GRP_EQ }, + + /* [23] QF records */ + { "QS_QF_NEW_ATTEMPT", GRP_QF }, /* [24] Memory Pool (MP) records */ - "QS_QF_MPOOL_GET", - "QS_QF_MPOOL_PUT", + { "QS_QF_MPOOL_GET", GRP_MP }, + { "QS_QF_MPOOL_PUT", GRP_MP }, /* [26] Additional Framework (QF) records */ - "QS_QF_PUBLISH", - "QS_QF_NEW_REF", - "QS_QF_NEW", - "QS_QF_GC_ATTEMPT", - "QS_QF_GC", - "QS_QF_TICK", + { "QS_QF_PUBLISH", GRP_QF }, + { "QS_QF_NEW_REF", GRP_QF }, + { "QS_QF_NEW", GRP_QF }, + { "QS_QF_GC_ATTEMPT", GRP_QF }, + { "QS_QF_GC", GRP_QF }, + { "QS_QF_TICK", GRP_QF }, /* [32] Time Event (TE) records */ - "QS_QF_TIMEEVT_ARM", - "QS_QF_TIMEEVT_AUTO_DISARM", - "QS_QF_TIMEEVT_DISARM_ATTEMPT", - "QS_QF_TIMEEVT_DISARM", - "QS_QF_TIMEEVT_REARM", - "QS_QF_TIMEEVT_POST", + { "QS_QF_TIMEEVT_ARM", GRP_TE }, + { "QS_QF_TIMEEVT_AUTO_DISARM", GRP_TE }, + { "QS_QF_TIMEEVT_DISARM_ATTEMPT", GRP_TE }, + { "QS_QF_TIMEEVT_DISARM", GRP_TE }, + { "QS_QF_TIMEEVT_REARM", GRP_TE }, + { "QS_QF_TIMEEVT_POST", GRP_TE }, /* [38] Additional Framework (QF) records */ - "QS_QF_DELETE_REF", - "QS_QF_CRIT_ENTRY", - "QS_QF_CRIT_EXIT", - "QS_QF_ISR_ENTRY", - "QS_QF_ISR_EXIT", - "QS_QF_INT_DISABLE", - "QS_QF_INT_ENABLE", + { "QS_QF_DELETE_REF", GRP_QF }, + { "QS_QF_CRIT_ENTRY", GRP_QF }, + { "QS_QF_CRIT_EXIT", GRP_QF }, + { "QS_QF_ISR_ENTRY", GRP_QF }, + { "QS_QF_ISR_EXIT", GRP_QF }, + { "QS_QF_INT_DISABLE", GRP_QF }, + { "QS_QF_INT_ENABLE", GRP_QF }, /* [45] Additional Active Object (AO) records */ - "QS_QF_ACTIVE_POST_ATTEMPT", + { "QS_QF_ACTIVE_POST_ATTEMPT", GRP_AO }, /* [46] Additional Event Queue (EQ) records */ - "QS_QF_EQUEUE_POST_ATTEMPT", + { "QS_QF_EQUEUE_POST_ATTEMPT", GRP_EQ }, /* [47] Additional Memory Pool (MP) records */ - "QS_QF_MPOOL_GET_ATTEMPT", + { "QS_QF_MPOOL_GET_ATTEMPT", GRP_MP }, /* [48] Scheduler (SC) records */ - "QS_MUTEX_LOCK", - "QS_MUTEX_UNLOCK", - "QS_SCHED_LOCK", - "QS_SCHED_UNLOCK", - "QS_SCHED_NEXT", - "QS_SCHED_IDLE", - "QS_SCHED_RESUME", + { "QS_MUTEX_LOCK", GRP_SC }, + { "QS_MUTEX_UNLOCK", GRP_SC }, + { "QS_SCHED_LOCK", GRP_SC }, + { "QS_SCHED_UNLOCK", GRP_SC }, + { "QS_SCHED_NEXT", GRP_SC }, + { "QS_SCHED_IDLE", GRP_SC }, + { "QS_SCHED_RESUME", GRP_SC }, /* [55] Additional QEP records */ - "QS_QEP_TRAN_HIST", - "QS_QEP_TRAN_EP", - "QS_QEP_TRAN_XP", + { "QS_QEP_TRAN_HIST", GRP_SM }, + { "QS_QEP_TRAN_EP", GRP_SM }, + { "QS_QEP_TRAN_XP", GRP_SM }, /* [58] Miscellaneous QS records (not maskable) */ - "QS_TEST_PAUSED", - "QS_TEST_PROBE_GET", - "QS_SIG_DICT", - "QS_OBJ_DICT", - "QS_FUN_DICT", - "QS_USR_DICT", - "QS_TARGET_INFO", - "QS_TARGET_DONE", - "QS_RX_STATUS", - "QS_QUERY_DATA", - "QS_PEEK_DATA", - "QS_ASSERT_FAIL" - "QS_QF_RUN" - - /* [71] Reserved QS records */ - "QS_RESERVED_71", - "QS_RESERVED_72", - "QS_RESERVED_73", - "QS_RESERVED_74", - "QS_RESERVED_75", - "QS_RESERVED_76", - "QS_RESERVED_77", - "QS_RESERVED_78", - "QS_RESERVED_79", - "QS_RESERVED_80", - "QS_RESERVED_81", - "QS_RESERVED_82", - "QS_RESERVED_83", - "QS_RESERVED_84", - "QS_RESERVED_85", - "QS_RESERVED_86", - "QS_RESERVED_87", - "QS_RESERVED_88", - "QS_RESERVED_89", - "QS_RESERVED_90", - "QS_RESERVED_91", - "QS_RESERVED_92", - "QS_RESERVED_93", - "QS_RESERVED_94", - "QS_RESERVED_95", - "QS_RESERVED_96", - "QS_RESERVED_97", - "QS_RESERVED_98", - "QS_RESERVED_99", - - /* [100] Application-specific (User) QS records */ + { "QS_TEST_PAUSED", GRP_TST }, + { "QS_TEST_PROBE_GET", GRP_TST }, + { "QS_SIG_DICT", GRP_DIC }, + { "QS_OBJ_DICT", GRP_DIC }, + { "QS_FUN_DICT", GRP_DIC }, + { "QS_USR_DICT", GRP_DIC }, + { "QS_TARGET_INFO", GRP_INF }, + { "QS_TARGET_DONE", GRP_TST }, + { "QS_RX_STATUS", GRP_TST }, + { "QS_QUERY_DATA", GRP_TST }, + { "QS_PEEK_DATA", GRP_TST }, + { "QS_ASSERT_FAIL", GRP_ERR }, + { "QS_QF_RUN", GRP_INF }, + + /* [71] Miscellaneous QS records (not maskable) */ + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, + { "QS_RESERVED", GRP_ERR }, }; -/* QS object kinds... NOTE: keep in synch with qs_copy.h */ +/* QS object kinds... NOTE: keep in synch with qspy_qs.h */ static char const * l_qs_obj[] = { "SM", "AO", @@ -239,7 +217,7 @@ static char const * l_qs_obj[] = { "SM_AO" }; -/* QS-RX record names... NOTE: keep in synch with qs_copy.h */ +/* QS-RX record names... NOTE: keep in synch with qspy_qs_pkg.h */ static char const * l_qs_rx_rec[] = { "QS_RX_INFO", "QS_RX_COMMAND", @@ -260,7 +238,7 @@ static char const * l_qs_rx_rec[] = { "QS_RX_EVENT" }; -/* stuff for QSPY host application only (but not for QSPY parser) */ +/* facilities for QSPY host application only (but not for QSPY parser) */ #ifdef QSPY_APP #define FPRINF_MATFILE(format_, ...) \ @@ -274,7 +252,6 @@ static char const * l_qs_rx_rec[] = { #endif /* QSPY_APP */ - /*==========================================================================*/ void QSPY_config(QSpyConfig const *config, QSPY_CustParseFun custParseFun) @@ -295,7 +272,7 @@ void QSPY_config(QSpyConfig const *config, Dictionary_config(&QSPY_usrDict, 1); SigDictionary_config(&QSPY_sigDict, QSPY_conf.objPtrSize); - QSPY_conf.tstamp[5] = 0U; /* invalidate the year-part of the timestamp */ + QSPY_conf.tstamp[5] = 0U; /* invalidate the year-part of the timestamp */ l_userRec = ((QSPY_conf.version < 660U) ? OLD_QS_USER : QS_USER); } /*..........................................................................*/ @@ -335,8 +312,8 @@ QSpyStatus QSpyRecord_OK(QSpyRecord * const me) { } /* is this a standard QS record? */ - if (me->rec < sizeof(l_qs_rec)/sizeof(l_qs_rec[0])) { - SNPRINTF_APPEND("Rec=%s", l_qs_rec[me->rec]); + if (me->rec < l_userRec) { + SNPRINTF_APPEND("Rec=%s", QSPY_rec[me->rec].name); } else { /* USER-specific record */ SNPRINTF_APPEND("Rec=USER+%3d", (int)(me->rec - l_userRec)); @@ -560,8 +537,8 @@ uint8_t const *QSpyRecord_getMem(QSpyRecord * const me, return (uint8_t *)0; } -/****************************************************************************/ -/* application-specific (user) QSPY records... */ +/*==========================================================================*/ +/* application-specific (user) QS records... */ static void QSpyRecord_processUser(QSpyRecord * const me) { int64_t i64; uint64_t u64; @@ -758,8 +735,8 @@ static void QSpyRecord_processUser(QSpyRecord * const me) { FPRINF_MATFILE("%c", '\n'); } -/****************************************************************************/ -/* predefined QSPY records... */ +/*==========================================================================*/ +/* pre-defined QS records... */ static void QSpyRecord_process(QSpyRecord * const me) { uint32_t t, a, b, c, d, e; uint64_t p, q, r; @@ -1719,7 +1696,8 @@ static void QSpyRecord_process(QSpyRecord * const me) { a = QSpyRecord_getUint32(me, 4U); if (QSpyRecord_OK(me)) { SNPRINTF_LINE("%010u TstProbe Fun=%s,Data=%d", - t, Dictionary_get(&QSPY_funDict, q, (char *)0), a); + t, Dictionary_get(&QSPY_funDict, + q, (char *)0), a); QSPY_onPrintLn(); } break; @@ -1851,7 +1829,8 @@ static void QSpyRecord_process(QSpyRecord * const me) { CONFIG_UPDATE(tevtCtrSize, (uint8_t)((buf[1] >> 4) & 0xFU),d); /* update the user record offset */ - l_userRec = ((QSPY_conf.version < 660U) ? OLD_QS_USER : QS_USER); + l_userRec = ((QSPY_conf.version < 660U) + ? OLD_QS_USER : QS_USER); for (e = 0U; e < sizeof(QSPY_conf.tstamp); ++e) { CONFIG_UPDATE(tstamp[e], (uint8_t)buf[7U + e], d); @@ -1876,7 +1855,7 @@ static void QSpyRecord_process(QSpyRecord * const me) { SNPRINTF_LINE(" %s", "Target info mismatch " "(dictionaries discarded)"); - QSPY_onPrintLn(); + QSPY_printInfo(); QSPY_resetAllDictionaries(); } @@ -2140,7 +2119,7 @@ void QSPY_printError(void) { QSPY_onPrintLn(); } -/****************************************************************************/ +/*==========================================================================*/ static uint8_t l_record[QS_RECORD_SIZE_MAX]; static uint8_t *l_pos = l_record; /* position within the record */ static uint8_t l_chksum = 0U; @@ -2173,9 +2152,9 @@ void QSPY_parse(uint8_t const *buf, uint32_t nBytes) { SNPRINTF_LINE(" ERROR Record too long at " "Seq=%u(?),", (unsigned)l_seq); /* is it a standard QS record? */ - if (l_record[1] < sizeof(l_qs_rec)/sizeof(l_qs_rec[0])) { + if (l_record[1] < l_userRec) { SNPRINTF_APPEND("Rec=%s(?)", - l_qs_rec[l_record[1]]); + QSPY_rec[l_record[1]].name); } else { /* this is a USER-specific record */ SNPRINTF_APPEND("Rec=USER+%u(?)", @@ -2195,9 +2174,9 @@ void QSPY_parse(uint8_t const *buf, uint32_t nBytes) { if (!isJustStarted) { SNPRINTF_LINE(" ERROR %s", "Bad checksum in "); - if (l_record[1] < sizeof(l_qs_rec)/sizeof(l_qs_rec[0])) { + if (l_record[1] < l_userRec) { SNPRINTF_APPEND("Rec=%s(?),", - l_qs_rec[l_record[1]]); + QSPY_rec[l_record[1]].name); } else { SNPRINTF_APPEND("Rec=USER+%u(?),", @@ -2211,8 +2190,8 @@ void QSPY_parse(uint8_t const *buf, uint32_t nBytes) { SNPRINTF_LINE(" ERROR Record too short at " "Seq=%u(?),", (unsigned)l_seq); - if (l_record[1] < sizeof(l_qs_rec)/sizeof(l_qs_rec[0])) { - SNPRINTF_APPEND("Rec=%s", l_qs_rec[l_record[1]]); + if (l_record[1] < l_userRec) { + SNPRINTF_APPEND("Rec=%s", QSPY_rec[l_record[1]].name); } else { SNPRINTF_APPEND("Rec=USER+%u(?)", @@ -2277,8 +2256,8 @@ void QSPY_parse(uint8_t const *buf, uint32_t nBytes) { SNPRINTF_LINE(" ERROR Record too long at " "Seq=%3u,", (unsigned)l_seq); - if (l_record[1] < sizeof(l_qs_rec)/sizeof(l_qs_rec[0])) { - SNPRINTF_APPEND("Rec=%s", l_qs_rec[l_record[1]]); + if (l_record[1] < l_userRec) { + SNPRINTF_APPEND("Rec=%s", QSPY_rec[l_record[1]].name); } else { SNPRINTF_APPEND("Rec=USER+%3u", @@ -2605,5 +2584,3 @@ void SigDictionary_reset(SigDictionary * const me) { } me->entries = 0; } - - diff --git a/qspy/source/qspy_be.c b/qspy/source/qspy_be.c index f0fd6e1..eaee6db 100644 --- a/qspy/source/qspy_be.c +++ b/qspy/source/qspy_be.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief Back-End connection point for the external Front-Ends -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief Back-End connection point for the external Front-Ends +* @ingroup qpspy */ #include #include @@ -45,21 +38,10 @@ #include "be.h" /* Back-End interface */ #include "pal.h" /* Platform Abstraction Layer */ -typedef char char_t; -typedef float float32_t; -typedef double float64_t; -typedef int enum_t; -typedef int int_t; -typedef unsigned uint_t; -typedef void QEvt; - -#ifndef Q_SPY -#define Q_SPY 1 -#endif -#define QS_OBJ_PTR_SIZE 4 -#define QS_FUN_PTR_SIZE 4 -#define Q_SIGNAL_SIZE 2 -#include "qs_copy.h" /* copy of the target-resident QS interface */ +#define Q_SPY 1 /* this is QP implementation */ +#define QP_IMPL 1 /* this is QP implementation */ +#include "qpc_qs.h" /* QS target-resident interface */ +#include "qpc_qs_pkg.h" /* QS package-scope interface */ /*..........................................................................*/ static uint8_t l_rxBeSeq; /* receive Back-End sequence number */ @@ -303,4 +285,3 @@ void BE_sendLine(void) { } } } - diff --git a/qspy/source/qspy_dict.c b/qspy/source/qspy_dict.c index 65ec267..39f818f 100644 --- a/qspy/source/qspy_dict.c +++ b/qspy/source/qspy_dict.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief QSPY host uility: dictionary file reading/writing -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-10-18 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QSPY host uility: dictionary file reading/writing +* @ingroup qpspy */ #include #include @@ -130,7 +123,7 @@ QSpyStatus QSPY_writeDict(void) { fclose(dictFile); SNPRINTF_LINE(" Dictionaries saved to File=%s", buf); - QSPY_onPrintLn(); + QSPY_printInfo(); return QSPY_SUCCESS; } @@ -310,7 +303,7 @@ QSpyStatus QSPY_readDict(void) { if ((stat != QSPY_ERROR) && (d != 0U) && (c != 0U)) { SNPRINTF_LINE(" %s", "Dictionaries mismatch the Target (discarded)"); - QSPY_onPrintLn(); + QSPY_printInfo(); QSPY_resetAllDictionaries(); stat = QSPY_ERROR; diff --git a/qspy/source/qspy_main.c b/qspy/source/qspy_main.c index e4f21b6..2c548db 100644 --- a/qspy/source/qspy_main.c +++ b/qspy/source/qspy_main.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief main for QSPY host utility -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2022-01-27 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief main for QSPY host utility +* @ingroup qpspy */ #include #include @@ -49,6 +42,11 @@ #include "pal.h" /* Platform Abstraction Layer */ #include "getopt.h" /* command-line option processor */ +#define Q_SPY 1 /* this is QP implementation */ +#define QP_IMPL 1 /* this is QP implementation */ +#include "qpc_qs.h" /* QS target-resident interface */ +#include "qpc_qs_pkg.h" /* QS package-scope interface */ + /*..........................................................................*/ typedef enum { NO_LINK, @@ -81,8 +79,13 @@ static int l_bePort = 7701; /* default UDP port */ static int l_tcpPort = 6601; /* default TCP port */ static int l_baudRate = 115200; /* default serial baudrate */ +/* color rendeing */ +extern char const * const l_darkPalette[]; +extern char const * const l_lightPalette[]; +static char const * const *l_colorPalette = l_darkPalette; + static char const l_introStr[] = \ - "QSPY %s Copyright (c) 2005-2021 Quantum Leaps\n" \ + "QSPY %s Copyright (c) 2005-2022 Quantum Leaps\n" \ "Documentation: https://www.state-machine.com/qtools/qspy.html\n" \ "Current timestamp: %s\n"; @@ -96,6 +99,7 @@ static char const l_helpStr[] = "-q [num] (key-q) quiet mode (no QS data output)\n" "-u [UDP_port|0] 7701 UDP socket with optional port, 0-no UDP\n" "-v 6.6 compatibility with QS version\n" + "-r c1 rendering (c0=no-color, c1-color1, )\n" "-k suppress keyboard input\n" "-o (key-o) save screen output to a file\n" "-s (key-s) save binary QS data to a file\n" @@ -123,7 +127,7 @@ static char const l_helpStr[] = static char const l_kbdHelpStr[] = "Keyboard shortcuts (valid when -k option is absent):\n" "KEY(s) ACTION\n" - "-----------------------------------------------------------------\n" + "----------------------------------------------------------------\n" "/x/X Exit QSPY\n" " h display keyboard help and QSPY status\n" " c clear the screen\n" @@ -140,6 +144,7 @@ static char const l_kbdHelpStr[] = /*..........................................................................*/ static QSpyStatus configure(int argc, char *argv[]); +static void colorPrintLn(void); static uint8_t l_buf[8*1024]; /* process input in 8K chunks */ /*..........................................................................*/ @@ -237,9 +242,24 @@ void Q_onAssert(char const * const module, int loc) { /*..........................................................................*/ void QSPY_onPrintLn(void) { + if (l_outFile != (FILE *)0) { + /* output file receives all trace records, regardles of -q mode */ + fputs(&QSPY_output.buf[QS_LINE_OFFSET], l_outFile); + fputc('\n', l_outFile); + } + + if (QSPY_output.type != INF_OUT) { /* just an internal info? */ + BE_sendLine(); /* forward to the back-end */ + } + if (l_quiet < 0) { - fputs(QSPY_line, stdout); - fputc('\n', stdout); + if (l_colorPalette) { + colorPrintLn(); + } + else { + fputs(&QSPY_output.buf[QS_LINE_OFFSET], stdout); + fputc('\n', stdout); + } } else if (l_quiet > 0) { if ((l_quiet_ctr == 0U) || (QSPY_output.type != REG_OUT)) { @@ -247,8 +267,13 @@ void QSPY_onPrintLn(void) { if (l_quiet_ctr != l_quiet - 1) { fputc('\n', stdout); } - fputs(&QSPY_output.buf[QS_LINE_OFFSET], stdout); - fputc('\n', stdout); + if (l_colorPalette) { + colorPrintLn(); + } + else { + fputs(&QSPY_output.buf[QS_LINE_OFFSET], stdout); + fputc('\n', stdout); + } l_quiet_ctr = l_quiet; } } @@ -258,23 +283,13 @@ void QSPY_onPrintLn(void) { --l_quiet_ctr; } - if (l_outFile != (FILE *)0) { - /* the output file receives all trace records, regardles of -q mode */ - fputs(&QSPY_output.buf[QS_LINE_OFFSET], l_outFile); - fputc('\n', l_outFile); - } - - if (QSPY_output.type != INF_OUT) { /* just an internal info? */ - BE_sendLine(); /* forward to the back-end */ - } - QSPY_output.type = REG_OUT; /* reset for the next time */ } /*..........................................................................*/ static QSpyStatus configure(int argc, char *argv[]) { static char const getoptStr[] = - "hq::u::v:kosmg:c:b:t::p:f:d::T:O:F:S:E:Q:P:B:C:"; + "hq::u::v:r:kosmg:c:b:t::p:f:d::T:O:F:S:E:Q:P:B:C:"; /* default configuration options... */ QSpyConfig config = { @@ -345,6 +360,23 @@ static QSpyStatus configure(int argc, char *argv[]) { } break; } + case 'r': { /* rendering options */ + if (optarg != NULL) { /* is optional argument provided? */ + PRINTF_S("-r %s\n", optarg); + if (optarg[0] == 'c') { + if (optarg[1] == '1') { + l_colorPalette = l_darkPalette; + } + else if (optarg[1] == '2') { + l_colorPalette = l_lightPalette; + } + else { + l_colorPalette = (char const * const *)0; + } + } + } + break; + } case 'k': { /* suppress keyboard input */ l_kbd_inp = false; break; @@ -507,6 +539,13 @@ static QSpyStatus configure(int argc, char *argv[]) { return QSPY_ERROR; } + /* open the keyboard input... */ + if (PAL_openKbd(l_kbd_inp, (l_colorPalette != (char const * const*)0)) + != QSPY_SUCCESS) + { + return QSPY_ERROR; + } + /* configure QSPY ......................................................*/ /* open Back-End link. NOTE: must happen *before* opening Target link */ if (l_bePort != 0) { @@ -587,11 +626,6 @@ static QSpyStatus configure(int argc, char *argv[]) { QSPY_readDict(); } - /* open the keyboard input... */ - if (PAL_openKbd(l_kbd_inp) != QSPY_SUCCESS) { - return QSPY_ERROR; - } - return QSPY_SUCCESS; } /*..........................................................................*/ @@ -766,7 +800,7 @@ bool QSPY_command(uint8_t cmdId) { case 'x': case 'X': - case '\033': /* Esc */ + case '\x1b': /* Esc */ isRunning = false; /* terminate the event loop */ break; } @@ -791,3 +825,191 @@ char const* QSPY_tstampStr(void) { return &tstampStr[0]; } + +/*--------------------------------------------------------------------------*/ +/* color output to the terimal */ + +/* terminal colors */ +#define B_DFLT "\x1b[0m" +#define B_BLACK "\x1b[40m" +#define B_RED "\x1b[41m" +#define B_GREEN "\x1b[42m" +#define B_YELLOW "\x1b[43m" +#define B_BLUE "\x1b[44m" +#define B_MAGENTA "\x1b[45m" +#define B_CYAN "\x1b[46m" +#define B_WHITE "\x1b[47m" + +#define F_BLACK "\x1b[30m" +#define F_RED "\x1b[31m" +#define F_GREEN "\x1b[32m" +#define F_YELLOW "\x1b[33m" +#define F_BLUE "\x1b[34m" +#define F_MAGENTA "\x1b[35m" +#define F_CYAN "\x1b[36m" +#define F_WHITE "\x1b[37m" + +#define F_GRAY "\x1b[30;1m" +#define F_BRED "\x1b[31;1m" +#define F_BGREEN "\x1b[32;1m" +#define F_BYELLOW "\x1b[33;1m" +#define F_BBLUE "\x1b[34;1m" +#define F_BMAGENTA "\x1b[35;1m" +#define F_BCYAN "\x1b[36;1m" +#define F_BWHITE "\x1b[37;1m" + +/* color palette entries */ +enum { + PALETTE_ERR_OUT, + PALETTE_INF_OUT, + PALETTE_TSTAMP, + PALETTE_DSC_SM, + PALETTE_DSC_QP, + PALETTE_DSC_INF, + PALETTE_DSC_TST, + PALETTE_SM_TXT, + PALETTE_QP_TXT, + PALETTE_INF_TXT, + PALETTE_DIC_TXT, + PALETTE_TST_TXT, + PALETTE_USR_TXT, +}; + +char const * const l_darkPalette[] = { +/* PALETTE_ERR_OUT */ B_RED F_BYELLOW, +/* PALETTE_INF_OUT */ B_DFLT B_GREEN F_BLACK, +/* PALETTE_TSTAMP */ B_BLACK F_GRAY, +/* PALETTE_DSC_SM */ B_BLUE F_WHITE, +/* PALETTE_DSC_QP */ B_DFLT B_MAGENTA F_WHITE, +/* PALETTE_DSC_INF */ B_DFLT B_BLUE F_BYELLOW, +/* PALETTE_DSC_TST */ B_DFLT B_CYAN F_BWHITE, +/* PALETTE_SM_TXT */ B_BLACK F_BWHITE, +/* PALETTE_QP_TXT */ B_BLACK F_WHITE, +/* PALETTE_INF_TXT */ B_DFLT B_BLACK F_BYELLOW, +/* PALETTE_DIC_TXT */ B_BLACK F_GRAY, +/* PALETTE_TST_TXT */ B_DFLT B_BLACK F_YELLOW, +/* PALETTE_USR_TXT */ B_DFLT B_WHITE F_BLACK, +}; + +char const * const l_lightPalette[] = { +/* PALETTE_ERR_OUT */ B_RED F_BYELLOW, +/* PALETTE_INF_OUT */ B_DFLT B_GREEN F_BLACK, +/* PALETTE_TSTAMP */ B_WHITE F_GRAY, +/* PALETTE_DSC_SM */ B_BLUE F_WHITE, +/* PALETTE_DSC_QP */ B_DFLT B_MAGENTA F_WHITE, +/* PALETTE_DSC_INF */ B_DFLT B_BLUE F_BYELLOW, +/* PALETTE_DSC_TST */ B_DFLT B_CYAN F_BWHITE, +/* PALETTE_SM_TXT */ B_WHITE F_BLUE, +/* PALETTE_QP_TXT */ B_WHITE F_MAGENTA, +/* PALETTE_INF_TXT */ B_DFLT B_WHITE F_RED, +/* PALETTE_DIC_TXT */ B_WHITE F_GRAY, +/* PALETTE_TST_TXT */ B_DFLT B_WHITE F_BLUE, +/* PALETTE_USR_TXT */ B_DFLT B_BLACK F_WHITE, +}; + +enum { + COL_TSTAMP = 11, + COL_DESC = 19, +}; + +static void colorPrintLn(void) { + if (QSPY_output.type == REG_OUT) { + int group = QSPY_output.rec < QS_USER + ? QSPY_rec[QSPY_output.rec].group + : GRP_USR; + + /* timestamp */ + char ch; + ch = QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP]; + QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP] = '\0'; + fputs(l_colorPalette[PALETTE_TSTAMP], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET], stdout); + QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP] = ch; + + switch (group) { + case GRP_ERR: { + fputs(l_colorPalette[PALETTE_ERR_OUT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + break; + } + case GRP_INF: { + /* description section */ + ch = QSPY_output.buf[QS_LINE_OFFSET + COL_DESC]; + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = '\0'; + fputs(l_colorPalette[PALETTE_DSC_INF], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = ch; + if (QSPY_output.len > COL_DESC) { + fputs(l_colorPalette[PALETTE_INF_TXT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_DESC], stdout); + } + break; + } + case GRP_DIC: { + fputs(l_colorPalette[PALETTE_DIC_TXT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + break; + } + case GRP_TST: { + /* description section */ + ch = QSPY_output.buf[QS_LINE_OFFSET + COL_DESC]; + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = '\0'; + fputs(l_colorPalette[PALETTE_DSC_TST], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = ch; + if (QSPY_output.len > COL_DESC) { + fputs(l_colorPalette[PALETTE_TST_TXT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_DESC], stdout); + } + break; + } + case GRP_SM: { + /* description section */ + ch = QSPY_output.buf[QS_LINE_OFFSET + COL_DESC]; + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = '\0'; + fputs(l_colorPalette[PALETTE_DSC_SM], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = ch; + if (QSPY_output.len > COL_DESC) { + fputs(l_colorPalette[PALETTE_SM_TXT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_DESC], stdout); + } + break; + } + case GRP_AO: + case GRP_EQ: + case GRP_MP: + case GRP_TE: + case GRP_QF: + case GRP_SC: { + /* description section */ + ch = QSPY_output.buf[QS_LINE_OFFSET + COL_DESC]; + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = '\0'; + fputs(l_colorPalette[PALETTE_DSC_QP], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + QSPY_output.buf[QS_LINE_OFFSET + COL_DESC] = ch; + if (QSPY_output.len > COL_DESC) { + fputs(l_colorPalette[PALETTE_QP_TXT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_DESC], stdout); + } + break; + } + case GRP_USR: /* intentionally fall through */ + default: { + fputs(l_colorPalette[PALETTE_USR_TXT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET + COL_TSTAMP], stdout); + break; + } + } + } + else if (QSPY_output.type == INF_OUT) { + fputs(l_colorPalette[PALETTE_INF_OUT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET], stdout); + } + else { /* ERR_OUT */ + fputs(l_colorPalette[PALETTE_ERR_OUT], stdout); + fputs(&QSPY_output.buf[QS_LINE_OFFSET], stdout); + } + fputs(B_DFLT "\n", stdout); +} + diff --git a/qspy/source/qspy_seq.c b/qspy/source/qspy_seq.c index 916a9ff..851919d 100644 --- a/qspy/source/qspy_seq.c +++ b/qspy/source/qspy_seq.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief QSPY host uility: sequence diagram generation -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-10-19 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QSPY host uility: sequence diagram generation +* @ingroup qpspy */ #include #include diff --git a/qspy/source/qspy_tx.c b/qspy/source/qspy_tx.c index e34accd..e6113ed 100644 --- a/qspy/source/qspy_tx.c +++ b/qspy/source/qspy_tx.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief QSPY transmit facilities -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2021-12-23 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QSPY transmit facilities +* @ingroup qpspy */ #include #include @@ -47,21 +40,10 @@ #include "qspy.h" /* QSPY data parser */ #include "pal.h" /* Platform Abstraction Layer */ -typedef char char_t; -typedef float float32_t; -typedef double float64_t; -typedef int enum_t; -typedef int int_t; -typedef unsigned uint_t; -typedef void QEvt; - -#ifndef Q_SPY -#define Q_SPY 1 -#endif -#define QS_OBJ_PTR_SIZE 4 -#define QS_FUN_PTR_SIZE 4 -#define Q_SIGNAL_SIZE 2 -#include "qs_copy.h" /* copy of the target-resident QS interface */ +#define Q_SPY 1 /* this is QP implementation */ +#define QP_IMPL 1 /* this is QP implementation */ +#include "qpc_qs.h" /* QS target-resident interface */ +#include "qpc_qs_pkg.h" /* QS package-scope interface */ /*..........................................................................*/ static uint8_t l_dstBuf[1024]; /* for encoding from FE to Target */ diff --git a/qspy/win32/Makefile b/qspy/win32/Makefile index 207c637..7d4e18b 100644 --- a/qspy/win32/Makefile +++ b/qspy/win32/Makefile @@ -1,36 +1,27 @@ -############################################################################## -# Product: Makefile for QSPY console, Win32, MinGW -# Last updated for version 6.9.4 -# Last updated on 2021-10-19 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software +#============================================================================= +# Makefile for QSPY console, Win32, MinGW +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial # -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# This software is dual-licensed under the terms of the open source GNU +# General Public License version 3 (or any later version), or alternatively, +# under the terms of one of the closed source Quantum Leaps commercial +# licenses. # -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. +# The terms of the open source GNU General Public License version 3 +# can be found at: # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# The terms of the closed source Quantum Leaps commercial licenses +# can be found at: # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Redistributions in source code must retain this top-level comment block. +# Plagiarizing this software to sidestep the license obligations is illegal. # # Contact information: -# +# # -############################################################################## +#============================================================================= # examples of invoking this Makefile: # building configurations: Debug (default), Release, and Spy # make @@ -63,7 +54,6 @@ VPATH := . \ INCLUDES := -I. \ -I../include - #----------------------------------------------------------------------------- # project files: # diff --git a/qspy/win32/qspy.vcxproj.filters b/qspy/win32/qspy.vcxproj.filters index 857a12b..412fcb8 100644 --- a/qspy/win32/qspy.vcxproj.filters +++ b/qspy/win32/qspy.vcxproj.filters @@ -43,9 +43,6 @@ Source Files - - Source Files - Source Files @@ -55,5 +52,8 @@ PAL + + Source Files + \ No newline at end of file diff --git a/qspy/win32/qspy_pal.c b/qspy/win32/qspy_pal.c index 33f6591..d870c89 100644 --- a/qspy/win32/qspy_pal.c +++ b/qspy/win32/qspy_pal.c @@ -1,41 +1,34 @@ -/** -* @file -* @brief QSPY PAL implementation for Win32 -* @ingroup qpspy -* @cond -****************************************************************************** -* Last updated for version 6.9.4 -* Last updated on 2021-11-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software +/*============================================================================ +* QP/C Real-Time Embedded Framework (RTEF) +* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. * -* Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial * -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. * -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. +* The terms of the open source GNU General Public License version 3 +* can be found at: * -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: * -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. * * Contact information: -* +* * -****************************************************************************** -* @endcond +============================================================================*/ +/*! +* @date Last updated on: 2022-01-25 +* @version Last updated for version: 7.0.0 +* +* @file +* @brief QSPY PAL implementation for Win32 +* @ingroup qpspy */ #include /* for system() */ #include @@ -74,10 +67,6 @@ static QSPYEvtType file_getEvt(unsigned char *buf, uint32_t *pBytes); static QSpyStatus file_send2Target(unsigned char *buf, uint32_t nBytes); static void file_cleanup(void); -/* helper functions ........................................................*/ -static QSPYEvtType be_receive (unsigned char *buf, uint32_t *pBytes); -static QSPYEvtType kbd_receive(unsigned char *buf, uint32_t *pBytes); - /*..........................................................................*/ enum PAL_Constants { /* local constants... */ FE_DETACHED = 0, /* Front-End detached */ @@ -91,6 +80,7 @@ typedef union { } fe_addr; static bool l_kbd_inp = false; +static bool l_color = false; static HANDLE l_serHNDL; static COMMTIMEOUTS l_timeouts; @@ -105,21 +95,29 @@ static SOCKET l_clientSock = INVALID_SOCKET; static FILE *l_file = (FILE *)0; /*==========================================================================*/ -/* Keyboard input */ - +/* Ctrl-C handler */ static BOOL WINAPI CtrlHandler(_In_ DWORD dwCtrlType) { (void)dwCtrlType; /* unused parameter */ QSPY_cleanup(); exit(0); } -QSpyStatus PAL_openKbd(bool kbd_inp) { +/* Keyboard input */ +QSpyStatus PAL_openKbd(bool kbd_inp, bool color) { l_kbd_inp = kbd_inp; + l_color = color; SetConsoleCtrlHandler(&CtrlHandler, TRUE); + if (l_color) { + system("color"); /* to support color output */ + fputs("\033[0m", stdout); /* switch default colors */ + } return QSPY_SUCCESS; } /*..........................................................................*/ void PAL_closeKbd(void) { + if (l_color) { + fputs("\033[0m", stdout); /* switch default colors */ + } } /*==========================================================================*/ @@ -231,18 +229,18 @@ QSpyStatus PAL_openTargetSer(char const *comName, int baudRate) { } /*..........................................................................*/ static QSPYEvtType ser_getEvt(unsigned char *buf, uint32_t *pBytes) { - QSPYEvtType evt; + QSPYEvtType evtType; /* try to receive data from keyboard... */ - evt = kbd_receive(buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + evtType = PAL_receiveKbd(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; } /* try to receive data from the Back-End socket... */ - evt = be_receive(buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + evtType = PAL_receiveBe(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; } /* try to receive data from the Target... */ @@ -378,7 +376,7 @@ static void tcp_cleanup(void) { } /*..........................................................................*/ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { - QSPYEvtType evt; + QSPYEvtType evtType; struct timeval timeout = {(long)0, (long)(PAL_TOUT_MS*1000)}; fd_set readSet; int status; @@ -386,15 +384,15 @@ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { char client_hostname[128]; /* try to receive data from keyboard... */ - evt = kbd_receive(buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + evtType = PAL_receiveKbd(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; } /* try to receive data from the Back-End socket... */ - evt = be_receive(buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + evtType = PAL_receiveBe(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; } /* still waiting for the client? */ @@ -475,9 +473,9 @@ static QSPYEvtType tcp_getEvt(unsigned char *buf, uint32_t *pBytes) { sizeof(client_hostname) - 1U); #endif SNPRINTF_LINE(" TCP-IP Disconn from " - "Host=%s,Port=%d" - "\n----------------------------------------------------------", - client_hostname, (int)ntohs(l_clientAddr.sin_port)); + "Host=%s,Port=%d", + client_hostname, + (int)ntohs(l_clientAddr.sin_port)); QSPY_printInfo(); /* go back to waiting for a client */ @@ -532,19 +530,19 @@ QSpyStatus PAL_openTargetFile(char const *fName) { } /*..........................................................................*/ static QSPYEvtType file_getEvt(unsigned char *buf, uint32_t *pBytes) { - QSPYEvtType evt; + QSPYEvtType evtType; uint32_t nBytes; /* try to receive data from keyboard... */ - evt = kbd_receive(buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + evtType = PAL_receiveKbd(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; } /* try to receive data from the Back-End socket... */ - evt = be_receive(buf, pBytes); - if (evt != QSPY_NO_EVT) { - return evt; + evtType = PAL_receiveBe(buf, pBytes); + if (evtType != QSPY_NO_EVT) { + return evtType; } /* try to receive data from the File... */ @@ -685,7 +683,7 @@ void PAL_clearScreen(void) { } /*--------------------------------------------------------------------------*/ -static QSPYEvtType be_receive(unsigned char *buf, uint32_t *pBytes) { +QSPYEvtType PAL_receiveBe(unsigned char *buf, uint32_t *pBytes) { fe_addr feAddr; int feAddrSize; int status; @@ -735,7 +733,7 @@ static QSPYEvtType be_receive(unsigned char *buf, uint32_t *pBytes) { } /*..........................................................................*/ -static QSPYEvtType kbd_receive(unsigned char *buf, uint32_t *pBytes) { +QSPYEvtType PAL_receiveKbd(unsigned char *buf, uint32_t *pBytes) { if (l_kbd_inp) { wint_t ch = 0; while (_kbhit()) { diff --git a/qutest/qutest.py b/qutest/qutest.py index d1b10c6..d8fb955 100644 --- a/qutest/qutest.py +++ b/qutest/qutest.py @@ -1,38 +1,34 @@ -## -# @file -#----------------------------------------------------------------------------- -# Product: QUTest Python scripting (requires Python 3.3+) -# Last updated for version 6.9.4 -# Last updated on 2021-09-17 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software +#============================================================================= +# QUTest Python scripting support +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial # -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# This software is dual-licensed under the terms of the open source GNU +# General Public License version 3 (or any later version), or alternatively, +# under the terms of one of the closed source Quantum Leaps commercial +# licenses. # -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. +# The terms of the open source GNU General Public License version 3 +# can be found at: # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# The terms of the closed source Quantum Leaps commercial licenses +# can be found at: # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Redistributions in source code must retain this top-level comment block. +# Plagiarizing this software to sidestep the license obligations is illegal. # # Contact information: -# +# # -#----------------------------------------------------------------------------- +#============================================================================= +## +# @date Last updated on: 2022-01-27 +# @version Last updated for version: 7.0.0 +# +# @file +# @brief QUTest Python scripting support (implementation) +# @ingroup qutest import socket import struct @@ -56,7 +52,7 @@ # https://www.state-machine.com/qtools/qutest_script.html # class QUTest: - VERSION = 694 + VERSION = 700 # class variables _host_exe = "" @@ -84,17 +80,19 @@ class QUTest: _OPT_NORESET = 0x01 # output strings with decorations (colors/backgrounds) - _STR_TEST_PASS = "PASS" # no decorations - _STR_TEST_FAIL = "\033[1;91mFAIL\033[0m" - _STR_ERR1 = "\033[41m\033[37m" # WHITE on RED - _STR_ERR2 = "\033[0m" # expectation end DEFAULT - _STR_EXP1 = "\033[44m\033[37m" # WHITE on BLUE - _STR_EXP2 = "\033[0m" # expectation end DEFAULT - _STR_EXC1 = "\033[31m" # exception text begin RED - _STR_EXC2 = "\033[0m" # exception text end DEFAULT - _STR_FINAL_OK = "\033[42m \033[30m OK \033[0m" - _STR_FINAL_FAIL = "\033[41m \033[1;37m FAIL \033[0m" - _STR_QSPY_FAIL = "\033[1;91mFAIL\033[0m" + _STR_TEST_PASS = "\x1b[32mPASS\x1b[0m" # GREEN on DEFAULT + _STR_TEST_FAIL = "\x1b[31;1mFAIL\x1b[0m" # B-RED on DEFAULT + _STR_ERR1 = "\x1b[41m\x1b[37m" # WHITE on RED + _STR_ERR2 = "\x1b[0m" # expectation end DEFAULT + _STR_EXP1 = "\x1b[44m\x1b[37m" # WHITE on BLUE + _STR_EXP2 = "\x1b[0m" # expectation end DEFAULT + _STR_EXC1 = "\x1b[31m" # exception text begin RED + _STR_EXC2 = "\x1b[0m" # exception text end DEFAULT + _STR_GRP1 = "\x1b[32;1m" # test-group text begin B-YELLOW + _STR_GRP2 = "\x1b[0m" # test-group test end DEFAULT + _STR_FINAL_OK = "\x1b[42m\x1b[30m OK \x1b[0m" + _STR_FINAL_FAIL = "\x1b[41m\x1b[1;37m FAIL \x1b[0m" + _STR_QSPY_FAIL = "\x1b[1;91mFAIL\x1b[0m" def __init__(self): QUTest._have_target = False @@ -724,8 +722,8 @@ def last_rec(self): # helper methods --------------------------------------------------------- @staticmethod def _run_script(fname): - print("--------------------------------------------------" - "\nGroup:", fname) + print("--------------------------------------------------") + print(QUTest._STR_GRP1 + "Group:" + fname + QUTest._STR_GRP2) QUTest._num_groups += 1 err = 0 # assume no errors diff --git a/qutest/qutest_dsl.py b/qutest/qutest_dsl.py index d50e19c..54d70b2 100644 --- a/qutest/qutest_dsl.py +++ b/qutest/qutest_dsl.py @@ -1,57 +1,37 @@ -## -# @file -# @ingroup qutest -# @brief QUTest unit testing harness support for Python scripting. -# -# @description -# The Python module "qutest.py" defines a small Domain Specific Language -# (DSL) for writing test scripts in Python. This script also implements a -# console-based ("headless") front-end to the QSPY back-and for running -# such user tests. -# -# @usage -# `python /qutest.py [-x] [test-scripts] [host_exe] [host[:udp_port]] [tcp_port]` -# -# or +#============================================================================= +# QUTest Python scripting support +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # -# `qutest [-x] [test-scripts] [host_exe] [host[:udp_port]] [tcp_port]` +# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial # -#----------------------------------------------------------------------------- -# Product: QUTest Python scripting (requires Python 3.3+) -# Last updated for version 6.9.5 -# Last updated on 2021-09-17 +# This software is dual-licensed under the terms of the open source GNU +# General Public License version 3 (or any later version), or alternatively, +# under the terms of one of the closed source Quantum Leaps commercial +# licenses. # -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software +# The terms of the open source GNU General Public License version 3 +# can be found at: # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# The terms of the closed source Quantum Leaps commercial licenses +# can be found at: # -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Redistributions in source code must retain this top-level comment block. +# Plagiarizing this software to sidestep the license obligations is illegal. # # Contact information: -# +# # -#----------------------------------------------------------------------------- +#============================================================================= +## +# @date Last updated on: 2022-01-27 +# @version Last updated for version: 7.0.0 +# +# @file +# @brief QUTest Python scripting support (documentation) +# @ingroup qutest ## @brief current version of the Python QUTest interface -VERSION = 694 +VERSION = 700 ## @brief include python code in a test script # @description diff --git a/qutest/setup.py b/qutest/setup.py index ed6b025..237214d 100644 --- a/qutest/setup.py +++ b/qutest/setup.py @@ -9,7 +9,7 @@ setup( name="qutest", - version="6.9.4", + version="7.0.0", author="Quantum Leaps", author_email="info@state-machine.com", description="QUTest Python scripting support",