diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2013-05-21 15:16:29 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2013-05-21 15:16:59 +0900 |
commit | c198c0a82526292ed31a37ae837185f2e679e844 (patch) | |
tree | d5794b9406f9d9da5b8ce416a7e2a10d12ace67b |
Initial commit
-rw-r--r-- | COPYING | 674 | ||||
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | EXCEPTION | 11 | ||||
-rw-r--r-- | board/board-fst-01.h | 20 | ||||
-rw-r--r-- | board/board-stm8s-discovery.h | 16 | ||||
-rw-r--r-- | chopstx.c | 813 | ||||
-rw-r--r-- | chopstx.h | 88 | ||||
-rw-r--r-- | chopstx.png | bin | 0 -> 16318 bytes | |||
-rw-r--r-- | chopstx.svg | 156 | ||||
-rw-r--r-- | entry.c | 340 | ||||
-rw-r--r-- | example/Makefile | 31 | ||||
-rw-r--r-- | example/aes-constant-ft.c | 145 | ||||
-rw-r--r-- | example/sample.c | 138 | ||||
-rw-r--r-- | example/sample.ld | 142 | ||||
-rw-r--r-- | example/sys.c | 600 | ||||
-rw-r--r-- | example/sys.h | 97 | ||||
-rw-r--r-- | rules.mk | 51 |
17 files changed, 3326 insertions, 0 deletions
@@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 <http://www.gnu.org/licenses/>. + +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: + + <program> Copyright (C) <year> <name of author> + 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 +<http://www.gnu.org/licenses/>. + + 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 +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e8f77e2 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4 @@ +2013-05-21 Niibe Yutaka <gniibe@fsij.org> + + * Initial commit. + diff --git a/EXCEPTION b/EXCEPTION new file mode 100644 index 0000000..1fb1de2 --- /dev/null +++ b/EXCEPTION @@ -0,0 +1,11 @@ +For released versions of Chopstx, it is OK to distribute a binary +without the copy of the GNU GPL. + +Legally speaking: + +As additional permission under GNU GPL version 3 section 7, you may +distribute non-source form of the code without the copy of the GNU GPL +normally required by section 4, provided you accompany the license +notice and a URL through which recipients can access the Corresponding +Source. +-- diff --git a/board/board-fst-01.h b/board/board-fst-01.h new file mode 100644 index 0000000..c9ec367 --- /dev/null +++ b/board/board-fst-01.h @@ -0,0 +1,20 @@ +#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 +#define STM32_PLLMUL_VALUE 6 +#define STM32_HSECLK 12000000 + +#define GPIO_USB_SET_TO_ENABLE 10 +#define GPIO_LED_SET_TO_EMIT 0 + +#define VAL_GPIO_ODR 0xFFFFE7FD +#define VAL_GPIO_CRL 0xBBB38888 /* PA7...PA0 */ +#define VAL_GPIO_CRH 0x88811388 /* PA15...PA8 */ + +#define VAL_GPIO_LED_ODR 0xFFFFFFFF +#define VAL_GPIO_LED_CRL 0x88888883 /* PA7...PA0 */ +#define VAL_GPIO_LED_CRH 0x88888888 /* PA15...PA8 */ + +#define GPIO_USB_BASE GPIOA_BASE +#define GPIO_LED_BASE GPIOB_BASE + +#define RCC_APB2ENR_IOP_EN (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN) +#define RCC_APB2RSTR_IOP_RST (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST) diff --git a/board/board-stm8s-discovery.h b/board/board-stm8s-discovery.h new file mode 100644 index 0000000..6be488a --- /dev/null +++ b/board/board-stm8s-discovery.h @@ -0,0 +1,16 @@ +#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 +#define STM32_PLLMUL_VALUE 9 +#define STM32_HSECLK 8000000 + +#undef GPIO_USB_CLEAR_TO_ENABLE +#define GPIO_LED_SET_TO_EMIT 8 + +#define VAL_GPIO_ODR 0xFFFFE7FF +#define VAL_GPIO_CRL 0x88888888 /* PA7...PA0 */ +#define VAL_GPIO_CRH 0x88811881 /* PA15...PA8 */ + +#define GPIO_USB_BASE GPIOA_BASE +#define GPIO_LED_BASE GPIOA_BASE + +#define RCC_APB2ENR_IOP_EN (RCC_APB2ENR_IOPAEN) +#define RCC_APB2RSTR_IOP_RST (RCC_APB2RSTR_IOPARST) diff --git a/chopstx.c b/chopstx.c new file mode 100644 index 0000000..1c8a5a1 --- /dev/null +++ b/chopstx.c @@ -0,0 +1,813 @@ +/* + * chopstx.c - Threads and only threads. + * + * Copyright (C) 2013 Flying Stone Technology + * Author: NIIBE Yutaka <gniibe@fsij.org> + * + * This file is a part of Chopstx, a thread library for embedded. + * + * Chopstx 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. + * + * Chopstx 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 <http://www.gnu.org/licenses/>. + * + * A special exception to the GNU GPL may be applied for a specific + * case. See the file EXCEPTION for full details. + * + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <chopstx.h> + +/* RUNNING: the current thread. */ +struct chx_thread *running; + +/* Use this when we support round robin scheduling. */ +#define PREEMPTION_USEC (1000*MHZ) /* 1ms */ + +/* Double linked list operations. */ +struct chx_dll { + struct chx_thread *next, *prev; +}; + + +/* READY: priority queue. */ +struct chx_ready { + struct chx_thread *next, *prev; + struct chx_spinlock lock; +}; + +static struct chx_ready q_ready; + +struct chx_timer { + struct chx_thread *next, *prev; + struct chx_spinlock lock; +}; + +/* threads waiting for timer. */ +static struct chx_timer q_timer; + +/* XXX: q_exit; Queue for threads already exited. */ + +/* Forward declaration(s). */ +static void chx_preempt (void); + + +/**************/ +static void chx_LOCK (struct chx_spinlock *lk) +{ + (void)lk; +} + +static void chx_UNLOCK (struct chx_spinlock *lk) +{ + (void)lk; +} + +/* The thread context: specific to ARM Cortex-M3 now. */ +struct tcontext { + uint32_t reg[9]; /* r4, r5, r6, r7, r8, r9, r10, r11, r13 */ +}; + +/* Saved registers on the stack. */ +struct chx_stack_regs { + uint32_t reg[8]; /* r0, r1, r2, r3, r12, lr, pc, xpsr */ +}; + +/* + * Constants for ARM. + */ +#define REG_SP 8 + +#define REG_R0 0 +#define REG_LR 5 +#define REG_PC 6 +#define REG_XPSR 7 + +#define INITIAL_XPSR 0x01000000 /* T=1 */ + +/* + * SysTick registers. + */ +static volatile uint32_t *const SYST_CSR = (uint32_t *const)0xE000E010; +static volatile uint32_t *const SYST_RVR = (uint32_t *const)0xE000E014; +static volatile uint32_t *const SYST_CVR = (uint32_t *const)0xE000E018; + +#define MHZ 72 + +static uint32_t usec_to_ticks (uint32_t usec) +{ + return usec * MHZ; +} +/**************/ + +struct chx_thread { + struct chx_thread *next, *prev; + struct tcontext tc; + uint16_t prio; + uint16_t prio_orig; + uint32_t v; + struct chx_mtx *mutex_list; +} __attribute__((packed)); + + +/* + * Double linked list handling. + */ + +static int +ll_empty (void *head) +{ + struct chx_thread *l = (struct chx_thread *)head; + + return (struct chx_thread *)l == l->next; +} + +static struct chx_thread * +ll_dequeue (struct chx_thread *tp) +{ + struct chx_thread *tp0 = tp; + + tp->next->prev = tp->prev; + tp->prev->next = tp->next; + return tp0; +} + +static void +ll_insert (struct chx_thread *tp0, void *head) +{ + struct chx_thread *tp = (struct chx_thread *)head; + + tp0->next = tp; + tp0->prev = tp->prev; + tp->prev->next = tp0; + tp->prev = tp0; +} + + +static struct chx_thread * +ll_pop (void *head) +{ + struct chx_thread *l = (struct chx_thread *)head; + struct chx_thread *tp0 = l->next; + + if (tp0 == l) + return NULL; + + return ll_dequeue (tp0); +} + +static void +ll_prio_push (struct chx_thread *tp0, void *head) +{ + struct chx_thread *l = (struct chx_thread *)head; + struct chx_thread *tp; + + for (tp = l->next; tp != l; tp = tp->next) + if (tp->prio <= tp0->prio) + break; + + ll_insert (tp0, tp); +} + +static void +ll_prio_enqueue (struct chx_thread *tp0, void *head) +{ + struct chx_thread *l = (struct chx_thread *)head; + struct chx_thread *tp; + + for (tp = l->next; tp != l; tp = tp->next) + if (tp->prio < tp0->prio) + break; + + ll_insert (tp0, tp); +} + + +/* + * Thread status encoded in ->v. + */ +#define THREAD_WAIT_MTX 0x00000001 +#define THREAD_WAIT_CND 0x00000002 +#define THREAD_WAITTIME 0x00000003 + +#define THREAD_RUNNING 0x00000000 +#define THREAD_WAIT_INT 0x00000004 +#define THREAD_EXITED 0x00000008 +#define THREAD_READY 0x0000000C + +static uint32_t +chx_ready_pop (void) +{ + struct chx_thread *tp; + + chx_LOCK (&q_ready.lock); + tp = ll_pop (&q_ready); + if (tp) + tp->v = THREAD_RUNNING; + chx_UNLOCK (&q_ready.lock); + + return (uint32_t)tp; +} + + +static void +chx_ready_push (struct chx_thread *t) +{ + chx_LOCK (&q_ready.lock); + t->v = THREAD_READY; + ll_prio_push (t, &q_ready); + chx_UNLOCK (&q_ready.lock); +} + + +static void +chx_ready_enqueue (struct chx_thread *t) +{ + chx_LOCK (&q_ready.lock); + t->v = THREAD_READY; + ll_prio_enqueue (t, &q_ready); + chx_UNLOCK (&q_ready.lock); +} + +/* Registers on stack (PSP): r0, r1, r2, r3, r12, lr, pc, xpsr */ +static void __attribute__ ((naked,used)) +sched (void) +{ + register uint32_t r0 asm ("r0"); + + asm volatile ("cpsid i" : : : "memory"); + + r0 = chx_ready_pop (); + + asm volatile (/* Now, r0 points to the thread to be switched. */ + /* Put it to *running. */ + "ldr r1, =running\n\t" + /* Update running. */ + "str r0, [r1]\n\t" + "cbz r0, 3f\n\t" + /**/ + "str r0, [r0]\n\t" + "str r0, [r0, 4]\n\t" + "cpsie i\n\t" /* Unmask interrupts. */ + "add r0, #8\n\t" + "ldm r0!, {r4, r5, r6, r7}\n\t" + "ldr r8, [r0], 4\n\t" + "ldr r9, [r0], 4\n\t" + "ldr r10, [r0], 4\n\t" + "ldr r11, [r0], 4\n\t" + "ldr r1, [r0]\n\t" + "msr PSP, r1\n\t" + "mov r0, #-1\n\t" + "sub r0, #2\n\t" /* EXC_RETURN to a thread with PSP */ + "bx r0\n" + "3:\n\t" + "cpsie i\n\t" /* Unmask interrupts. */ + /* Spawn an IDLE thread. */ + "ldr r0, =__main_stack_end__\n\t" + "msr MSP, r0\n\t" + "mov r0, #0\n\t" + "mov r1, #0\n\t" + "ldr r2, =idle\n\t" /* PC = idle */ + "mov r3, #0x01000000\n\t" /* xPSR = T-flag set (Thumb) */ + "push {r0, r1, r2, r3}\n\t" + "mov r0, #0\n\t" + "mov r1, #0\n\t" + "mov r2, #0\n\t" + "mov r3, #0\n\t" + "push {r0, r1, r2, r3}\n" + "mov r0, #-1\n\t" + "sub r0, #6\n\t" /* EXC_RETURN to a thread with MSP */ + "bx r0\n" + : /* no output */ : "r" (r0) : "memory"); +} + +void __attribute__ ((naked)) +preempt (void) +{ + register uint32_t r0 asm ("r0"); + + asm volatile ("ldr r1, =running\n\t" + "ldr r0, [r1]\n\t" + "cbnz r0, 0f\n\t" + /* It's idle which was preempted. */ + "ldr r1, =__main_stack_end__\n\t" + "msr MSP, r1\n\t" + "b sched\n" + "0:\n\t" + "ldr r2, [r0, 48]\n\t" /* Check ->v to avoid RACE. */ + "cbz r2, 1f\n\t" + /* RUNNING is busy on transition, do nothing. */ + "bx lr\n" + "1:\n\t" + "add r2, r0, #8\n\t" + /* Save registers onto CHX_THREAD struct. */ + "stm r2!, {r4, r5, r6, r7}\n\t" + "mov r3, r8\n\t" + "mov r4, r9\n\t" + "mov r5, r10\n\t" + "mov r6, r11\n\t" + "mrs r7, PSP\n\t" /* r13(=SP) in user space. */ + "stm r2, {r3, r4, r5, r6, r7}" + : "=r" (r0): /* no input */ : "memory"); + + asm volatile ("cpsid i" : : : "memory"); + chx_ready_push ((struct chx_thread *)r0); + asm volatile ("ldr r1, =running\n\t" + "mov r2, #0\n\t" + "str r2, [r1]\n\t" /* running := NULL */ + "cpsie i" /* Unmask interrupts. */ + : /* no output */ : /* no input */ : "memory"); + + asm volatile ("b sched" + : /* no output */: /* no input */ : "memory"); +} + + +/* system call: sched */ +void __attribute__ ((naked)) +svc (void) +{ + register uint32_t r0 asm ("r0"); + register uint32_t orig_r0 asm ("r2"); + + asm volatile ("ldr r1, =running\n\t" + "ldr r0, [r1]\n\t" + "add r2, r0, #8\n\t" + /* Save registers onto CHX_THREAD struct. */ + "stm r2!, {r4, r5, r6, r7}\n\t" + "mov r3, r8\n\t" + "mov r4, r9\n\t" + "mov r5, r10\n\t" + "mov r6, r11\n\t" + "mrs r7, PSP\n\t" /* r13(=SP) in user space. */ + "stm r2, {r3, r4, r5, r6, r7}\n\t" + "ldr r2, [r7]" + : "=r" (r0), "=r" (orig_r0) : /* no input */ : "memory"); + + if (orig_r0) + { + asm volatile ("cpsid i" : : : "memory"); + chx_ready_enqueue ((struct chx_thread *)r0); + asm volatile ("ldr r1, =running\n\t" + "mov r2, #0\n\t" + "str r2, [r1]\n\t" /* running := NULL */ + "cpsie i" /* Unmask interrupts. */ + : /* no output */ : /* no input */ : "memory"); + } + + asm volatile ("b sched" + : /* no output */: /* no input */ : "memory"); +} + + +static void +chx_set_timer (struct chx_thread *q, uint32_t ticks) +{ + if (q == (struct chx_thread *)&q_timer) + { + *SYST_RVR = ticks; + *SYST_CVR = 0; /* write (any) to clear the counter to reload. */ + *SYST_RVR = 0; + } + else + q->v = (ticks<<8)|THREAD_WAITTIME; +} + +static void +chx_timer_insert (struct chx_thread *tp, uint32_t usec) +{ + uint32_t ticks = usec_to_ticks (usec); + uint32_t next_ticks = *SYST_CVR; + struct chx_thread *q; + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&q_timer.lock); + + for (q = q_timer.next; q != (struct chx_thread *)&q_timer; q = q->next) + { + if (ticks < next_ticks) + { + ll_insert (tp, q); + chx_set_timer (tp->prev, ticks); + chx_set_timer (tp, (next_ticks - ticks)); + break; + } + else + { + ticks -= next_ticks; + next_ticks = (q->v >> 8); + } + } + + if (q == (struct chx_thread *)&q_timer) + { + ll_insert (tp, q); + chx_set_timer (tp->prev, ticks); + chx_set_timer (tp, 1); /* Non-zero for the last entry. */ + } + chx_UNLOCK (&q_timer.lock); + asm volatile ("cpsie i" : : : "memory"); +} + + +void +chx_timer_expired (void) +{ + struct chx_thread *t; + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&q_timer.lock); + if ((t = ll_pop (&q_timer))) + { + uint32_t next_tick = t->v >> 8; + + chx_ready_enqueue (t); + + if (!ll_empty (&q_timer)) + { + struct chx_thread *t_next; + + for (t = q_timer.next; + t != (struct chx_thread *)&q_timer && next_tick == 0; + t = t_next) + { + next_tick = (t->v >> 8); + t_next = t->next; + ll_dequeue (t); + chx_ready_enqueue (t); + } + + if (!ll_empty (&q_timer)) + chx_set_timer ((struct chx_thread *)&q_timer, next_tick); + } + } + + chx_preempt (); + chx_UNLOCK (&q_timer.lock); + asm volatile ("cpsie i" : : : "memory"); +} + + +static void +chx_enable_intr (uint8_t irq_num) +{ +} + +static void +chx_disable_intr (uint8_t irq_num) +{ +} + +void +chx_handle_intr (chopstix_intr_t *intr) +{ + chx_disable_intr (intr->irq_num); + asm volatile ("cpsid i" : : : "memory"); + intr->ready++; + if (intr->t) + { + chx_ready_enqueue (intr->t); + chx_preempt (); + } + asm volatile ("cpsie i" : : : "memory"); +} + +void +chx_systick_init (void) +{ + *SYST_RVR = 0; + *SYST_CVR = 0; + *SYST_CSR = 7; +} + +#define PRIO_DEFAULT 1 + +void +chx_init (struct chx_thread *tp) +{ + memset (&tp->tc, 0, sizeof (tp->tc)); + q_ready.next = q_ready.prev = (struct chx_thread *)&q_ready; + q_timer.next = q_timer.prev = (struct chx_thread *)&q_timer; + tp->prio_orig = tp->prio = PRIO_DEFAULT; + tp->next = tp->prev = tp; + tp->mutex_list = NULL; + tp->v = THREAD_RUNNING; + + running = tp; +} + + +static void +chx_preempt (void) +{ + static volatile uint32_t *const ICSR = (uint32_t *const)0xE000ED04; + + *ICSR = (1 << 28); + asm volatile ("" : : : "memory"); +} + +static void +chx_sched (void) +{ + register uint32_t r0 asm ("r0") = 0; + + asm volatile ("svc #0" : : "r" (r0) : "memory"); +} + +static void +chx_yield (void) +{ + register uint32_t r0 asm ("r0") = 1; + + asm volatile ("svc #0" : : "r" (r0) : "memory"); +} + +void +chopstx_attr_init (chopstx_attr_t *attr) +{ + attr->prio = PRIO_DEFAULT; + attr->addr = 0; + attr->size = 0; +} + +void +chopstx_attr_setschedparam (chopstx_attr_t *attr, uint8_t prio) +{ + attr->prio = prio; +} + +void +chopstx_attr_setstack (chopstx_attr_t *attr, uint32_t addr, size_t size) +{ + attr->addr = addr; + attr->size = size; +} + +void +chopstx_create (chopstx_t *thd, const chopstx_attr_t *attr, + void *(thread_entry) (void *), void *arg) +{ + struct chx_thread *tp; + void *stack; + struct chx_stack_regs *p; + + if (attr->size < sizeof (struct chx_thread) + 8 * sizeof (uint32_t)) + return; + + stack = (void *)(attr->addr + attr->size - sizeof (struct chx_thread) + - sizeof (struct chx_stack_regs)); + memset (stack, 0, sizeof (struct chx_stack_regs)); + p = (struct chx_stack_regs *)stack; + p->reg[REG_R0] = (uint32_t)arg; + p->reg[REG_LR] = 0; /* XXX: address of exit??? */ + p->reg[REG_PC] = (uint32_t)thread_entry; + p->reg[REG_XPSR] = INITIAL_XPSR; + + tp = (struct chx_thread *)(stack + sizeof (struct chx_stack_regs)); + memset (&tp->tc, 0, sizeof (tp->tc)); + tp->prio_orig = tp->prio = attr->prio; + tp->tc.reg[REG_SP] = (uint32_t)stack; + tp->next = tp->prev = tp; + tp->mutex_list = NULL; + tp->v = THREAD_EXITED; + *thd = (uint32_t)tp; + + asm volatile ("cpsid i" : : : "memory"); + chx_ready_enqueue (tp); + asm volatile ("cpsie i" : : : "memory"); + if (tp->prio > running->prio) + chx_yield (); +} + + +void +chopstx_usleep (uint32_t usec) +{ + while (usec) + { + uint32_t usec0 = (usec > 200*1000) ? 200*1000: usec; + + chx_timer_insert (running, usec0); + chx_sched (); + + usec -= usec0; + } +} + + +void +chopstx_mutex_init (chopstx_mutex_t *mutex) +{ + mutex->q.next = mutex->q.prev = (struct chx_thread *)mutex; + mutex->list = NULL; +} + +void +chopstx_mutex_lock (chopstx_mutex_t *mutex) +{ + while (1) + { + struct chx_thread *t = running; + chopstx_mutex_t *m; + struct chx_thread *owner; + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&mutex->lock); + if (mutex->owner == NULL) + { + /* The mutex is acquired. */ + mutex->owner = t; + mutex->list = t->mutex_list; + t->mutex_list = mutex; + chx_UNLOCK (&mutex->lock); + asm volatile ("cpsie i" : : : "memory"); + return; + } + + m = mutex; + owner = m->owner; + while (1) + { + owner->prio = t->prio; + if (owner->v == THREAD_READY) + { + ll_prio_enqueue (ll_dequeue (owner), &q_ready); + break; + } + else if ((owner->v & 0x03) == THREAD_WAIT_MTX) + { + m = (chopstx_mutex_t *)(owner->v & ~0x03); + + ll_prio_enqueue (ll_dequeue (owner), m); + owner = m->owner; + continue; + } + else if ((owner->v & 0x03) == THREAD_WAIT_CND) + { + chopstx_cond_t *cnd = (chopstx_cond_t *)(owner->v & ~0x03); + + ll_prio_enqueue (ll_dequeue (owner), cnd); + break; + } + else + break; + /* XXX: RUNNING and SMP??? */ + } + + ll_prio_enqueue (t, &mutex->q); + t->v = (uint32_t)mutex | THREAD_WAIT_MTX; + chx_UNLOCK (&mutex->lock); + asm volatile ("cpsie i" : : : "memory"); + chx_sched (); + } +} + +void +chopstx_mutex_unlock (chopstx_mutex_t *mutex) +{ + struct chx_thread *t; + int yield = 0; + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&mutex->lock); + mutex->owner = NULL; + running->mutex_list = mutex->list; + mutex->list = NULL; + + t = ll_pop (&mutex->q); + if (t) + { + uint16_t newprio = running->prio_orig; + chopstx_mutex_t *m; + + chx_ready_enqueue (t); + + /* Examine mutexes we hold, and determine new priority for running. */ + for (m = running->mutex_list; m; m = m->list) + if (!ll_empty (&m->q) && m->q.next->prio > newprio) + newprio = m->q.next->prio; + /* Then, assign it. */ + running->prio = newprio; + + if (t->prio > running->prio) + yield = 1; + } + + chx_UNLOCK (&mutex->lock); + asm volatile ("cpsie i" : : : "memory"); + if (yield) + chx_yield (); +} + + +void +chopstx_cond_init (chopstx_cond_t *cond) +{ + cond->q.next = cond->q.prev = (struct chx_thread *)cond; +} + +void +chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex) +{ + struct chx_thread *t = running; + + if (mutex) + chopstx_mutex_unlock (mutex); + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&cond->lock); + ll_prio_enqueue (t, &cond->q); + t->v = (uint32_t)cond | THREAD_WAIT_CND; + chx_UNLOCK (&cond->lock); + asm volatile ("cpsie i" : : : "memory"); + + chx_sched (); + + if (mutex) + chopstx_mutex_lock (mutex); +} + +void +chopstx_cond_signal (chopstx_cond_t *cond) +{ + struct chx_thread *t; + int yield = 0; + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&cond->lock); + t = ll_pop (&cond->q); + if (t) + { + chx_ready_enqueue (t); + if (t->prio > running->prio) + yield = 1; + } + chx_UNLOCK (&cond->lock); + asm volatile ("cpsie i" : : : "memory"); + + if (yield) + chx_yield (); +} + +void +chopstx_cond_broadcast (chopstx_cond_t *cond) +{ + struct chx_thread *t; + int yield = 1; + + asm volatile ("cpsid i" : : : "memory"); + chx_LOCK (&cond->lock); + while ((t = ll_pop (&cond->q))) + { + chx_ready_enqueue (t); + if (t->prio > running->prio) + yield = 1; + } + chx_UNLOCK (&cond->lock); + asm volatile ("cpsie i" : : : "memory"); + if (yield) + chx_yield (); +} + + +#define MAX_INTR_NUM 16 + +chopstix_intr_t *intr_table[MAX_INTR_NUM]; + +void +chopstx_intr_register (chopstix_intr_t *intr, uint8_t irq_num) +{ + intr_table[irq_num] = intr; + intr->irq_num = irq_num; + intr->t = running; + intr->ready = 0; +} + + +void +chopstx_wait_intr (chopstix_intr_t *intr) +{ + chx_enable_intr (intr->irq_num); + asm volatile ("cpsid i" : : : "memory"); + while (intr->ready == 0) + { + intr->t = running; + running->v = THREAD_WAIT_INT; + asm volatile ("cpsie i" : : : "memory"); + chx_sched (); + asm volatile ("cpsid i" : : : "memory"); + } + intr->ready--; + asm volatile ("cpsie i" : : : "memory"); +} diff --git a/chopstx.h b/chopstx.h new file mode 100644 index 0000000..6ab9b87 --- /dev/null +++ b/chopstx.h @@ -0,0 +1,88 @@ +/* + * chopstx.h - Threads and only threads. + * + * Copyright (C) 2013 Flying Stone Technology + * Author: NIIBE Yutaka <gniibe@fsij.org> + * + * This file is a part of Chopstx, a thread library for embedded. + * + * Chopstx 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. + * + * Chopstx 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 <http://www.gnu.org/licenses/>. + * + * A special exception to the GNU GPL may be applied for a specific + * case. See the file EXCEPTION for full details. + * + */ + +typedef uint32_t chopstx_t; +struct struct_attr { uint32_t prio; uint32_t addr; size_t size; }; +typedef struct struct_attr chopstx_attr_t; + +void chopstx_attr_init (chopstx_attr_t *attr); + +/* NOTE: This signature is different to PTHREAD's one. */ +void chopstx_attr_setschedparam (chopstx_attr_t *attr, uint8_t prio); + +void chopstx_attr_setstack (chopstx_attr_t *attr, uint32_t addr, + size_t size); + +void chopstx_create (chopstx_t *thd, const chopstx_attr_t *attr, + void *(thread_entry) (void *), void *); + +void chopstx_usleep (uint32_t useconds); + +struct chx_spinlock { + /* nothing for uniprocessor. */ +}; + +typedef uint16_t chopstx_prio_t; +typedef struct chx_mtx { + struct { + struct chx_thread *next, *prev; + } q; + struct chx_spinlock lock; + struct chx_thread *owner; + struct chx_mtx *list; +} chopstx_mutex_t; + +/* NOTE: This signature is different to PTHREAD's one. */ +void chopstx_mutex_init (chopstx_mutex_t *mutex); + +void chopstx_mutex_lock (chopstx_mutex_t *mutex); + +void chopstx_mutex_unlock (chopstx_mutex_t *mutex); + +typedef struct chx_cond { + struct { + struct chx_thread *next, *prev; + } q; + struct chx_spinlock lock; +} chopstx_cond_t; + +/* NOTE: This signature is different to PTHREAD's one. */ +void chopstx_cond_init (chopstx_cond_t *cond); + +void chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex); +void chopstx_cond_signal (chopstx_cond_t *cond); +void chopstx_cond_broadcast (chopstx_cond_t *cond); + +typedef struct chx_intr { + struct chx_thread *t; + struct chx_spinlock lock; + uint8_t irq_num; + uint8_t ready; +} chopstix_intr_t; + +void chopstx_intr_register (chopstix_intr_t *intr, uint8_t irq_num); + +void chopstx_wait_intr (chopstix_intr_t *intr); diff --git a/chopstx.png b/chopstx.png Binary files differnew file mode 100644 index 0000000..5335dcc --- /dev/null +++ b/chopstx.png diff --git a/chopstx.svg b/chopstx.svg new file mode 100644 index 0000000..61ab6ae --- /dev/null +++ b/chopstx.svg @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + id="svg2" + version="1.1" + inkscape:version="0.48.3.1 r9886" + sodipodi:docname="chopstx.svg" + inkscape:export-filename="chopstx.png" + inkscape:export-xdpi="36" + inkscape:export-ydpi="36"> + <defs + id="defs4"> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lend" + style="overflow:visible;"> + <path + id="path3762" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.5" + inkscape:cx="459.21448" + inkscape:cy="471.91176" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + showborder="true" + inkscape:window-width="906" + inkscape:window-height="719" + inkscape:window-x="1" + inkscape:window-y="24" + inkscape:window-maximized="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g4305" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <g + transform="translate(-190,-14)" + id="g4236" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <g + id="g4199" + transform="translate(186,0)" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <path + style="fill-rule:evenodd;stroke:none;stroke-width:0.10000000000000001;fill:#164122;fill-opacity:1;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="M 245.5395,924.99188 237.95004,940.17081 274,915.50504 l -43.63943,1.89737 z" + id="path4205" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + </g> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#164122;fill-opacity:1;stroke:none;stroke-width:0.10000000000000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="m 451.30156,863.09375 c -12.29154,0.67964 -24.56513,6.31983 -32.55093,15.74368 -6.74505,8.98414 -14.74647,19.18713 -13.27855,31.13292 0.81861,7.53179 4.96334,15.52377 12.3578,18.2841 6.5527,1.56145 12.36737,-2.87335 18.24105,-4.87414 2.46026,0.0325 7.79766,-5.57819 2.80659,-2.62717 -5.86212,3.04634 -12.09693,7.41598 -19.02815,6.20781 -6.67881,-2.45807 -10.67091,-9.57389 -11.94134,-16.2776 -1.65616,-6.85973 1.2677,-13.63117 5.02324,-19.23708 7.11677,-11.84162 18.63914,-21.98251 32.76069,-23.75581 14.13711,-2.23575 29.01952,1.81411 40.58636,10.08551 7.52021,5.28929 14.01916,12.81867 15.41858,22.18896 2.35212,12.95802 -5.71873,25.02827 -15.27391,32.93766 -9.57979,7.75126 -20.98736,12.8445 -32.4632,17.09918 -5.28833,-0.64073 -7.07207,5.94812 -4.23041,9.49281 0.54847,2.21012 1.09694,4.42025 1.64541,6.63037 18.79336,-6.7629 38.15989,-16.2698 49.24661,-33.6521 6.02058,-10.72278 10.41044,-23.35707 8.15467,-35.76217 -1.2356,-5.99366 -5.54747,-10.6846 -8.85242,-15.6466 -7.03785,-9.20338 -18.12594,-14.19792 -29.30714,-16.17859 -6.35088,-1.24159 -12.83528,-2.02773 -19.31495,-1.79174 z" + id="path4214" + inkscape:connector-curvature="0" /> + </g> + <g + id="g4236-1" + transform="translate(-297.33681,-120.22628)" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <g + id="g4199-2" + transform="translate(186,0)" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <path + style="fill-rule:evenodd;stroke:none;stroke-width:0.10000000000000001;fill:#164122;fill-opacity:1;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="M 245.5395,924.99188 237.95004,940.17081 274,915.50504 l -43.63943,1.89737 z" + id="path4205-7" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + </g> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#164122;fill-opacity:1;stroke:none;stroke-width:0.10000000000000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="m 451.30156,863.09375 c -12.29154,0.67964 -24.56513,6.31983 -32.55093,15.74368 -6.74505,8.98414 -14.74647,19.18713 -13.27855,31.13292 0.81861,7.53179 4.96334,15.52377 12.3578,18.2841 6.5527,1.56145 12.36737,-2.87335 18.24105,-4.87414 2.46026,0.0325 7.79766,-5.57819 2.80659,-2.62717 -5.86212,3.04634 -12.09693,7.41598 -19.02815,6.20781 -6.67881,-2.45807 -10.67091,-9.57389 -11.94134,-16.2776 -1.65616,-6.85973 1.2677,-13.63117 5.02324,-19.23708 7.11677,-11.84162 18.63914,-21.98251 32.76069,-23.75581 14.13711,-2.23575 29.01952,1.81411 40.58636,10.08551 7.52021,5.28929 14.01916,12.81867 15.41858,22.18896 2.35212,12.95802 -5.71873,25.02827 -15.27391,32.93766 -9.57979,7.75126 -20.98736,12.8445 -32.4632,17.09918 -5.28833,-0.64073 -7.07207,5.94812 -4.23041,9.49281 0.54847,2.21012 1.09694,4.42025 1.64541,6.63037 18.79336,-6.7629 38.15989,-16.2698 49.24661,-33.6521 6.02058,-10.72278 10.41044,-23.35707 8.15467,-35.76217 -1.2356,-5.99366 -5.54747,-10.6846 -8.85242,-15.6466 -7.03785,-9.20338 -18.12594,-14.19792 -29.30714,-16.17859 -6.35088,-1.24159 -12.83528,-2.02773 -19.31495,-1.79174 z" + id="path4214-1" + inkscape:connector-curvature="0" /> + </g> + <g + id="g4236-8" + transform="translate(-321.33681,5.77372)" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <g + id="g4199-5" + transform="translate(186,0)" + style="fill:#164122;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-dasharray:none"> + <path + style="fill-rule:evenodd;stroke:none;stroke-width:0.10000000000000001;fill:#164122;fill-opacity:1;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="M 245.5395,924.99188 237.95004,940.17081 274,915.50504 l -43.63943,1.89737 z" + id="path4205-1" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + </g> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#164122;fill-opacity:1;stroke:none;stroke-width:0.10000000000000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="m 451.30156,863.09375 c -12.29154,0.67964 -24.56513,6.31983 -32.55093,15.74368 -6.74505,8.98414 -14.74647,19.18713 -13.27855,31.13292 0.81861,7.53179 4.96334,15.52377 12.3578,18.2841 6.5527,1.56145 12.36737,-2.87335 18.24105,-4.87414 2.46026,0.0325 7.79766,-5.57819 2.80659,-2.62717 -5.86212,3.04634 -12.09693,7.41598 -19.02815,6.20781 -6.67881,-2.45807 -10.67091,-9.57389 -11.94134,-16.2776 -1.65616,-6.85973 1.2677,-13.63117 5.02324,-19.23708 7.11677,-11.84162 18.63914,-21.98251 32.76069,-23.75581 14.13711,-2.23575 29.01952,1.81411 40.58636,10.08551 7.52021,5.28929 14.01916,12.81867 15.41858,22.18896 2.35212,12.95802 -5.71873,25.02827 -15.27391,32.93766 -9.57979,7.75126 -20.98736,12.8445 -32.4632,17.09918 -5.28833,-0.64073 -7.07207,5.94812 -4.23041,9.49281 0.54847,2.21012 1.09694,4.42025 1.64541,6.63037 18.79336,-6.7629 38.15989,-16.2698 49.24661,-33.6521 6.02058,-10.72278 10.41044,-23.35707 8.15467,-35.76217 -1.2356,-5.99366 -5.54747,-10.6846 -8.85242,-15.6466 -7.03785,-9.20338 -18.12594,-14.19792 -29.30714,-16.17859 -6.35088,-1.24159 -12.83528,-2.02773 -19.31495,-1.79174 z" + id="path4214-3" + inkscape:connector-curvature="0" /> + </g> + </g> + <g + id="g4301" + transform="translate(8,-22)"> + <path + sodipodi:nodetypes="cccccc" + inkscape:connector-curvature="0" + id="path4281" + d="m 544,310.36218 -309,554 3,3 327,-545 -1,-14 z" + style="fill:#cd0000;fill-opacity:1;stroke:#000088;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cccccc" + inkscape:connector-curvature="0" + id="path4281-5" + d="m 478.99332,286.67888 -275.00872,571.63555 3.17555,2.81352 293.51899,-563.73807 -1.84294,-13.91415 z" + style="fill:#cd0000;fill-opacity:1;stroke:#000088;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + </g> + </g> +</svg> @@ -0,0 +1,340 @@ +/* + * entry.c - Entry routine when reset and interrupt vectors. + * + * Copyright (C) 2013 Flying Stone Technology + * Author: NIIBE Yutaka <gniibe@fsij.org> + * + * This file is a part of Chopstx, a thread library for embedded. + * + * Chopstx 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. + * + * Chopstx 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 <http://www.gnu.org/licenses/>. + * + * A special exception to the GNU GPL may be applied for a specific + * case. See the file EXCEPTION for full details. + * + */ + +#include <stdint.h> +#include <stdlib.h> +#include "sys.h" + +static void __attribute__ ((used)) +flash_unlock (void) +{ + (*vector[3]) (); +} + +#if 0 +static void __attribute__ ((used)) +clock_init (void) +{ + (*vector[16]) (); +} + +static void __attribute__ ((used)) +gpio_init (void) +{ + (*vector[17]) (); +} +#else +#include "board.h" + +#define STM32_SW_PLL (2 << 0) +#define STM32_PLLSRC_HSE (1 << 16) + +#define STM32_PLLXTPRE_DIV1 (0 << 17) +#define STM32_PLLXTPRE_DIV2 (1 << 17) + +#define STM32_HPRE_DIV1 (0 << 4) + +#define STM32_PPRE1_DIV2 (4 << 8) + +#define STM32_PPRE2_DIV1 (0 << 11) +#define STM32_PPRE2_DIV2 (4 << 11) + +#define STM32_ADCPRE_DIV4 (1 << 14) +#define STM32_ADCPRE_DIV6 (2 << 14) + +#define STM32_USBPRE_DIV1P5 (0 << 22) + +#define STM32_MCO_NOCLOCK (0 << 24) + +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_ADCPRE STM32_ADCPRE_DIV6 +#define STM32_MCOSEL STM32_MCO_NOCLOCK +#define STM32_USBPRE STM32_USBPRE_DIV1P5 + +#define STM32_PLLCLKIN (STM32_HSECLK / 1) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) +#define STM32_SYSCLK STM32_PLLCLKOUT +#define STM32_HCLK (STM32_SYSCLK / 1) + +#define STM32_FLASHBITS 0x00000012 + +#define PERIPH_BASE 0x40000000 +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) + +struct RCC { + volatile uint32_t CR; + volatile uint32_t CFGR; + volatile uint32_t CIR; + volatile uint32_t APB2RSTR; + volatile uint32_t APB1RSTR; + volatile uint32_t AHBENR; + volatile uint32_t APB2ENR; + volatile uint32_t APB1ENR; + volatile uint32_t BDCR; + volatile uint32_t CSR; +}; + +#define RCC_BASE (AHBPERIPH_BASE + 0x1000) +#define RCC ((struct RCC *)RCC_BASE) + +#define RCC_APB1ENR_USBEN 0x00800000 +#define RCC_APB1RSTR_USBRST 0x00800000 + +#define RCC_CR_HSION 0x00000001 +#define RCC_CR_HSIRDY 0x00000002 +#define RCC_CR_HSITRIM 0x000000F8 +#define RCC_CR_HSEON 0x00010000 +#define RCC_CR_HSERDY 0x00020000 +#define RCC_CR_PLLON 0x01000000 +#define RCC_CR_PLLRDY 0x02000000 + +#define RCC_CFGR_SWS 0x0000000C +#define RCC_CFGR_SWS_HSI 0x00000000 + +#define RCC_AHBENR_CRCEN 0x0040 + +struct FLASH { + volatile uint32_t ACR; + volatile uint32_t KEYR; + volatile uint32_t OPTKEYR; + volatile uint32_t SR; + volatile uint32_t CR; + volatile uint32_t AR; + volatile uint32_t RESERVED; + volatile uint32_t OBR; + volatile uint32_t WRPR; +}; + +#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) +#define FLASH ((struct FLASH *) FLASH_R_BASE) + +static void __attribute__((used)) +clock_init (void) +{ + /* HSI setup */ + RCC->CR |= RCC_CR_HSION; + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; + RCC->CFGR = 0; + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; + + /* HSE setup */ + RCC->CR |= RCC_CR_HSEON; + while (!(RCC->CR & RCC_CR_HSERDY)) + ; + + /* PLL setup */ + RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; + + /* Clock settings */ + RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE + | STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + + /* Flash setup */ + FLASH->ACR = STM32_FLASHBITS; + + /* CRC */ + RCC->AHBENR |= RCC_AHBENR_CRCEN; + + /* Switching on the configured clock source. */ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +} + +#define RCC_APB2ENR_IOPAEN 0x00000004 +#define RCC_APB2RSTR_IOPARST 0x00000004 +#define RCC_APB2ENR_IOPBEN 0x00000008 +#define RCC_APB2RSTR_IOPBRST 0x00000008 +#define RCC_APB2ENR_IOPCEN 0x00000010 +#define RCC_APB2RSTR_IOPCRST 0x00000010 +#define RCC_APB2ENR_IOPDEN 0x00000020 +#define RCC_APB2RSTR_IOPDRST 0x00000020 + + +struct GPIO { + volatile uint32_t CRL; + volatile uint32_t CRH; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t BRR; + volatile uint32_t LCKR; +}; + +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOD ((struct GPIO *) GPIOD_BASE) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define GPIOE ((struct GPIO *) GPIOE_BASE) + +#define GPIO_USB ((struct GPIO *) GPIO_USB_BASE) +#define GPIO_LED ((struct GPIO *) GPIO_LED_BASE) + +static void __attribute__((used)) +gpio_init (void) +{ + /* Enable GPIO clock. */ + RCC->APB2ENR |= RCC_APB2ENR_IOP_EN; + RCC->APB2RSTR = RCC_APB2RSTR_IOP_RST; + RCC->APB2RSTR = 0; + + GPIO_USB->ODR = VAL_GPIO_ODR; + GPIO_USB->CRH = VAL_GPIO_CRH; + GPIO_USB->CRL = VAL_GPIO_CRL; + +#if GPIO_USB_BASE != GPIO_LED_BASE + GPIO_LED->ODR = VAL_GPIO_LED_ODR; + GPIO_LED->CRH = VAL_GPIO_LED_CRH; + GPIO_LED->CRL = VAL_GPIO_LED_CRL; +#endif +} +#endif + + +static void nmi (void) +{ + for (;;); +} + +static void hard_fault (void) +{ + for (;;); +} + +static void mem_manage (void) +{ + for (;;); +} + +static void bus_fault (void) +{ + for (;;); +} + +static void usage_fault (void) +{ + for (;;); +} + +static void none (void) +{ +} + +/* + * This routine only changes PSP and not MSP. + */ +static __attribute__ ((naked,section(".text.startup.0"))) +void entry (void) +{ + asm volatile ("bl clock_init\n\t" + /* Clear BSS. Assume its size is > 0. */ + "mov r0, #0\n\t" + "ldr r1, =_bss_start\n\t" + "ldr r2, =_bss_end\n" + "0:\n\t" + "str r0, [r1], #4\n\t" + "cmp r2, r1\n\t" + "bhi 0b\n\t" + /* Switch to PSP. */ + "ldr r0, =__process0_stack_end__\n\t" + "sub r0, #56\n\t" + "msr PSP, r0\n\t" /* Process (main routine) stack */ + "mov r1, #2\n\t" + "msr CONTROL, r1\n\t" + "isb\n\t" + "bl chx_init\n\t" + "bl chx_systick_init\n\t" + "bl gpio_init\n\t" + /* Enable interrupts. */ + "mov r0, #0\n\t" + "msr BASEPRI, r0\n\t" + "cpsie i\n\t" + /* Call main. */ + "mov r1, r0\n\t" + "bl main\n" + "1:\n\t" + "b 1b" + : /* no output */ : /* no input */ : "memory"); +} + +void __attribute__((naked, used)) +idle (void) +{ + /* XXX: use WFI */ + for (;;); +} + + +typedef void (*handler)(void); +extern uint8_t __main_stack_end__; + +extern void svc (void); +extern void preempt (void); +extern void chx_timer_expired (void); + +handler vector_table[] __attribute__ ((section(".startup.vectors"))) = { + (handler)&__main_stack_end__, + entry, + nmi, /* nmi */ + hard_fault, /* hard fault */ + /* 0x10 */ + mem_manage, /* mem manage */ + bus_fault, /* bus fault */ + usage_fault, /* usage fault */ + none, + /* 0x20 */ + none, none, none, /* reserved */ + svc, /* SVCall */ + none, /* Debug */ + none, /* reserved */ + preempt, /* PendSV */ + chx_timer_expired, /* SysTick */ + /* 0x40 */ + none, none, none, none, none, none, none, none, + /* 0x60 */ + none, none, none, none, none, none, none, none, + /* 0x80 */ + none, none, none, none, + /* 0x90 */ + none, +}; diff --git a/example/Makefile b/example/Makefile new file mode 100644 index 0000000..085d42b --- /dev/null +++ b/example/Makefile @@ -0,0 +1,31 @@ +# Makefile for example application of Chopstx + +PROJECT = sample + +CHOPSTX = .. +LDSCRIPT= sample.ld +CSRC = sys.c aes-constant-ft.c sample.c + +################################### +CROSS = arm-none-eabi- +CC = $(CROSS)gcc +LD = $(CROSS)gcc +OBJCOPY = $(CROSS)objcopy + +MCU = cortex-m3 +CWARN = -Wall -Wextra -Wstrict-prototypes +DEFS = -DFREE_STANDING +OPT = -O3 -Os -g +LIBS = + +#################### +include ../rules.mk + +board.h: + @echo Please make a symbolic link \'board.h\' to a file in ../board; + @exit 1 + +sys.c: board.h + +distclean: clean + rm -f board.h diff --git a/example/aes-constant-ft.c b/example/aes-constant-ft.c new file mode 100644 index 0000000..21d1ba7 --- /dev/null +++ b/example/aes-constant-ft.c @@ -0,0 +1,145 @@ +/* + * aes-constant-ft.c - AES forward tables. + * + * We need something useful for the initial flash ROM page (4 Ki + * bytes), which cannot be modified after installation. Even after + * upgrade of the firmware, it stays intact. + * + * We decide to put 3/4 of AES forward tables to fill 3 Ki bytes, as + * its useful and it won't change. + * + * The code was taken from aes.c of PolarSSL version 0.14, and then, + * modified to add section names. + * + * Since this is just a data, it wouldn't be copyright-able, but the + * original auther would claim so. Thus, we put original copyright + * notice here. It is highly likely that there will be no such a + * thing for copyright. Nevertheless, we think that PolarSSL is good + * software to address here, and encourage people using it. + * + */ + +#include <stdint.h> + +/* + * Original copyright notice is below: + */ + +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +const uint32_t FT0[256] __attribute__((section(".sys.0"))) = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +const uint32_t FT1[256] __attribute__((section(".sys.1"))) = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +const uint32_t FT2[256] __attribute__((section(".sys.2"))) = { FT }; +#undef V + +#ifdef ORIGINAL_IMPLEMENTATION +#define V(a,b,c,d) 0x##d##a##b##c +const uint32_t FT3[256] = { FT }; +#undef V +#endif diff --git a/example/sample.c b/example/sample.c new file mode 100644 index 0000000..9441a57 --- /dev/null +++ b/example/sample.c @@ -0,0 +1,138 @@ +#include <stdint.h> +#include <stdlib.h> +#include <chopstx.h> +#include "sys.h" /* for set_led */ + +static chopstx_mutex_t mtx; +static chopstx_cond_t cnd0; +static chopstx_cond_t cnd1; +static chopstx_cond_t cnd_intr; + +static uint8_t u, v; +static uint8_t m; /* 0..100 */ + +static void * +pwm (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd0, &mtx); + chopstx_mutex_unlock (&mtx); + + while (1) + { + set_led (u&v); + chopstx_usleep (m); + set_led (0); + chopstx_usleep (100-m); + } + + return NULL; +} + +static void * +blk (void *arg) +{ + (void)arg; + + chopstx_mutex_lock (&mtx); + chopstx_cond_wait (&cnd1, &mtx); + chopstx_mutex_unlock (&mtx); + + while (1) + { + v = 0; + chopstx_usleep (200*1000); + v = 1; + chopstx_usleep (200*1000); + } + + return NULL; +} + +#define INTR_REQ_0 0 + +static void * +intr (void *arg) +{ + (void)arg; + chopstix_intr_t interrupt; + + chopstx_intr_register (&interrupt, INTR_REQ_0); + + while (1) + { + chopstx_wait_intr (&interrupt); + + /* process interrupt... */ + chopstx_usleep (200*1000); + } + + return NULL; +} + +#define PRIO_PWM 3 +#define PRIO_BLK 2 +#define PRIO_INTR 2 + +extern uint8_t __process1_stack_base__, __process1_stack_size__; +extern uint8_t __process2_stack_base__, __process2_stack_size__; +extern uint8_t __process3_stack_base__, __process3_stack_size__; + +const uint32_t __stackaddr_pwm = (uint32_t)&__process1_stack_base__; +const size_t __stacksize_pwm = (size_t)&__process1_stack_size__; + +const uint32_t __stackaddr_blk = (uint32_t)&__process2_stack_base__; +const size_t __stacksize_blk = (size_t)&__process2_stack_size__; + +const uint32_t __stackaddr_intr = (uint32_t)&__process3_stack_base__; +const size_t __stacksize_intr = (size_t)&__process3_stack_size__; + + +int +main (int argc, const char *argv[]) +{ + chopstx_t thd; + chopstx_attr_t attr; + + (void)argc; + (void)argv; + + chopstx_mutex_init (&mtx); + chopstx_cond_init (&cnd0); + chopstx_cond_init (&cnd1); + + m = 10; + + chopstx_attr_init (&attr); + chopstx_attr_setschedparam (&attr, PRIO_PWM); + chopstx_attr_setstack (&attr, __stackaddr_pwm, __stacksize_pwm); + + chopstx_create (&thd, &attr, pwm, NULL); + + chopstx_attr_setschedparam (&attr, PRIO_BLK); + chopstx_attr_setstack (&attr, __stackaddr_blk, __stacksize_blk); + + chopstx_create (&thd, &attr, blk, NULL); + + chopstx_attr_setschedparam (&attr, PRIO_INTR); + chopstx_attr_setstack (&attr, __stackaddr_intr, __stacksize_intr); + + chopstx_create (&thd, &attr, intr, NULL); + + chopstx_usleep (200*1000); + + chopstx_mutex_lock (&mtx); + chopstx_cond_signal (&cnd0); + chopstx_cond_signal (&cnd1); + chopstx_mutex_unlock (&mtx); + + while (1) + { + u ^= 1; + chopstx_usleep (200*1000*6); + } + + return 0; +} diff --git a/example/sample.ld b/example/sample.ld new file mode 100644 index 0000000..f98d789 --- /dev/null +++ b/example/sample.ld @@ -0,0 +1,142 @@ +/* + * ST32F103 memory setup. + */ +__main_stack_size__ = 0x0100; /* Exception handlers */ +__process0_stack_size__ = 0x0100; /* Main program */ +__process1_stack_size__ = 0x0100; /* first thread program */ +__process2_stack_size__ = 0x0100; /* second thread program */ +__process3_stack_size__ = 0x0100; /* third thread program */ + +MEMORY +{ + flash0 : org = 0x08000000, len = 4k + flash : org = 0x08000000+0x1000, len = 60k + ram : org = 0x20000000, len = 20k +} + +__flash_start__ = 0x08001000; +__flash_end__ = 0x08020000; + +__ram_start__ = ORIGIN(ram); +__ram_size__ = 20k; +__ram_end__ = __ram_start__ + __ram_size__; + +SECTIONS +{ + . = 0; + + .sys : ALIGN(16) SUBALIGN(16) + { + _sys = .; + KEEP(*(.vectors)) + . = ALIGN(16); + *(.sys.version) + build/sys.o(.text) + build/sys.o(.text.*) + build/sys.o(.rodata) + build/sys.o(.rodata.*) + . = ALIGN(1024); + *(.sys.0) + *(.sys.1) + *(.sys.2) + } > flash0 + + _text = .; + + .startup : ALIGN(128) SUBALIGN(128) + { + KEEP(*(.startup.vectors)) + . = ALIGN (16); + } > flash =0xffffffff + + .text : ALIGN(16) SUBALIGN(16) + { + *(.text.startup.*) + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.glue_7t) + *(.glue_7) + *(.gcc*) + } > flash + + .ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash + + .ARM.exidx : { + PROVIDE(__exidx_start = .); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + PROVIDE(__exidx_end = .); + } > flash + + .eh_frame_hdr : {*(.eh_frame_hdr)} > flash + + .eh_frame : ONLY_IF_RO {*(.eh_frame)} > flash + + .textalign : ONLY_IF_RO { . = ALIGN(8); } > flash + + _etext = .; + _textdata = _etext; + + .process_stack : + { + . = ALIGN(8); + __process3_stack_base__ = .; + . += __process3_stack_size__; + . = ALIGN(8); + __process_stack3_end__ = .; + __process2_stack_base__ = .; + . += __process2_stack_size__; + . = ALIGN(8); + __process_stack2_end__ = .; + __process1_stack_base__ = .; + . += __process1_stack_size__; + . = ALIGN(8); + __process_stack1_end__ = .; + __process0_stack_base__ = .; + . += __process0_stack_size__; + . = ALIGN(8); + __process0_stack_end__ = .; + } > ram + + .main_stack : + { + . = ALIGN(8); + __main_stack_base__ = .; + . += __main_stack_size__; + . = ALIGN(8); + __main_stack_end__ = .; + } > ram + + .data : + { + . = ALIGN(4); + PROVIDE(_data = .); + *(.data) + . = ALIGN(4); + *(.data.*) + . = ALIGN(4); + *(.ramtext) + . = ALIGN(4); + PROVIDE(_edata = .); + } > ram AT > flash + + .bss : + { + . = ALIGN(4); + PROVIDE(_bss_start = .); + *(.bss) + . = ALIGN(4); + *(.bss.*) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + PROVIDE(_bss_end = .); + } > ram + + PROVIDE(end = .); + _end = .; +} + +__heap_base__ = _end; +__heap_end__ = __ram_end__; diff --git a/example/sys.c b/example/sys.c new file mode 100644 index 0000000..1e6c030 --- /dev/null +++ b/example/sys.c @@ -0,0 +1,600 @@ +/* + * sys.c - system routines for the initial page for STM32F103. + * + * Copyright (C) 2013 Flying Stone Technology + * Author: NIIBE Yutaka <gniibe@fsij.org> + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + * + * When the flash ROM is protected, we cannot modify the initial page. + * We put some system routines (which is useful for any program) here. + */ + +#include <stdint.h> +#include <stdlib.h> +#include "board.h" + + +#define CORTEX_PRIORITY_BITS 4 +#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS)) +#define USB_LP_CAN1_RX0_IRQn 20 +#define STM32_USB_IRQ_PRIORITY 11 + +#define FLASH_PAGE_SIZE 1024 + + + +#define STM32_SW_PLL (2 << 0) +#define STM32_PLLSRC_HSE (1 << 16) + +#define STM32_PLLXTPRE_DIV1 (0 << 17) +#define STM32_PLLXTPRE_DIV2 (1 << 17) + +#define STM32_HPRE_DIV1 (0 << 4) + +#define STM32_PPRE1_DIV2 (4 << 8) + +#define STM32_PPRE2_DIV1 (0 << 11) +#define STM32_PPRE2_DIV2 (4 << 11) + +#define STM32_ADCPRE_DIV4 (1 << 14) +#define STM32_ADCPRE_DIV6 (2 << 14) + +#define STM32_USBPRE_DIV1P5 (0 << 22) + +#define STM32_MCO_NOCLOCK (0 << 24) + +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_ADCPRE STM32_ADCPRE_DIV6 +#define STM32_MCOSEL STM32_MCO_NOCLOCK +#define STM32_USBPRE STM32_USBPRE_DIV1P5 + +#define STM32_PLLCLKIN (STM32_HSECLK / 1) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) +#define STM32_SYSCLK STM32_PLLCLKOUT +#define STM32_HCLK (STM32_SYSCLK / 1) + +#define STM32_FLASHBITS 0x00000012 + +struct NVIC { + uint32_t ISER[8]; + uint32_t unused1[24]; + uint32_t ICER[8]; + uint32_t unused2[24]; + uint32_t ISPR[8]; + uint32_t unused3[24]; + uint32_t ICPR[8]; + uint32_t unused4[24]; + uint32_t IABR[8]; + uint32_t unused5[56]; + uint32_t IPR[60]; +}; + +#define NVICBase ((struct NVIC *)0xE000E100) +#define NVIC_ISER(n) (NVICBase->ISER[n]) +#define NVIC_ICPR(n) (NVICBase->ICPR[n]) +#define NVIC_IPR(n) (NVICBase->IPR[n]) + +static void +nvic_enable_vector (uint32_t n, uint32_t prio) +{ + unsigned int sh = (n & 3) << 3; + + NVIC_IPR (n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh); + NVIC_ICPR (n >> 5) = 1 << (n & 0x1F); + NVIC_ISER (n >> 5) = 1 << (n & 0x1F); +} + + +#define PERIPH_BASE 0x40000000 +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) + +struct RCC { + volatile uint32_t CR; + volatile uint32_t CFGR; + volatile uint32_t CIR; + volatile uint32_t APB2RSTR; + volatile uint32_t APB1RSTR; + volatile uint32_t AHBENR; + volatile uint32_t APB2ENR; + volatile uint32_t APB1ENR; + volatile uint32_t BDCR; + volatile uint32_t CSR; +}; + +#define RCC_BASE (AHBPERIPH_BASE + 0x1000) +#define RCC ((struct RCC *)RCC_BASE) + +#define RCC_APB1ENR_USBEN 0x00800000 +#define RCC_APB1RSTR_USBRST 0x00800000 + +#define RCC_CR_HSION 0x00000001 +#define RCC_CR_HSIRDY 0x00000002 +#define RCC_CR_HSITRIM 0x000000F8 +#define RCC_CR_HSEON 0x00010000 +#define RCC_CR_HSERDY 0x00020000 +#define RCC_CR_PLLON 0x01000000 +#define RCC_CR_PLLRDY 0x02000000 + +#define RCC_CFGR_SWS 0x0000000C +#define RCC_CFGR_SWS_HSI 0x00000000 + +#define RCC_AHBENR_CRCEN 0x0040 + +struct FLASH { + volatile uint32_t ACR; + volatile uint32_t KEYR; + volatile uint32_t OPTKEYR; + volatile uint32_t SR; + volatile uint32_t CR; + volatile uint32_t AR; + volatile uint32_t RESERVED; + volatile uint32_t OBR; + volatile uint32_t WRPR; +}; + +#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) +#define FLASH ((struct FLASH *) FLASH_R_BASE) + +static void +clock_init (void) +{ + /* HSI setup */ + RCC->CR |= RCC_CR_HSION; + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; + RCC->CFGR = 0; + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; + + /* HSE setup */ + RCC->CR |= RCC_CR_HSEON; + while (!(RCC->CR & RCC_CR_HSERDY)) + ; + + /* PLL setup */ + RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; + + /* Clock settings */ + RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE + | STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + + /* Flash setup */ + FLASH->ACR = STM32_FLASHBITS; + + /* CRC */ + RCC->AHBENR |= RCC_AHBENR_CRCEN; + + /* Switching on the configured clock source. */ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +} + +#define RCC_APB2ENR_IOPAEN 0x00000004 +#define RCC_APB2RSTR_IOPARST 0x00000004 +#define RCC_APB2ENR_IOPBEN 0x00000008 +#define RCC_APB2RSTR_IOPBRST 0x00000008 +#define RCC_APB2ENR_IOPCEN 0x00000010 +#define RCC_APB2RSTR_IOPCRST 0x00000010 +#define RCC_APB2ENR_IOPDEN 0x00000020 +#define RCC_APB2RSTR_IOPDRST 0x00000020 + + +struct GPIO { + volatile uint32_t CRL; + volatile uint32_t CRH; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t BRR; + volatile uint32_t LCKR; +}; + +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOA ((struct GPIO *) GPIOA_BASE) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOB ((struct GPIO *) GPIOB_BASE) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOC ((struct GPIO *) GPIOC_BASE) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOD ((struct GPIO *) GPIOD_BASE) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define GPIOE ((struct GPIO *) GPIOE_BASE) + +#define GPIO_USB ((struct GPIO *) GPIO_USB_BASE) +#define GPIO_LED ((struct GPIO *) GPIO_LED_BASE) + +static void +gpio_init (void) +{ + /* Enable GPIO clock. */ + RCC->APB2ENR |= RCC_APB2ENR_IOP_EN; + RCC->APB2RSTR = RCC_APB2RSTR_IOP_RST; + RCC->APB2RSTR = 0; + + GPIO_USB->ODR = VAL_GPIO_ODR; + GPIO_USB->CRH = VAL_GPIO_CRH; + GPIO_USB->CRL = VAL_GPIO_CRL; + +#if GPIO_USB_BASE != GPIO_LED_BASE + GPIO_LED->ODR = VAL_GPIO_LED_ODR; + GPIO_LED->CRH = VAL_GPIO_LED_CRH; + GPIO_LED->CRL = VAL_GPIO_LED_CRL; +#endif +} + +static void +usb_cable_config (int enable) +{ +#if defined(GPIO_USB_SET_TO_ENABLE) + if (enable) + GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE); + else + GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE); +#elif defined(GPIO_USB_CLEAR_TO_ENABLE) + if (enable) + GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); + else + GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); +#else + (void)enable; +#endif +} + +void +set_led (int on) +{ +#if defined(GPIO_LED_CLEAR_TO_EMIT) + if (on) + GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT); + else + GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT); +#else + if (on) + GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT); + else + GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT); +#endif +} + +static void wait (int count) +{ + int i; + + for (i = 0; i < count; i++) + asm volatile ("" : : "r" (i) : "memory"); +} + +#define USB_IRQ 20 +#define USB_IRQ_PRIORITY ((11) << 4) + +static void +usb_lld_sys_shutdown (void) +{ + RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + usb_cable_config (0); +} + +static void +usb_lld_sys_init (void) +{ + if ((RCC->APB1ENR & RCC_APB1ENR_USBEN) + && (RCC->APB1RSTR & RCC_APB1RSTR_USBRST) == 0) + /* Make sure the device is disconnected, even after core reset. */ + { + usb_lld_sys_shutdown (); + /* Disconnect requires SE0 (>= 2.5uS). */ + wait (300); + } + + usb_cable_config (1); + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + nvic_enable_vector (USB_LP_CAN1_RX0_IRQn, + CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY)); + /* + * Note that we also have other IRQ(s): + * USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous) + * USBWakeUp_IRQn (suspend/resume) + */ + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + RCC->APB1RSTR = 0; +} + +#define FLASH_KEY1 0x45670123UL +#define FLASH_KEY2 0xCDEF89ABUL + +enum flash_status +{ + FLASH_BUSY = 1, + FLASH_ERROR_PG, + FLASH_ERROR_WRP, + FLASH_COMPLETE, + FLASH_TIMEOUT +}; + +static void __attribute__ ((used)) +flash_unlock (void) +{ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; +} + + +#define intr_disable() asm volatile ("cpsid i" : : : "memory") + +#define intr_enable() asm volatile ("msr BASEPRI, %0\n\t" \ + "cpsie i" : : "r" (0) : "memory") + +#define FLASH_SR_BSY 0x01 +#define FLASH_SR_PGERR 0x04 +#define FLASH_SR_WRPRTERR 0x10 +#define FLASH_SR_EOP 0x20 + +#define FLASH_CR_PG 0x0001 +#define FLASH_CR_PER 0x0002 +#define FLASH_CR_MER 0x0004 +#define FLASH_CR_OPTPG 0x0010 +#define FLASH_CR_OPTER 0x0020 +#define FLASH_CR_STRT 0x0040 +#define FLASH_CR_LOCK 0x0080 +#define FLASH_CR_OPTWRE 0x0200 +#define FLASH_CR_ERRIE 0x0400 +#define FLASH_CR_EOPIE 0x1000 + +static int +flash_wait_for_last_operation (uint32_t timeout) +{ + int status; + + do + { + status = FLASH->SR; + if (--timeout == 0) + break; + } + while ((status & FLASH_SR_BSY) != 0); + + return status & (FLASH_SR_BSY|FLASH_SR_PGERR|FLASH_SR_WRPRTERR); +} + +#define FLASH_PROGRAM_TIMEOUT 0x00010000 +#define FLASH_ERASE_TIMEOUT 0x01000000 + +static int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PG; + + *(volatile uint16_t *)addr = data; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PG; + } + intr_enable (); + + return status; +} + +static int +flash_erase_page (uint32_t addr) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PER; + FLASH->AR = addr; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PER; + } + intr_enable (); + + return status; +} + +static int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + const uint8_t *p; + + for (p = p_start; p < p_start + size; p++) + if (*p != 0xff) + return 0; + + return 1; +} + +extern uint8_t __flash_start__, __flash_end__; + +static int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int status; + uint32_t flash_start = (uint32_t)&__flash_start__; + uint32_t flash_end = (uint32_t)&__flash_end__; + + if (dst_addr < flash_start || dst_addr + len > flash_end) + return 0; + + while (len) + { + uint16_t hw = *src++; + + hw |= (*src++ << 8); + status = flash_program_halfword (dst_addr, hw); + if (status != 0) + return 0; /* error return */ + + dst_addr += 2; + len -= 2; + } + + return 1; +} + +#define OPTION_BYTES_ADDR 0x1ffff800 + +static int +flash_protect (void) +{ + int status; + uint32_t option_bytes_value; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + intr_disable (); + if (status == 0) + { + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + FLASH->CR |= FLASH_CR_OPTER; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_OPTER; + } + intr_enable (); + + if (status != 0) + return 0; + + option_bytes_value = *(uint32_t *)OPTION_BYTES_ADDR; + return (option_bytes_value & 0xff) == 0xff ? 1 : 0; +} + +static void __attribute__((naked)) +flash_erase_all_and_exec (void (*entry)(void)) +{ + uint32_t addr = (uint32_t)&__flash_start__; + uint32_t end = (uint32_t)&__flash_end__; + int r; + + while (addr < end) + { + r = flash_erase_page (addr); + if (r != 0) + break; + + addr += FLASH_PAGE_SIZE; + } + + if (addr >= end) + (*entry) (); + + for (;;); +} + +struct SCB +{ + volatile uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint8_t SHP[12]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile uint32_t PFR[2]; + volatile uint32_t DFR; + volatile uint32_t ADR; + volatile uint32_t MMFR[4]; + volatile uint32_t ISAR[5]; +}; + +#define SCS_BASE (0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) +#define SCB ((struct SCB *) SCB_BASE) + +#define SYSRESETREQ 0x04 +static void +nvic_system_reset (void) +{ + SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); + asm volatile ("dsb"); +} + +static void __attribute__ ((naked)) +reset (void) +{ + asm volatile ("cpsid i\n\t" /* Mask all interrupts. */ + "mov.w r0, #0xed00\n\t" /* r0 = SCR */ + "movt r0, #0xe000\n\t" + "mov r1, pc\n\t" /* r1 = (PC + 0x1000) & ~0x0fff */ + "mov r2, #0x1000\n\t" + "add r1, r1, r2\n\t" + "sub r2, r2, #1\n\t" + "bic r1, r1, r2\n\t" + "str r1, [r0, #8]\n\t" /* Set SCR->VCR */ + "ldr r0, [r1], #4\n\t" + "msr MSP, r0\n\t" /* Main (exception handler) stack. */ + "ldr r0, [r1]\n\t" /* Reset handler. */ + "bx r0\n" + : /* no output */ : /* no input */ : "memory"); +} + +typedef void (*handler)(void); +extern uint8_t __ram_end__; + +extern const unsigned long *FT0, *FT1, *FT2; + +handler vector[] __attribute__ ((section(".vectors"))) = { + (handler)&__ram_end__, + reset, + (handler)set_led, + flash_unlock, + (handler)flash_program_halfword, + (handler)flash_erase_page, + (handler)flash_check_blank, + (handler)flash_write, + (handler)flash_protect, + (handler)flash_erase_all_and_exec, + usb_lld_sys_init, + usb_lld_sys_shutdown, + nvic_system_reset, + clock_init, + gpio_init, + (handler)&FT0, + (handler)&FT1, + (handler)&FT2, +}; + +const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = { + 3*2+2, /* bLength */ + 0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/ + /* sys version: "2.0" */ + '2', 0, '.', 0, '0', 0, +}; diff --git a/example/sys.h b/example/sys.h new file mode 100644 index 0000000..bb1ea71 --- /dev/null +++ b/example/sys.h @@ -0,0 +1,97 @@ +extern const uint8_t sys_version[8]; + +typedef void (*handler)(void); +extern handler vector[18]; + +static inline const uint8_t * +unique_device_id (void) +{ + /* STM32F103 has 96-bit unique device identifier */ + const uint8_t *addr = (const uint8_t *)0x1ffff7e8; + + return addr; +} + +static inline void +set_led (int on) +{ + void (*func) (int) = (void (*)(int))vector[2]; + + return (*func) (on); +} + +#if 0 +static inline void +flash_unlock (void) +{ + (*vector[3]) (); +} +#endif + +static inline int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int (*func) (uint32_t, uint16_t) = (int (*)(uint32_t, uint16_t))vector[4]; + + return (*func) (addr, data); +} + +static inline int +flash_erase_page (uint32_t addr) +{ + int (*func) (uint32_t) = (int (*)(uint32_t))vector[5]; + + return (*func) (addr); +} + +static inline int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + int (*func) (const uint8_t *, int) = (int (*)(const uint8_t *, int))vector[6]; + + return (*func) (p_start, size); +} + +static inline int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int (*func) (uint32_t, const uint8_t *, size_t) + = (int (*)(uint32_t, const uint8_t *, size_t))vector[7]; + + return (*func) (dst_addr, src, len); +} + +static inline int +flash_protect (void) +{ + int (*func) (void) = (int (*)(void))vector[8]; + + return (*func) (); +} + +static inline void __attribute__((noreturn)) +flash_erase_all_and_exec (void (*entry)(void)) +{ + void (*func) (void (*)(void)) = (void (*)(void (*)(void)))vector[9]; + + (*func) (entry); + for (;;); +} + +static inline void +usb_lld_sys_init (void) +{ + (*vector[10]) (); +} + +static inline void +usb_lld_sys_shutdown (void) +{ + (*vector[11]) (); +} + +static inline void +nvic_system_reset (void) +{ + (*vector[12]) (); +} diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..91c77ca --- /dev/null +++ b/rules.mk @@ -0,0 +1,51 @@ +# Chopstx make rules. + +CSRC += $(CHOPSTX)/entry.c $(CHOPSTX)/chopstx.c +INCDIR = $(CHOPSTX) + +BUILDDIR = build +OUTFILES = $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PROJECT).bin + +OPT += -ffunction-sections -fdata-sections -fno-common + +OBJS = $(addprefix $(BUILDDIR)/, $(notdir $(CSRC:.c=.o))) + +IINCDIR = $(patsubst %,-I%,$(INCDIR)) +LLIBDIR = $(patsubst %,-L%,$(LIBDIR)) + +VPATH = $(sort $(dir $(CSRC))) +### +MCFLAGS = -mcpu=$(MCU) + +CFLAGS = $(MCFLAGS) $(OPT) $(CWARN) -Wa,-alms=$(BUILDDIR)/$(notdir $(<:.c=.lst)) $(DEFS) + +LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--gc-sections $(LLIBDIR) + +CFLAGS += -mthumb -mno-thumb-interwork -DTHUMB +LDFLAGS += -mthumb -mno-thumb-interwork + +CFLAGS += -MD -MP -MF .dep/$(@F).d + +all: $(OBJS) $(OUTFILES) + +$(OBJS): | $(BUILDDIR) + +$(BUILDDIR): + mkdir -p $(BUILDDIR) + +$(OBJS) : $(BUILDDIR)/%.o : %.c Makefile + @echo + $(CC) -c $(CFLAGS) -I. $(IINCDIR) $< -o $@ + +%.elf: $(OBJS) $(LDSCRIPT) + @echo + $(LD) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ + +%.bin: %.elf $(LDSCRIPT) + $(OBJCOPY) -O binary $< $@ + +clean: + -rm -f -r .dep $(BUILDDIR) + +# Include dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) |