Pages

Interface DS1307 RTC with PIC16f877 through I2C

Previous post introduce you the I2C communication protocol in briefly and present a complete set of functions to perform I2C communication as a 'master' (from hi tech C compiler). This post will be dedicated to introduce a RTC(Real Time Clock) IC DS1307 and a simple code to perform read/write operations on RTC through I2C. This code also implemented using Hi tech C compiler and PIC16f877 as the MCU.

What is RTC? yaaa RTC stands for Real Time Clock. Most of the devices those maintaining a clock for their functions use these kind of ICs.Also DS1307 has its own capability to use backup battery(3V coin) power when main power source shutdown.
 
You can download  Datasheet for DS1307.

The features can be listed bellow,

  • Real-time clock (RTC) counts seconds, minutes, hours, date of the month, month, day of the week, and year with leap-year compensation valid up to 2100
  • 56-byte, battery-backed, nonvolatile (NV) RAM for data storage
  • Two-wire serial interface (I2C)
  • Programmable square wave output signal
  • Automatic power-fail detects and switches circuitry
  • Consumes less than 500nA in battery backup mode with oscillator running
  • Optional industrial temperature range: -40°C to +85°C
  • Available in 8-pin DIP or SOIC

Most significant thing in the IC is the battery backup power because if it a real time clock it should be run always to get the real time from it. Therefore you do non need to worry about clock it will run independently from your MCU.


Source code for DS1307 RTC

So let's move to source code. This code uses the functions implemented on previous post. Therefore it is better to download those codes and create a header file for those functions so you can re-use them latter. Don't worry a complete source code can be found at the end of this post. Here DS1307 act as a slave on the bus and our MCU act as the master on the bus.

Data Write - Slave Receiver Mode
First let's try to write a function to write a byte to DS1307's EEPROM. I refer following diagram which I grab from DS1307's datasheet to code this function.


So lets implement this diagram into code!

void ds1307Write(unsigned char address, unsigned char data){
    i2CStart();//start the i2c bus
    i2CSend(208);//send DS1307 write command, DS1307 address + direction bit(R/nW) 1101000 + 0 = 11010000 = 208
    i2CSend(address);//send the address that you need to write data on.
    i2CSend(data);//write data on the address
    i2CStop();//close the I2C bus
}

Code explained

i2CStart();//start the i2c bus

This is the function call which we create in previous post to send start condition through I2C bus. So this code is to send the start condition to slave device.


i2CSend(208);//send DS1307 write command, DS1307 address + direction bit(R/nW) 1101000 + 0 = 11010000 = 208

If you can remember, I2C communication can be done by sending 7 bits wide address and R/W bit immediately following start condition on the bus. So this is the sending of address and the direction bit to the DS1307. The address for DS1307 is 1101000 (in binary) then the direction bit R/W (1 for read 0 for write). Then whole byte is the concatenated bits of address and R/W bit,

1101000 + 0 = 11010000 = 208 (in decimal)


i2CSend(address);//send the address that you need to write data on.

Then you need to send address which you want to write data on EEPROM of DS1307.


i2CSend(data);//write data on the address

Then the data to be written on above specified address.


i2CStop();//close the I2C bus

Then stop the I2C communication.


Data Read—Slave Transmitter Mode
Now the read function. This will be some what complicated, because you need to point the address where you want to read from before initiate the read operation. I refer following diagram from datasheet to implement the function. This function will return a byte at once which is located on address specified.



unsigned char ds1307Read(unsigned char address){
    unsigned char data;

    i2CStart();//send start signal on I2C bus
    i2CSend(208);//send DS1307 dummy write command to get the pointer to our location
                //DS1307 address + direction bit(R/nW) 1101000 + 0 = 11010000 = 208
    i2CSend(address);//set the address pointer
    i2CRestart();//send stop+start signal to bus
    i2CSend(209);//send read command to DS1307
    data = i2CRead();//read the buffer for received data
    i2CStop();//close the i2c bus
    return data;
}

Code explained
Initially send the start condition to the bus as explained in previous function to initiate the I2C bus for communication.


i2CSend(208);//send DS1307 dummy write command to get the pointer to our location
             //DS1307 address + direction bit(R/nW) 1101000 + 0 = 11010000 = 208

Then we send a dummy write command to get the EEPROM's pointer to the location that we need to read from. Therefore this byte will send to the DS3107 with the write operation direction bit (same as previous function). But we do not write anything on it.


i2CSend(address);//set the address pointer

Then send the address that we need to point on to set the EEPROM's pointer to the location.


i2CRestart();//send stop+start signal to bus

As I explained earlier we are not going to write anything, only purpose to issue write operation is set the pointer to the location.Therefore send the 'repeated start' condition to the bus.


i2CSend(209);//send read command to DS1307

Now we can send the read operation to DS1307. The value can be calculated as follows,
DS1307 address (1101000) + direction bit (1 for read) = 1101001 = 209 (in decimal


data = i2CRead();//read the buffer for received data

Now you can read data from DS1307 and hold these data on "data" variable. If you have any doubt about these function which are calling in this post please refer previous post. Because, none of the function that we calling here are inbuilt functions.


i2CStop();//close the i2c bus
return data;


Then close the I2C bus by sending stop condition and return the data which read from DS1307's EEPROM

DS1307's memory
Now you have functions for read and write operations. Now let's try to extract data from DS1307. We will need its memory map to do that. Memory map is,


Now let's try to read seconds from the memory as you can see here the Seconds data contain in 3 parts. Those are CH bit, 10 Seconds and Seconds. If you read the datasheet, you can find the functionality of CH bit. It is the clock enable bit. If you set CH = 0 the clock is enabled and running, if you set CH = 1 the clock will be disable. I will explain 10 Seconds and Second thing from a example,

Let's say the seconds on the clock is 36, then,
10 Seconds  = 3 (011)
Seconds = 6 (110)
and let CH = 0

Now the byte on the 0th position is 0 + 011 + 110 = 0011110 (plus mean concatenate). So I think you got the trick or still complicated...! Don't worry I have created functions to get and set Seconds, Minutes, Hours (in 12 hour or 24 hour mode), and Day. You can code your own functions for other things (Date, month and year). Only thing is to understand the memory map of the IC and code it.

You can download a complete source code and test program at the end of this tutorial.
The complete code is,

/**
 * Function will read a byte from the @address location of the memory
 * @param address - address that you need to read
 * @return received data byte from DS1307
 */
unsigned char ds1307Read(unsigned char address){
    unsigned char data;

    i2CStart();//send start signal on I2C bus
    i2CSend(208);//send DS1307 dummy write command to get the pointer to our location
                //DS1307 address + direction bit(R/nW) 1101000 + 0 = 11010000 = 208
    i2CSend(address);//set the address pointer
    i2CRestart();//send stop+start signal to bus
    i2CSend(209);//send read commad to DS1307
    data = i2CRead();//read the buffer for received data
    i2CStop();//close the i2c bus
    return data;
}

/**
 * Write to DS1307's eeprom
 * @param address - address to write data (0 - 7)
 * @param data - 8bit data to be written
 */
void ds1307Write(unsigned char address, unsigned char data){
    i2CStart();//start the i2c bus
    i2CSend(208);//send DS1307 write command, DS1307 address + direction bit(R/nW) 1101000 + 0 = 11010000 = 208
    i2CSend(address);//send the address that you need to write data on.
    i2CSend(data);//write data on the address
    i2CStop();//close the I2C bus
}

/**
 * get seconds from DS1307's eeprom
 * @return seconds on DS1307
 */
unsigned char ds1307GetSec(){
    unsigned char sec10;
    unsigned char sec1;

    unsigned char bcdSec = ds1307Read(0);//get the 0th location data(CH + 10Sec + 1Sec)[in BCD format]

    bcdSec = bcdSec & 0b1111111;//ignore CH bit (ignore MSB)
    sec10 = bcdSec >> 4;//shift 4 bits right to ignore 1sec position(ignore 4 LSB)
    sec1 = bcdSec & 0b1111;//ignore 4 MSBs

    return sec10 * 10 + sec1;//return the seconds
}

/**
 * get minutes from DS1307's eeprom
 * @return minutes on DS1307
 */
unsigned char ds1307GetMin(){
    unsigned char min10;
    unsigned char min1;

    unsigned char bcdMin = ds1307Read(1);//get the 1st loaction's data(0 + 10Min + 1Min)[in BCD format]

    bcdMin = bcdMin & 0b1111111;//ignore MSB
    min10 = bcdMin >> 4;//shift 4 bit right to ignore 1min position(ignore 4 LSB)
    min1 = bcdMin &0b1111;

    return min10 * 10 + min1;//return the minnutes
}

/**
 * This function will return the hours in 24 hour format by reading from DS1307
 * @return hours from DS1307 in 24 hours format
 */
unsigned char ds1307GetHours(){
    unsigned char hour10;
    unsigned char hour1;
    unsigned char retHour;

    unsigned char bcdHour = ds1307Read(2);//get the 1st loaction's data(0 + 12 or 24 hour mode + 10hour(first bit) or PM/AM + 10hour(second bit) + 1hour)[in BCD format]
    bcdHour = bcdHour & 0b1111111;//ignore MSB(7th bit)
    if(bcdHour > 63){//is in 12 hours mode?
        bcdHour = bcdHour & 0b111111;//ignore MSB(6th bit)

        hour10 = (bcdHour & 0b11111) >> 4;//get the hour10 position by ignoring MSB(5th bit) and shift 4 bits to right
        hour1 = bcdHour & 0b1111;//get hour1 position by getting only 4 LSBs
        retHour = hour10 * 10 + hour1;//calculate the hours using hour10 and hour1

        if(bcdHour > 31){//is PM?
            if(retHour != 12)
                retHour = retHour + 12;
        }
    }else{
        bcdHour = bcdHour & 0b111111;//ignore MSB(6th bit)
        hour10 = bcdHour >> 4;//shift 4 bit to right to get 5th and 4th bits
        hour1 = bcdHour & 0b1111;//get 4 LSBs

        retHour = hour10 * 10 + hour1;//calculate the hours using hour10 and hour1
    }

    return retHour;
}

/**
 * reads the Day value from DS1307 memory
 * @return the number for the specific day (1=SUN, 2=MON,... 7=SAT)
 */
unsigned char ds1307GetDay(){
    return ds1307Read(3);//read value on 3rd location of DS1307 and return it
}

/**
 * set seconds to DS1307 with CH bit
 * @param newSec - seconds to be set (0 - 79)
 * @param chBit - Clock enable bit (0 = clock enable, 1 = clock disable)
 */
void ds1307SetSecond(unsigned char newSec, unsigned char chBit){
    unsigned char bcdNum;
    if(newSec > 79)
        return;//to avoid writing to CH when writing to second feild

    ds1307separateDigits(newSec);
    bcdNum = digitPlaceVal[1] << 4;//shift 4 bits left
    bcdNum = bcdNum | digitPlaceVal[0];//ORing with placeValue1

    //add CH bit
    if(chBit == 1)
        bcdNum = bcdNum | 0b10000000;

    ds1307Write(0, bcdNum);//write to sec
}

/**
 * Set DS1307 minutes
 * @param newMin - minutes to be set(0 - 127)
 */
void ds1307SetMinutes(unsigned char newMin){
    unsigned char bcdNum;
    if(newMin > 127)
        return;//to avoid overlimit

    ds1307separateDigits(newMin);
    bcdNum = digitPlaceVal[1] << 4;//shift 4 bits left
    bcdNum = bcdNum | digitPlaceVal[0];//ORing with placeValue1

    ds1307Write(1, bcdNum);//write to min
}

/**
 * Set DS1307 hours in 12 hour mode
 * @param newHour - hours in 12 hour mode (0 - 19)
 * @param pm_nAm - AM/PM bit (1 for PM, 0 for AM)
 */
void ds1307SetHours12(unsigned char newHour, unsigned char pm_nAm){
    unsigned char bcdNum;
    if(newHour > 19)
        return;//avoid overlimit

    ds1307separateDigits(newHour);
    bcdNum = digitPlaceVal[1] << 4;//place hour's placeValue10
    bcdNum = bcdNum | digitPlaceVal[0];//ORing with placeValue1

    bcdNum = bcdNum | 0b1000000;//set 12 hour mode
    if(pm_nAm)//PM?
        bcdNum = bcdNum | 0b100000;//set PM

    ds1307Write(2, bcdNum);//write to hours
}

/**
 * Set DS1307 hours in 24 hour mode
 * @param newHour - hours in 24 hour mode (0 - 29)
 */
void ds1307SetHour24(unsigned char newHour){
    unsigned char bcdNum;
    if(newHour > 29)
        return;//avoid overlimit

    ds1307separateDigits(newHour);
    bcdNum = digitPlaceVal[1] << 4;//place hour's placeValue10
    bcdNum = bcdNum | digitPlaceVal[0];//ORing with placeValue1

    ds1307Write(2, bcdNum);//write to hours
}

/**
 * Set day to DS1307 (range 0-7)
 * @param newDay - day to be set (1 = SUN, 2 = MON,...., 7 = SAT)
 */
void ds1307SetDay(unsigned char newDay){
    if(newDay > 7)
        return;//avoid overlimit

    ds1307Write(3, newDay);//write to day
}

/**
 * This function accept 2 digit number and separate it into 10 and 1 place value and assign to digit array
 *
digit[0] = place value 1
 *
digit[1] = place value 10
 * @param num2 - 2 digit number(0 - 99)
 */
void ds1307separateDigits(unsigned char num2){
    digitPlaceVal[1] = num2 / 10;
    digitPlaceVal[0] = num2 - (digitPlaceVal[1] * 10);
}


Download
A complete source code and test program.

Hi-tech C code for I2C communication

Before move to code I think it is better to write a brief introduction to I2C communication.

I²C (pronounced I-squared-C) created by Philips Semiconductors and commonly written as 'I2C' stands for Inter-Integrated Circuit and allows communication of data between I2C devices over two wires. It sends information serially using one line for data (SDA) and one for clock (SCL).There needs to be a third wire which is just the ground or 0 volts. There may also be a 5volt wire is power is being distributed to the devices. Both SCL and SDA lines are "open drain" drivers. What this means is that the chip can drive its output low, but it cannot drive it high. For the line to be able to go high you must provide pull-up resistors to the 5v supply. I2C bus can have one or more I2C devices connected.



Master and Slave
The devices on the I2C bus are either masters or slaves. The master is always the device that drives the SCL clock line. Slaves are the devices that respond to the master. A slave cannot initiate a transfer over the I2C bus, only a master can do that. There can be multiple slaves on the I2C bus. Also both slaves and masters can receive/send data over I2C. But always master initiate the data transfer over I2C bus.

Always I2C communication start with the start condition and terminate with the stop condition. Between these conditions you can transfer data between master and slave(s).

Addressing
Each slave device on the I2C bus should have a unique address. Then master can address these salve device individually for better communication between master and slave device. Always master initiate data transfer with the address to select a slave device on the bus for further communication.
Address byte contain 7bit address and data direction bit (R/W). This will initiate the specific slave device to be read or write operations.


START (S) and STOP (P) bits
START (S) and STOP (P) bits are unique signals that can be generated on the bus but only by a bus master.
This can be done at any time so you can force a restart if anything goes wrong even in the middle of communication.
START and STOP bits are defined as rising or falling edges on the data line while the clock line is kept high.
 And this is the only occurrence of falling or rising SDA line while SCL line in high. Therefore this can be captured by slave devices as start/stop condition.
Also microchip device support restart condition, which is simply send stop(P) condition and start(S) condition sequentially by the master.



Data
All data blocks are composed of 8 bits (1 Byte). The initial block has 7 address bits followed by a direction bit (Read or Write). Acknowledge bits are squeezed in between each block. Each data byte is transmitted MSB first including the address byte.

Acknowledge
The acknowledge bit (generated by the receiving device) indicates to the transmitter that the the data transfer was ok. Note that the clock pulse for the acknowledge bit is always created by the bus master.
The acknowledge data bit is generated by either the master or slave depending on the data direction. For the master writing to a slave the acknowledge is generated by the slave. For the master receiving data from a slave the master generates the acknowledge bit.

This acknowledge bit can  acknowledge(ACK) or not-acknowledge(NACK) depending on operations on the I2C bus.
  • To acknowledge the receiving device must put the SDA line into low with the next clock pulse.
  • To not-acknowledge  the receiving device must high SDA line with the next clock pulse (simply do nothing on the SDA line, then it will remain high) 
 When data receiving by the master not-acknowledge bit must generate by the master to indicate to slave, "there no need to send more data to me(master)". Then master must stop the I2C bus by sending STOP(P) condition.


Data transfer from master to slave



Data transfer from slave to master




I think now you have a brief idea about I2C communication. So let's move to code. This code was written in Hitech C for most popular PIC16f877 microcontroller which is developed by microchip Inc using its inbuilt MSSP(Master Synchronous Serial Port) unit.


Source code for complete I2C (Master) communication with PIC16f877


/**
 * Initialize the I2C module as a master mode

 * SCL - RC3
 * SDA - RC4
 * 100kHz I2C click at 4Mhz crystal
 */
void initializeI2C(){
    TRISC3 = 1;//make SCL as input
    TRISC4 = 1;//make SDA as intput

    //----------configs for SSPSTAT register------------
    SSPSTAT = 0b10000000;//SMP = 1 [Slew rate control disabled for standard speed mode (100 kHz and 1 MHz)]
    //--------------------------------------------------

    //---------- configs for SSPCON register------------
    //Synchronous Serial Port Mode Select bits
    //configs as I2C Master mode, clock = FOSC / (4 * (SSPADD+1))
    SSPM0 = 0;
    SSPM1 = 0;
    SSPM2 = 0;
    SSPM3 = 1;

    SSPEN = 1;//Enables the serial port and configures the SDA and SCL pins as the source of the serial port pins

    SSPOV = 0;//No overflow

    WCOL = 0;//No collision
    //--------------------------------------------------

    //---------- configs for SSPCON2 register-----------
    SSPCON2 = 0;//initially no operations on the bus
    //--------------------------------------------------

    SSPADD = 40;// 100kHz clock speed at 4Mhz cystal

    //----------PIR1-----------
    SSPIF = 0;//clear  Master Synchronous Serial Port (MSSP) Interrupt Flag bit

    //-----------PIR2-----------
    BCLIF = 0;//clear Bus Collision Interrupt Flag bit
}

/**
 * wait until I2C bus become idel
 */
void waitUntilIdel(){
    while(R_W || SEN || RSEN || PEN || RCEN || ACKEN){
        __delay_ms(1);
    }
}

/**
 * Send 8 bit(1 byte) through I2C bus
 * @param data - 8 bit data t be sent
 */
void i2CSend(unsigned char data){
    waitUntilIdel();
    SSPBUF = data;
    //while(BF) continue;// wait until complete this bit transmision
    waitUntilIdel();//wait until any pending transaction
}

/**
 * Send start condition to I2C bus
 */
void i2CStart(){
    waitUntilIdel();
    SEN = 1;//Initiate Start condition on SDA and SCL pins. Automatically cleared by hardware
    waitUntilIdel();
}

/**
 * Send stop condition to I2C bus
 */
void i2CStop(){
    waitUntilIdel();
    PEN = 1;//Initiate Stop condition on SDA and SCL pins. Automatically cleared by hardware.
    waitUntilIdel();
}

/**
 * Send restart condition to I2C bus
 */
void i2CRestart(){
    waitUntilIdel();
    RSEN = 1;//Initiate Repeated Start condition on SDA and SCL pins. Automatically cleared by hardware.
    waitUntilIdel();
}

/**
 * read the I2C bus
 * @return Read data from I2C slave
 */
unsigned char i2CRead(){
    unsigned char temp;

    waitUntilIdel();

    //configure MSSP for data recieving
    RCEN = 1;//Enables Receive mode for I2C

    waitUntilIdel();

    while(!BF);//wait for buffer full
    temp = SSPBUF;//read the buffer
    waitUntilIdel();//wait for any transaction
    return temp;//return the bufferd byte
}

/**
 * send acknowledge condition
 */
void i2CAck(){
    waitUntilIdel();
    ACKDT = 0;//Acknowledge Data bit(0 = Acknowledge)
    ACKEN = 1;//Initiate Acknowledge sequence on SDA and SCL pins, and transmit ACKDT data bit.Automatically cleared by hardware.
    waitUntilIdel();
}

/**
 * send not acknowledge condition
 */
void i2CNAck(){
    waitUntilIdel();
    ACKDT = 1;//Acknowledge data bit(1 = Not Acknowledge)
    ACKEN = 1;//Initiate Acknowledge sequence on SDA and SCL pins, and transmit ACKDT data bit.Automatically cleared by hardware.
    waitUntilIdel();
}


I think comments on each code line is better enough to understand these functions.
The MSSP module has three associated registers. These include a status register (SSPSTAT) and two control registers (SSPCON and SSPCON2). Above functions will configure these registers to use I2C communication in Master mode.

You can download complete source code with test program.

Next post will be a practical usage of I2C communication which use the RTC (Real Time Clock) IC DS1307.

Proteus VSM viewer to debug MPLABX projects

Hi all, Before few months earlier I heard Microchip released a new IDE to implement firmwares for their products. That is MPLABX. MPlabX has very nice features and tools to assist while you are coding, compiling, debugging, etc... If you familiar with Netbeans, it will be the great advantage to use MPLABX. Because MPLAB X is based on the Oracle Sponsored open-source NetBeans platform. Therefore supports many third-party tools, and is compatible with many NetBeans plug-ins. So try out it your self to feel the difference from MpLab8.

If you prefer to download new version of MPLABX click here

This post is not to present features of the MPLABX. So this article will introduce the way to work MPLABX with Proteus VSM viewer for debugging purposes. MPLAB8 has its inbuilt ability to work with Proteus VSM viewer. But there are a few more steps to integrate it with the MPLABX IDE. When you are working with Proteus VSM viewer in MPLABX, you will see how much easier to debug your code.

Step 1 - The first step is to install VSM viewer in MPLABX IDE.Open Plugins window by selecting Tools->Plugins from the menu bar. Then click on Available plugins, then you will see the Proteus VSM viewer from the list under 'MPLAB DBCore' category. (If proteus vsm viewer not listed on the list just press on Reload Catalog button to reload the list).

Then click on Install to install the plugin to IDE, the install wizard will guide you to install it successfully. Also you can update or remove you existing plugins from this window.

Step 2 - Create your project from MPLABX and select Proteus VSM viewer as debugging tool when it asked.As showed in following figure.

OR you can set Proteus VSM as the debugging tool for you existing project. Just goto project Properties by right click on your project. Then click on 'Config: [default]' category. Then select Proteus VSM from the list box positioned at right side of the window as shown below.

Step 3 - Now you can code your project and compile your project in debug mode. To do that right click on your project from the Projects window then select Debug from the drop down menu. Now this will lead to create files and folder hierarchy for debugging by IDE, if your code compile successfully. (This will terminate debugging session until we still do not create a ISIS design for our project. Just don't care those!)

Step 4 - Create the design file file for your project from the Proteus ISIS and select the .cof file which is located at \dist\default\debug folder as the program file for your micocontroller(in ISIS design). Then save the design in your project folder.

Step 5 - Now we should add our design file to MPLabX project. Go to project properties window and click on Proteus VSM Viewer category under Config: [default] category then select your design file from Design File Name and press on apply (you can let other configurations as it is under default environment).

Now you can set break points in your source code and Debug your project. Then MPLabX will automatically run the ISIS design simultaneously with your code.

Oh I forgot to say, it is better to only open your ISIS design from the Proteus ISIS while you debug and enable Remote Debug Monitor from Proteus ISIS (Debug->Use Remote Debug Monitor)

Then you can open both windows simultaneously and debug you project as you can see...




Create GUI with Gtkmm - Glade with gtkmm

Previous post introduced the Gtkmm library and eclipse IDE for gtkmm development. As I mentioned at there, there are two possible ways to design gtkmm GUI either from code or Glade UI designer. I believe (and most of people believe) that Glade UI designer is the easiest way to create GUI for gtkmm development. Glade has a very user friendly environment to design and create GUI and finally the created GUI can be export as a xml file with two different formats as GtkBuilder and libglade. For this and future examples I am willing to use GtkBuilder format.
Now let's create a simple GUI from Glade. First you have to install Glade on your system, you may use synaptic package manager or Ubuntu software center to install it.

When you run Glade you may see the following window as the main window of Glade.




As you can see, left hand side of the window includes the palette which has all the gtkmm widget that glade support, and right hand side includes the properties of the selected widget and all the widgets list as a hierarchical list.

Every gtkmm GUI needs a top level window. Therefore first of all add a 'Window' from the palette, then you can add more widgets to the window. Also there is a widget type called 'Containers', containers can have one or more widgets on it. Therefore you should add proper containers to the empty window to include more widgets. For this example first add 'Vertical box' to window with 2 items. Then I added 'Label' to first position and 'Horizontal box' with 2 items to second position of vertical box. Likewise I have created the following GUI and saved it as GtkBuilder file format with the file name “gui.glade”. Also I have changed names of some widgets to make design file more understandable. The xml file for Glade GUI can be found at the end of this article for downloads.




Now let's write a C++ code for this GUI. As we all know C++ is a OOP language, but still we did not use the advantage of the OOP behavior for our gtkmm codes. Now let's see how to encapsulate all the things which are related to specific gui into one class.

First add new class to your project by right click on the eclipse project and selecting new class from the pop-up menu. It will create two file on the project's src folder as header file and source file. Copy following code to header (.h) file.

#include <gtkmm.h>

class FrmMain : public Gtk::Window{
protected:
    Glib::RefPtr<Gtk::Builder> builder;
    Gtk::Button *btnOk;
    Gtk::Button *btnCancel;
    Gtk::Label *lblNotice;

public:
    FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);//constructor

protected:
    //signal handlers
    void on_ok_button_clicked();
    void on_cancel_button_clicked();
};

Code explained

class FrmMain : public Gtk::Window{
FrmMain is the class name and this class was inherited Gtk::Window class which enable to use FrmMain class as a Gtk window.

Glib::RefPtr<Gtk::Builder> builder;
Gtk::Button *btnOk;
Gtk::Button *btnCancel;
Gtk::Label *lblNotice;
These are the widget variables which enable you to execute some operations on that. Here, builder variable is essential to import and load xml file to our code.

FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);//constructor
This is the constructor of the class. The parameters defined in here are essential to initiate the Gtk::Window and Gtk::Builder.

void on_ok_button_clicked();
void on_cancel_button_clicked();
These are the declarations for signal handlers for the signal which are emitted by widgets of the GUI  (Such as event handlers in Java or C#).

The source file for the above header file will be,

#include "FrmMain.h"

using namespace Gtk;

FrmMain::FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
    Gtk::Window(cobject), builder(refGlade){

    builder->get_widget("btnOk", btnOk);
    builder->get_widget("btnCancel", btnCancel);
    builder->get_widget("lblNotice",lblNotice);

    btnOk->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
    btnCancel->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));

}


void FrmMain::on_ok_button_clicked(){
    lblNotice->set_text("OK clicked");
}

void FrmMain::on_cancel_button_clicked(){
    lblNotice->set_text("Cancel clicked");
}

Code explained

FrmMain::FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
    Gtk::Window(cobject), builder(refGlade){
The constructor, initiate by calling super class constructor as Gtk::Window(cobject) and builder as builder(refGlade).


builder->get_widget("btnOk", btnOk);
builder->get_widget("btnCancel", btnCancel);
builder->get_widget("lblNotice",lblNotice);
These code lines will assign widgets from xml to variables which are declared in header file. (btnOk, btnCancel and lblNotice are the names which I assigned for widgets from Glade).  get_widget function will allows you to get widgets from xml file to your variables. So you can use these variable to manipulate GUI's widgets as your wish.


btnOk->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
btnCancel->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));
These code lines will connect signal handlers from xml file to your functions. That's mean when you click on btnOk button it will call the function  on_ok_button_clicked on your source code. So you can include your codes to execute when click on the button. But you can not change the the return type and parameter list of these functions as your wish. There are predefined formats for each signals. You can refer the format from the source of the signal. To navigate to the source of the signal you can click on the 'signal_clicked' while pressing on ctrl key on eclipse IDE. You may see the code like this,

  Glib::SignalProxy0< void > signal_clicked();

Here zero mean no parameters and void means return type is void. Let's see another example,

  Glib::SignalProxy1< bool,GdkEventButton* > signal_button_press_event();


Here 1 mean one parameter with the type of GdkEventButton* and bool return type. Therefore your function will be,

bool on_my_button_press_event(GdkEventButton* event){
}


void FrmMain::on_ok_button_clicked(){
    lblNotice->set_text("OK clicked");
}

void FrmMain::on_cancel_button_clicked(){
    lblNotice->set_text("Cancel clicked");
}

Now these are the code for signal handlers. Each one will set a specific text to lblNotice label.

So our encapsulated class is ready for execution. But where is the place to import or load xml file to the project by giving the file name of the xml file? This task perform on the main function of the project as,

Main kit(argc,argv);
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("gui.glade");

FrmMain *frm = 0;
builder->get_widget_derived("frmMain", frm);
kit.run(*frm);

Code explained

Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("gui.glade");
This will load all xml (glade) file to builder variable and allow to use the file as a gtk builder.


FrmMain *frm = 0;
builder->get_widget_derived("frmMain", frm);
kit.run(*frm);
get_widget_derived function allow to load a gtk widget from xml file to the derived class which we already implemented. Then the derived object can be use to run the main loop of the gtk.

If you run the code, you will see the result as,

when you click on OK and Cancel button the text of the label will change accordingly.

So now you can encapsulate all the variables, functions and structs, etc... to a class through this way. Also this will enable re-usability of the code.

The complete source code can be download here (with the glade xml file).


Create GUI with Gtkmm - Setup Eclipse for Gtkmm

gtkmm is the official C++ interface for the popular GUI library GTK+. You can create user interfaces either in code or with the Glade User Interface designer, using Gtk::Builder.
Still you can use gtk on C++, but C++ is the Object Oriented Programming language then Gtkmm enable you to use some OOP techniques such as inheritance, polymorphism, etc... Also enable you to use standard C++ libraries on Gtkmm calls. Also gtkmm can be use to create GUI in C++ with the large number of widgets which you need to decorate your GUI.

I am willing to write a series of articles/tutorials about Gtkmm and its variance widgets with practical examples. Because I used gtkmm for my final year project and I would like to share the knowledge that I garbed with you all. This article describe the initial steps that you should follow to setup gtkmm library on Ubuntu and configure eclipse for gtkmm developing. I am using Eclipse Helios on Ubuntu 11.04 (64-bit).

Step 1 (Install required packages)
As you know there are several ways to install packages on Ubuntu. I am using Synaptic package manager for that.
So open synaptic from application menu and search for gtkmm-dev and install the latest version from the search result. I have installed libgtkmm-2.4-dev package. When you install synaptic will indicate some dependencies such as gtk++, install them all to complete the installation. I hope that you have the working eclipse with CDT (C/C++ Development Tooling).


Step 2 (Setup Eclipse for Gtkmm)
I am using CDT installed Eclipse IDE‌ for C++ developments. Because it has more features which are more helpful to developer to write programs effectively and rapidly.
Eclipse needs to be setup in order to create gtkmm project. Eclipse needs to complete these setups to compile the program successfully and fill the auto complete menu with all the functions, variables, data types, etc...
Initially you need to select Linux GCC as the toolchain when you create a C++ project on eclipse.
  1. Right click on the project that you need to be configure and select Properties from the menu.
  2. Expand C/C++ Build from the left side pane and click on Settings.
  3. Then click on GCC C++ Compiler.
  4. Paste following command line options between ${COMMAND} and ${FLAGS} to Command line pattern: text box.
    `pkg-config --cflags --libs gtkmm-2.4`
    Note - 2.4 holds the installed version, replace it with your version, if you installed different version.

    Now you may have the full text of the Command line pattern as,
    ${COMMAND} `pkg-config --cflags --libs gtkmm-2.4` ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
  5. Click on GCC C++ Linker and follow the same procedure as previous step.
  6. Now click on Includes under GCC C++ Compiler.
  7. Add include paths to the list and let eclipse find the header files on these paths. Click on add button and add following paths to the list. You should change the location by considering your location which includes installed on and version.

    /usr/include/gtkmm-2.4
    /usr/include/gdkmm-2.4
    /usr/include/glibmm-2.4

    Somehow finally you should include paths for gtkmm, gdkmm and glibmm libraries header files.

Now Eclipse ready for gtkmm development. Let's write a simple testing program to check the gtkmm.

First you should include following header files to the program. As,
#include <gtkmm.h>

Your main function should look like this,

int main(int argc, char **argv) {
    Gtk::Main kit(argc,argv);//The constructor for this object initializes gtkmm
    Gtk::Window frmMain;

    kit.run(frmMain);

    return 0;
}

Code explained,
All the gtkmm programs accepts command line arguments list as above (int argc, char **argv). Therefore all the gtkmm programs should follow the same argument list as describe in here.

Gtk::Main kit(argc,argv);//The constructor for this object initializes gtkmm

This line will initialize the basic gtkmm functionalities and let program to run gtkmm functions. Also checks the arguments passed to your application on the command line, looking for standard options such as -display.


Gtk::Window frmMain;

This will create a new widget of Gtk::Window type as frmMain to hold the main window of the program.


kit.run(frmMain);

This is the main loop of gtkmm and let user to use the widgets. This line will display the window which we already created.

You can download the complete source code of this testing program. Resultant of the program is an empty window as,

Next article will describe the OO behavior of gtkmm and introduce the Glade UI designer for gtkmm.

Cteate Stack in C++ using template

Stack is a data structure that allows access to only one data item at a time. If you remove this data item from the stack you can access to the next to last data item of the stack. Also stack perform a Last-In-First-Out(LIFO) operation on the stack. You may find more on stack here.

I will explain basic stack operations and then let's move to code.

Push - Insert a data item to the top of the stack.

Pop - Remove a data item from the top the stack.

Peek - Retrieve the data item from the top of the stack.

Other stack operations can be understand by just looking at the code simply.




This is the stack created by using template of C++. So that you can set any data or class type for stack data. Further more this post will answer the question, How to create template stack in C++?

The Stack.h source file is,

#include <stdlib.h>

#ifndef STACK_H_
#define STACK_H_

template<class T> class Stack{

private:
    unsigned int maxSize;
    T *stackData;
    int top;

public:
    Stack(int size){
        stackData = new T[size];//to hold the T ‌type data items
        top = -1;//no items on the stack
        maxSize = size;//set maximum size that stack can hold
    }


    virtual ~Stack(){}

    int count(){
        return top + 1;
    }


    bool isEmpty(){
        return top == -1 ? true : false;
    }


    bool isFull(){
        return top == maxSize - 1 ? true : false;
    }


    T* peek(){
        if(!isEmpty())//check for empty
            return &stackData[top - 1];
    }


    T* pop(){
        if(!isEmpty()){
            top -= 1;//decrease the top by 1 to indicate the delete
            return &stackData[top];//return deleted item
        }
        return NULL;
    }


    void push(T* item){
        stackData[top++] = *item;//insert to data array and increase the top by one
    }
};


#endif /* STACK_H_ */

Then the demonstration code,

#include <iostream>
#include "Stack.h"

using namespace std;

int main() {

    int data;
    Stack<int> intStack(10);//create integer stack with maximum 10 items

    //insert data to stack
    data = 1;
    intStack.push(&data);
    data = 2;
    intStack.push(&data);
    data = 3;
    intStack.push(&data);
    data = 5;
    intStack.push(&data);

    //get top item
    cout << *intStack.peek() << endl;

    intStack.pop();
    intStack.pop();

    //get top item
    cout << *intStack.peek() << endl;
   
    return 0;
}


I expect this will help anybody who want to create stack with the template!

Style source codes on the web page

Is there any way to change style of the source code that you include in the web page with simple method? Yes, there is. If you read my previous posts such as hibernate operations, ant build file, you can see the way my source codes are presented. Key words, variable names, and class names, etc are formatted according to the language that source code belongs.

How did I formatted these text on the web page? Did I change font color of each words on the text? No there is a easy method to do that. Thanks to google code prettify on google code.

This is the method that you should follow to format your source code snippets in an html page.

You can simply download their zip file and add those source file to your web page by uploading to the hosting server.

But I will explain an easy way to do that using online resources itself without downloading and uploading.

Step 1
Okay first you have to add reference CSS and JavaScript file to your web page's head section. Copy following code to head section on your web page.

<link href='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css' rel='stylesheet' type='text/css'/>
<script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'/>

If you are a google blogger you should copy the above code to blog's layout head section.
Here we use their online resource of CSS and JavaScript file to load styles and functions to our web page.

Step 2
Now just only one initialization for our code formatter. Copy the following code to body tag on your page.
You should use the layout as same as previous step, if you are a google blogger.

onload="prettyPrint()"

As an example

<body onload="prettyPrint()">

Step 3
Now just surround your text which you want to format with code or pre tag and set the Prettier class to specify the language. that is all. following example show you how to do that.

Example -
Normal text of your source code is,

//This is JAVA source code
import java.util.Scanner;
class keyboardDemo {
    public static void main(String[] arg) {
        //read from System.in = normally keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter two integers : ");
        int x;
        //read the inputs
        x=keyboard.nextInt();
    }
}

Now surround this text with code tag and particular style on your HTML source code.

<code class="prettyprint lang-java">
//This is JAVA source code<br />
import java.util.Scanner;<br />
class keyboardDemo {<br />
&nbsp;&nbsp; public static void main(String[] arg) {<br />
&nbsp;&nbsp; &nbsp;&nbsp; //read from System.in = normally keyboard<br />
&nbsp;&nbsp; &nbsp;&nbsp; Scanner keyboard = new Scanner(System.in);<br />
&nbsp;&nbsp; &nbsp;&nbsp; System.out.print("Enter two integers : ");<br />
&nbsp;&nbsp; &nbsp;&nbsp; int x;<br />
&nbsp;&nbsp; &nbsp;&nbsp; //read the inputs<br />
&nbsp;&nbsp; &nbsp;&nbsp; x=keyboard.nextInt();<br />
&nbsp;&nbsp; }<br />
}<br />
</code>

Now you can see the formatted source code as follows on your web page,

//This is JAVA source code
import java.util.Scanner;
class keyboardDemo {
    public static void main(String[] arg) {
        //read from System.in = normally keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter two integers : ");
        int x;
        //read the inputs
        x=keyboard.nextInt();
    }
}


If you need you can surround code with a div tag to change background color and wrapping style.

My div tag looks like this,

<div style="background: none repeat scroll 0% 0% rgb(209, 206, 206); border: 2px none; overflow: auto; white-space: nowrap;">

</div>

Now final styled text is,

//This is JAVA source code
import java.util.Scanner;
class keyboardDemo {
    public static void main(String[] arg) {
        //read from System.in = normally keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter two integers : ");
        int x;
        //read the inputs
        x=keyboard.nextInt();
    }
}

Code prettify support several language for style them. To change the language that you need to style just change the class of the style to your language.


For JAVA,

<code class="prettyprint lang-java">

Example -

//This is JAVA source code
import java.util.Scanner;
class keyboardDemo {
    public static void main(String[] arg) {
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter two integers : ");
        int x;
    }
}

For xml,

<code class="prettyprint lang-xml">

Example -

<project default="final" name="yourProjectName">
           <target name="final" description="this is a function to echo some text">
                    <echo message="Hello world..."/>
           </target>
</project>


For HTML,

<code class="prettyprint lang-html">

Example -

<!DOCTYPE html>
<html>
    <body>
        <h1>My First Heading</h1>
        <p>My first paragraph.</p>
    </body>
</html>

You can refer this page for further more support languages. So that's all have fun with this!



Migrating from Visual SourceSafe to Team Foundation (VSS to TFS)

This post will describe how to totally migrate a Visual Sorcesafe database to Team Foundation Server. After migration the database you will have all the details on VSS database such as your source codes, users, and version history, etc...

There are some prerequisites which you should consider before start the migration process. Those are,
  • Team Explorer on Visual Studio.
  • Log on to the computer by using administrative credentials.
  • SQL Server Express.
  • Visual SourceSafe 2005 or later versions.
  • The Visual SourceSafe database that you want to analyze.
  • The administrator’s password for the Visual SourceSafe database.
And also some permissions, Therefore To perform the procedures in this post, you must have the following permissions.
  • In the Visual SourceSafe database that contains the data that you want to migrate, you must know the password of the Admin account.
  • On the migration machine (the machine where Visual Studio is installed), you must be a member of the Administrators group.
  • On the database that VSSConverter uses, you must have "create database" permission.
  • Be a member of the sysadmin server role for SQL Express. (By default, you are a member of the sysadmin server role if you are a member of the Administrators security group on the computer where SQL Express is installed.)
  • On your application tier for Team Foundation, you must be a member of the Team Foundation Administrators security group. For more information, see Team Foundation Server Permissions on MSDN.
Basically there are 3 main steps involved on migration.
  1. Preparing the Visual SourceSafe Database
  2. Analyzing the Projects for Migration.
  3. Migrating SourceSafe Project Folders to TFS
1. Preparing the Visual SourceSafe Database
This step also can be break down into three steps.

  1. Ask all database users to check in their files.
  2. Create a backup copy of your Visual SourceSafe Database to migrate.
  3. Use the Visual SourceSafe Analyze utility to locate and fix data integrity issues in the database.
a. Ask all database users to check in their files.
You should make sure that all the users are not loged-in to the VSS and all the files are checked in to the VSS.

So you can check loged in users from "Microsoft Visual SourceSafe Administration" tool. (Start --> All programs --> Microsoft Visual Sorcesafe --> Microsoft Visual SourceSafe Administration).

Also you can list all the check out files with the checked out user by issuing following command on cmd.
Here we are using ss.exe which is supplied by VSS therefore you should change the directory to VSS installation path.
Ex:- cd "C:\Program Files\Microsoft Visual SourceSafe"
If you need user wise list, type following command on cmd
ss status -R -Umilinda > "C:\Users\milinda\Desktop\VSS Checkouts\milindaCheckouts.txt"
This command will save all the files those checked out by milinda to the C:\Users\milinda\Desktop\VSS Checkouts\milindaCheckouts.txt file.
If you need all the checked out files list, type following command on cmd
ss status -R > "C:\Users\milinda\Desktop\VSS Checkouts\allCheckouts.txt"
This command will save all the files those checked out by all users to the C:\Users\milinda\Desktop\VSS Checkouts\milindaCheckouts.txt file.

b. Create a backup copy of your Visual SourceSafe Database to migrate.
Make sure that no one is using the database and that Analyze will not begin to run while you are backing up the database. To backup the VSS database just copy the following folders and files which are located on sorcesafe's database path. (You may find this database path from Visual SourceSafe Explorer File --> Open sorcesafe databse or press Ctrl+P).
  • \DATA
  • \Temp
  • \USERS
  • user.txt
  • srcsafe.ini
When you follow this procedure, you can do a full restore of the database by replacing the existing Users, Temp and Data folders as well as the Users.txt and Srcsafe.ini files with the copied versions.
You can also use this procedure to move the database to another location by placing the copied files into a new folder. To open the database, on the File menu in the Visual SourceSafe Explorer, click Open SourceSafe Database to browse to the new location.


c. Use the Visual SourceSafe Analyze utility to locate and fix data integrity issues in the database.

Just run analyze.exe on command prompt as “analyze -F -V3 <sourcesafe data directory>” which is located onC:\Program Files\Microsoft Visual SourceSafe”

-F stands for fix, This will automatically repairs inconsistencies and corruption that are detected, as long as no users are logged in.

-V3 to displays all errors.

More command line options can be found here.

Remember you should give the data path (\DATA) as argument not the database path which you found from Visual SourceSafe Explorer.

As my experience it will take 3 hours to 4 hours time duration to complete the analysis on 4.2GB database. Somehow this duration depends on errors on your database also.

Now preperation of Visual SourceSafe Database is finished. Let's move to next step.

2. Analyzing the Projects for Migration.

This process is based on xml input file. After running this step you will get an user mapping file and analyze report file which are needed for next step.

VSSConverter.exe tool is used to analyze the VSS projects that located on “C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE”. But still you can be invoked it from the Visual Studio command prompt. Or simply cd to the above path from cmd and follow the following commands.

My recommendation is copy VSSConverter.exe and VSSConverter.exe.config file to a different location and perform following commands.

VSSConverter.exe accepts following inputs to perform its operations
  • A path of the folder that contains the srcsafe.ini file for the Visual SourceSafe database under migration.
  • An XML-based file that contains settings.
This path you may find on Visual SourceSafe Explorer (File --> Open sorcesafe databse or press Ctrl+P)

The XML-based file format is,


<?xml version="1.0" encoding="utf-8"?>
<SourceControlConverter>
      <ConverterSpecificSetting>

            <Source name="VSS">
                  <VSSDatabase name="VSSDatabase_name"></VSSDatabase>
            </Source>

            <ProjectMap>
            <Project Source="$/FolderA"></Project>
            <Project Source="$/FolderB"></Project>
            </ProjectMap>

      </ConverterSpecificSetting>

      <Settings>
       <Output file="Analysis.xml"></Output>
     </Settings>
</SourceControlConverter>

  • Modify the VSSDatabase_name to point to the path to your VSS database.
  • In the <projectmap> section, specify the Visual SourceSafe folders to analyze. 
    • To analyze the whole database, use <Project Source="$/"></Project>
  • Save above XML file as settingsAnalyze.xml to the directory where VSSConverter.exe and VSSConverter.exe.config file located.
Now you can run the converter tool to analyze VSS projects. The user who is performing the analysis must be a system administrator for SQLExpress. By default, the user who installs Visual Studio will receive the required permissions for SQLExpress.
  • cd to directory where VSSConverter.exe and VSSConverter.exe.config file located and run following command
    • VSSConverter Analyze settingsAnalyze.xml
  • When you are prompted, provide the Visual SourceSafe administrator password.
The converter tool displays the status of the pre-conversion analysis. When it is completed, it generates a report (VSSAnalysisReport.xml) and a user mapping file (usermap.xml), and saves them in the current directory.

You can use this user mapping file to map Visual SourceSafe users to Team Foundation users.

3. Migrating SourceSafe Project Folders to Team Foundation Server


The converter also needs an xml file. It is most similar to settings.xml file which is created at analyze step. Therefore,

  1. Copy settingsAnalyze.xml file content and save it as settingsMigration.xml. (Ensure that the system drive has sufficient space to hold the largest file size under migration.)

  2. Change the settings file as follows.
    • In the <ProjectMap> sections, for each Visual SourceSafe folder, add the destination folders in TFS. This destination should be already created on TFS.
      <Project Source="$/FolderA" Destination="$/Team_ProjectA"> </Project>

    • To migrate everything in your Visual SourceSafe database, insert the following XML instead.
      <Project Source="$/" Destination="$/Team_Project/"> </Project>

    • Under the <Settings> section, add a <TeamFoundationServer> section, and specify the name, port, and protocol for the Team Foundation Server to which you are migrating. Use the following format. Here you should set the collection to a collection that you created on TFS insted of 'DefaultCollection'.
      <TeamFoundationServer name="TFS_server_name" port="port_number" protocol="http" collection="tfs/DefaultCollection"></TeamFoundationServer>

    • Remove <Output file="Analysis.xml"></Output> from the <Settings> section, or rename the output file to "migrationAnalysis.xml".
  3. Overall structure of a migration settings file as follows

    <?xml version="1.0" encoding="utf-8"?>
    <SourceControlConverter>
       <ConverterSpecificSetting>
          <Source name="VSS">
             <VSSDatabase name="VSSDatabase_name"></VSSDatabase>
             <UserMap name="c:\Migrate\Usermap.xml"></UserMap>
          </Source>
          <ProjectMap>
             <Project Source="$/FolderA" Destination="$/TeamProjectA">
             </Project>  
             <Project Source="$/FolderB" Destination="$/TeamProjectB/ProjectB">
             </Project>
          </ProjectMap>
       </ConverterSpecificSetting>
       <Settings>

          <TeamFoundationServer name="server_name" port="port_number" protocol="protocol" collection="tfs/DefaultCollection"></TeamFoundationServer>

        </Settings>
    </SourceControlConverter>

  4. Edit the Source Control Migration User Mapping File
    If you want to map user name to TFS from VSS as it is, you can keep usermapping.xml file remain unchanged and go to next step.

    The analysis phase generated a user map file. The user map file consists of all Visual SourceSafe users who have performed any source control operation on the folders that you specified for the migration. You use this file to map Visual SourceSafe users to Team Foundation users.

    For each Visual SourceSafe username you want to map, add a valid Windows user name or Team Foundation Server user name in To field, as shown in the following example. The ADMIN user in VSS should be mapped to a real user in TFS, typically the project administrator. Users in VSS who are no longer with the company should be mapped to existing users.

    For example,

    <?xml version="1.0" encoding="utf-8"?>
    <UserMappings>
        <UserMap From="Admin" To="MYDOMAIN\Jennifer"></UserMap>
        <UserMap From="guest" To="TestAlias1"></UserMap>
        <UserMap From="Jane" To="Jane"></UserMap>
        <UserMap From="Mike" To=""></UserMap>
    </UserMappings>

    If you provide a user name mapping similar to <UserMap From="Mike" To=""></UserMap> where "Mike" is a valid Windows user name, Team Foundation maps "Mike" to "MYDOMAIN\Mike," where MYDOMAIN is the default domain.

  5. Before you run the following command you should create the team project as you define on settingsMigration.xml file. You can refer this to create new team project

  6. Execute following command on cmd to migrate the VSS database to TFS as you define in above xml files.
              VSSConverter Migrate settingsMigration.xml

  7. When you are prompted, provide the password for the Visual SourceSafe admin user.

So that is it.........
After long post, you may have a totally migrated TFS database from VSS with all the VSS data such as source files, histories, users, etc..

The whole process takes 6-7 hours time duration to migrate 4.2GB VSS database. But this may change up to your database size, users, histories, network speed, etc.

I apologize, If this post is getting too long but these are the basic step that you should follow to migrate. Have a nice day thanks.

Microsoft Team Foundation Server (TFS)


Why do we need version controller or source controller? This post will answer this question and introduce a version controller which is introduced by Microsoft (Team Foundation Server) and compare it with the Microsoft visual sourcesafe.

This is a compact post of all above things, most of the things had refer on internet. Thanks every one who write these things on the web.

Let's try to answer above question. Actually why do we need a Version Control System (VCS)? Let's assume you are working on a large project and each single module developed by single programmer and also they need to share their source or builds among each others when they needed. So simply you can suggest a shared folder to hold all the sources and builds which every one can access it. But what's happen when two programmers open same project and edit it by both of them? Exactly it will complicated for both programmers. And also there are no way to control versions ~ can not roll back to previous version. Now you understood the needs of VCS.

You may find available VCS here

Now let's move to TFS.

What is TFS?

Team Foundation is a client-server source control system that uses a .NET Web service to access items stored in a SQL Server database.
  • Version control, for managing source code and other deliverables that require versioning.
  • Work item tracking, for keeping track of such things as defects, requirements, tasks, and scenarios.
  • Project management functions, which allow the shaping of a team project based on a user-specifiable software process, and which enable planning and tracking using Microsoft Excel and Microsoft Project.
  • Team build, for enabling a common process for building executable products.
  • Data collection and reporting, which aid in the assessment of a team project's state, based on information gleaned from Team Foundation Server tools.
  • The Team Project Portal, which provides a central point of communication for a team project packaged as a Microsoft Windows SharePoint Services site.
  • Team Foundation Shared Services, which provide a number of common infrastructure services that invisible to end users but that, are important to tool smiths and extenders.

Ways to access TFS

  • From Visual Studio – through Team Explorer
  • From the command line
  • From the web browser
  • From Microsoft Office products
  • From other platforms or IDEs
  • From Windows Explorer
There are some other products also to access to TFS.

Following figure shows the web interface of the TFS



Comparison between Visual Source Safe and TFS.

Visual source safe is an old software that Microsoft developed for version control. Most of the visual studio programmers are still use SourceSafe. But there is a way to completely migrate from VSS to TFS. We will see that method later. Now let's move to comparison.







VSS
TFS
Description
Security and Project Rights
Low
High

Reliability

Low
High
VSS does not have a server component, while TFS is client server application. TFS writes operations occur in the database by way of stored procedures that are not subject to network connectivity issues.
Scalability
Low
High
TFS can support teams of up to 2000 users whereas VSS is recommended for teams of 20 or less.
Sharing and Pinning
Yes
No
Share or Pin features not in TFS. When you migrate VSS projects to Team Foundation, Pins in a Visual SourceSafe database are replaced by labels.
Check-Out and Check-In
Yes
Yes
In Visual SourceSafe, you must do an explicit check-out and check-in only if you are editing a file. In Team Foundation, every action requires an explicit check-out and check-in.

Team Foundation Features that Do Not Exist in Visual SourceSafe

Visual SourceSafe Features that Do Not Exist in Team Foundation

  • Share
  • Pin
  • Archive and Restore
  • Destroy
  • Keyword expansion
  • Rollback
 Next post will be a complete guidance to migrate VSS database to TFS.