It is currently 21 May 2018 05:42

All times are UTC + 1 hour




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: 17 Jun 2013 07:21 
Offline

Joined: 14 Feb 2011 04:07
Posts: 1119
Location: Bar, Montenegro
I know this topic has been discussed before and that most of us are waiting for mE to officially support this feature, but that doesn't mean we should just sit and wait :)

I had some free time over the weekend so I tried to make some kind of a workaround for this problem. As you already know, all mikroE compiler products consist of 2 main executables: the console application (compiler) and IDE. The job of the IDE is to manage the project (source files, headers, configuration files etc.) and provide the command-line parameters for the compiler. When building the project, the IDE is starting the compiler and redirecting STDOUT to the "Messages" window. The configuration words (along with device name and oscillator frequency) are stored in a file named <project_name>.cfg which is implicitly passed to the compiler.

Now, here comes the interesting part. Those settings are not kept in memory, i.e. whenever you open project settings (Project -> Edit Project in IDE) the settings from the cfg file are loaded. That means if you edit the cfg file manually and then try to open the same window, you will see the changes you just made. This was a good starting point. One more interesting thing is that the cfg file is overwritten each time you start the build process (before actual compilation) but that observation is of little importance (probably because someone could manually rename or delete it)

The available configuration words and all available settings for the selected device are stored in the XML formatted definition files (<compiler_folder>\Defs\*.mlk). Each setting is identified by the config word field which is named as in the datasheet (and, of course, C18 compiler), word-value and the appropriate bit mask. Final config word is obtained by OR-ing all the word-values. The only thing missing is the setting-value. So, my first task was to create an application that will add one more XML node containing setting-value. Done :)
Attachment:
mlk_cfg_editor.png
mlk_cfg_editor.png [ 67.78 KiB | Viewed 4156 times ]
I didn't have the time to do that for all MLK files so I will leave that part to you :) You can find the configuration settings at Microchip's website or in C18 compiler documentation.

Then I thought about the way to implement this in code and instinctively tried:
#pragma config FOSC = HSMP
The Messages window returned:
Attachment:
unknown_pragma.png
unknown_pragma.png [ 13.31 KiB | Viewed 4156 times ]
So then I found out that all undefined pragmas are ignored. Cool :)

In my first attempt to take advantage of this behavior for setting config bits in code, I created an application/tool that communicated with the IDE through Windows API calls (saving project and source files), listed all the source files from <project_name>.mcppi file (INI file format), processed them looking for config bit pragmas and ran the compiler with redirected STDOUT to get the messages. It worked :D

Then I thought this solution was not "elegant" enough so I came up with a way to obtain this functionality without introducing new GUI elements, i.e. use only the "Messages" window of the IDE. As I have already said, the IDE is just processing the STDOUT of the compiler executable and displaying it in the "Messages" window:
Compiler ---> STDOUT ---> IDE
The idea was to introduce another console application that will get the STDOUT of the compiler (along with all the parameters), process it and forward the messages to the IDE:
Compiler ---> STDOUT ---> myApp---> STDOUT ---> IDE
This "man-in-the-middle" strategy proved to be a success :) Here's what happens when the project is built:

1. IDE saves the cfg file
2. IDE launches myApp (thinking that it is mikroC compiler executable)
3. myApp gets the list of all the source files (from parameters/arguments) that are parsed in search for config bits pragmas
4. myApp overwrites the cfg file with the settings obtained in step 3
5. myApp calls the compiler executable with the parameters from IDE and redirects the STDOUT to IDE

You can see the result in the following screenshot ("Unknown pragma" warnings are suppressed in myApp):
Attachment:
cfg_bits.png
cfg_bits.png [ 27.52 KiB | Viewed 4156 times ]

If you try to open "Edit project" window again, you will see the settings that were configured in code because the cfg file got overwritten as I have previously described.

I think that this solution offers compromise for both beginners (setting config bits in IDE) and more experienced users (setting config bits in code) because the GUI settings are overwritten with the in-code ones.

My suggestion to mE developers would be:

1. for the compiler
- create another file (e.g. <project_name>.config) which will be used for storing config bits set in code
- define another command-line parameter/argument for the compiler exe that will specify the config file to be used to build the project
2. for the IDE
- add checkbox to the "Edit project" window ("Set config bits in code") that will determine which configuration file will be passed to the compiler

Since I didn't have the time to write my own preprocessor (or more precisely pre-preprocessor :) ) there are some limitations to the method I described:
- you have to use pragmas in *.c files (header files are currently not supported)
- at the moment pragmas can only be commented with line comments (Do not use block comments to comment them out! This is on my to-do list :))


Last edited by aCkO on 19 Jun 2013 03:24, edited 8 times in total.

Top
 Profile  
 
PostPosted: 17 Jun 2013 07:23 
Offline

Joined: 14 Feb 2011 04:07
Posts: 1119
Location: Bar, Montenegro
More screenshots:
Attachment:
invalid_setting_name.png
invalid_setting_name.png [ 31.52 KiB | Viewed 4155 times ]
Attachment:
invalid_setting_value.png
invalid_setting_value.png [ 35.25 KiB | Viewed 4155 times ]

You will find the necessary files in the attachment. I won't upload them to Libtock yet since there is still some work to be done.
Installation:

1. Open mikroC PRO install folder and rename the file 'mikroCPIC1618.exe' to 'mikroCPIC.exe'
2. Extract both files from the attachment to mikroC PRO installation folder
3. Start the "MLK CFG Editor" application, open the MLK file of your current device, add setting-values for the config word fields and save the file
4. Build your projects as usual

Regards


Attachments:
CFGBITS_V1.00.zip [60 KiB]
Downloaded 325 times
Top
 Profile  
 
PostPosted: 17 Jun 2013 20:21 
Offline

Joined: 15 Mar 2012 16:02
Posts: 76
Good work as always. Thx! :wink:

I wonder why ME didn't do it in the first place? There have been numerous requests over the years. :?


Top
 Profile  
 
PostPosted: 19 Jun 2013 03:36 
Offline

Joined: 14 Feb 2011 04:07
Posts: 1119
Location: Bar, Montenegro
lighty wrote:
I wonder why ME didn't do it in the first place? There have been numerous requests over the years. :?
My guess is because they wanted to do that in a way that would leave little room for user mistakes. The way I suggested is just one of them. If I could come up with this in a couple of hours, imagine how long it would take them to implement it in their own product :wink:

Regards


Top
 Profile  
 
PostPosted: 19 Jun 2013 11:04 
Offline

Joined: 15 Mar 2012 16:02
Posts: 76
It's impossible to make fool-proof anything let alone compiler. :lol:


Top
 Profile  
 
PostPosted: 19 Jun 2013 13:32 
Offline

Joined: 29 Jul 2009 09:48
Posts: 664
Location: Sheffield
Wow, thanks!

I have been wanting to get round to looking at this for a while as I am fed up of having to alter the config bits for the WDT prescaler every time as it always defaults to 1:32768 and I have to have it at 1:256.
What is worse is that this is easy for me to miss when I release my code and program a unit because I use it to perform a reset if the micro has locked up during SD card access (if someone manages to remove the card during writing) and the only time it is found to be programmed incorrectly is when this is simulated or a customer manages to lock a unit up(and it is hard to remove the card in the split second the writing is taking place).

It would also makes my
Quote:
#define _DEBUG
statement complete if it were possible to do something like:
#ifdef _DEBUG
 #pragma config CP0 = OFF
#else
 #pragma config CP0 = ON
#endif


although this may be wishing for a little too much.

Just one point, it took me a while to notice that you need to click out of the value box or it will not save the data you have entered.

Also, to make life complete, do you know of a way to specify other parameters from the code like the project oscillator frequency?
I can use '#if __FOSC__ == 10000' commands to check the frequency but would prefer to do it the other way and specify the frequency in the code and the project compile at the frequency specified in the code.

Best regards,
Dave


Top
 Profile  
 
PostPosted: 19 Jun 2013 19:22 
Offline

Joined: 14 Feb 2011 04:07
Posts: 1119
Location: Bar, Montenegro
ISL_Dave wrote:
It would also makes my
Quote:
#define _DEBUG
statement complete if it were possible to do something like:
#ifdef _DEBUG
 #pragma config CP0 = OFF
#else
 #pragma config CP0 = ON
#endif


although this may be wishing for a little too much.
It's not too much and I plan to make a complete preprocessor as soon as I get some free time (hopefully over the weekend :) ). Consider this a demo version :) My goal was just to illustrate the idea of how this feature could be implemented in mikroC and maybe get some opinion from mE developers.
Quote:
Just one point, it took me a while to notice that you need to click out of the value box or it will not save the data you have entered.
Just press the ENTER key when you finish editing the datagrid cell. Also, after pressing ENTER, the next Value cell will be selected. I think everybody is used to this way of entering the data
Quote:
Also, to make life complete, do you know of a way to specify other parameters from the code like the project oscillator frequency?
I can use '#if __FOSC__ == 10000' commands to check the frequency but would prefer to do it the other way and specify the frequency in the code and the project compile at the frequency specified in the code.
One of the parameters/arguments that are passed to the compiler executable is the MCU clock so it won't be hard to replace it with the one found in code :wink:

Regards


Top
 Profile  
 
PostPosted: 08 Aug 2013 08:25 
Offline

Joined: 09 Nov 2012 16:00
Posts: 93
Location: Switzerland
Good Job!
Thanks!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: