What is it anyway?
Let me start by specifying what I mean when I say: reverse engineering, roundtrip engineering and forward engineering. All in the context of UML and Rhapsody of course.
- Reverse Engineering: Reading in existing source code and inserting it in a Rhapsody model in such a way that it continues to work.
- Roundtrip Engineering: Reading in source code that was generated by Rhapsody but was changed by the user. Note!: Please understand the difference between reverse and roundtrip! It is very different for Rhapsody to read in “strange” code then it is to read in “familiar” code.
- Forward Engineering: Something I invented myself (Or maybe it already exists then I just re-invented it…) It is reverse engineering but the user will take the result and do the necessary steps to make a decent UML Model out of it.
So. As I already wrote in a previous post, I don’t like reverse engineering. Sometimes you need to do it but it is something that prevents good modeling IMHO.
Roundtrip Engineering is OK although Rhapsody knows 3 modes there: Basic, Advanced and Respect.
- Basic: Allows you to change code that is between the Rhapsody generated comments: /*#[ and #]*/ That is the code that you type in state-chart entry/exit/transition and in the implementation body of your operations. Nothing else, changes to other parts will be ignored when Rhapsody generates new code. Is not trivial since Rhapsody sometimes uses the same code twice and will then ignore your changes! (Of course without commenting it…. Rhapsody is a tool for real men…) ***Recommended Setting***
- Advanced: Same as Basic but also allows you to add attributes and operations. Is also OK if you know what you are doing but keep way from it until you know what the effects are of what you change.
- Respect: The “Evil Knievel” option. Or “Eddy the Eagle” if you prefer him. This allows you to change every line in the generated code. Rhapsody will try to keep it as long as it is syntactically OK. To make things worse, Rhapsody will store this information in “source artifacts” that are hidden by default. (I still wonder which sadistically inclined person designed that option….) ***Not Recommended at all Setting***. At least switch on “Show Source Artifacts” (“View”, “Browser Display Options”, “Show Source Artifacts”).
So you have to be careful using these options. This is all more valid for ‘C’ then it is for other languages like ‘C++’ and Java, these languages are much closer to the UML and ca therefor produce much better results when doing reverse or roundtrip engineering!
LCD Display on the Keil MCB1700 Board
We use that board for our trainings. We do this since years and we use the LCD display on that board using some ‘C’ files that Keil provides. GLCD.C and GLCD.H. Here are these files: GLCD so you can check yourself.
The .h file has function prototypes (Useful for checking which functions are “public”!) and the defines for the colors. Reverse engineering will show these as types.
The .c file contains a couple of defines that are reverse engineered just as the all the defines in the .h file. Then there are all the functions. After examining the functions we can see that there are “public” functions (GLCD_xxxx() ) and “private” functions (spi_)
In the training we include glcd.h via the “external file” mechanism and the dependency with “Usage” stereotype. Glcd.c is inserted via the Component file and a “text element”. This works fine (And is of course aimed at learning different methods to use legacy code)
Reverse engineering also works, I tried, you can call the functions if you have reverse engineered them.
But we want something else: we want Classes that are completely generated from Rhapsody! So first we will create a class GLCD. Since SPI works a little bit different we will use a Singleton Object there.
Then we move all the functions to the respective class/object. Nice side-effect: the “me-pointer” is added automatically! But unfortunately… not to the code. This is where you have to do some work, add me-> to all uses of the attributes. I have created attributes from a few variables like orientation, bbps and position. You can add them to the init function. That is something that also needs to be done by hand: The init function must be converted into a constructor (initializer)
The SPI functions are moved to the SPI object. No me pointer is needed there but I used the variables that determine the exact version of the LCD hardware to attributes, you have to add the spi.<attribute> yourself.
The colors must be converted to an enum type. A bit of work which cannot be done automatically but it is worth it! (Why this is not done in the original ‘C’-code??)
I added some fine-tuning like converting some variables to enumerations or at least types, always a good habit in programming: let the compiler check as much as possible!
The result is quite nice: RhpGLCD, see for yourself.
Happy modeling with Rhapsody and greetings from the Bavarian Forrest!
Walter van der Heiden (email@example.com)