Binary Numbers

Programming in 'C'

Introduction

The 'C' computer language is one of the most widely used languages. It is useful as it can be used for many applications. Most of Unix, Linux and the Microsoft Windows operating systems are written in it as are a large number of applications. It is also widely used in embedded computers as used in TV's, Mobile phones, games consoles etc.

'C' is a compiled language. A program is written in an, english like, text fashion in a number of text files. These files are then passed to the compiler which validates the source code and compiles it into binary machine code for the CPU in question. There are actually three main phases of compiling a program:
  1. Preprocessing: In this phase the pre-processor execures the code in lines starting with a "#". The main operations are to "include" other files and to expand macros.
  2. Compile: The pre-processed code is compiled to the binary machine code of the CPU being used.
  3. Linking: The binary code from multiple files is linked together together with libraries of code to form the final program.
'C' is a proceedural language. A program runs line by line in a single sequence. In 'C' there is a set of computer instruction code and a set of data that the code manipulates. As with most computer languages it is not tollerant of errors. The code written has to be absulutely correct. The compiler can detect a lot of basic syntax programmer errors, but it can and does leave a lot of gotchas for the programmer.

Preprocessor

The prepocessor allows constants and other macros as well as including files to be performed before the actual 'C' compiler is run.
#include <stdio.h>

#define    CLOCK        4000000        // Clock frequency

Data Types

In 'C' all pieces of data (variables) need to be defined and have a type and a name to refer them by.

Data Types

int a;
32bit integer value named "a". (Note that the int type may be 8bit,16bit,32bit or 64bit depending on the machines basic architecture)
float b;
32bit floating point number (3.12 x e9)
char c;
8bit integer value named "c". The char type is also used to hold an alphanumeric character for text manipulation
short d;
16bit integer value named "d".
void
No data type


Data items, commonly termed variables, can have names written as alphanumeric strings. There are rules as to what characters are allowed. There are also reserved names in 'C' like "if", "for", "while" etc.
Always try and use names meaning full to their use. This makes it much easier to understand the code.
Often the typedef feature is used to define a new data type name based on the standard data types.
typedef unsigned int    UInt32;

Arrays

Any data type can be made into a sequential list called an array. The syntax is:
int    ages[128];
This defines an array of characters 128 elements long. Individual elements can be accessed using [].
int	ages[4];
int age;
int i;

age[0] = 11;
age[1] = 12;
age[2] = 13;
age[3] = 14;

for(i = 0; i < 4; i++){
printf("Age: %d\n", age[i]);
}

Memory usage

All program manipulated data is stored in the systems RAM memory. This memory has a random value until it is set up by the program. Memory is accessed by an address which is a numeric value. The compiler will associate a data items name with a particular address in memory. The following shows a simple memory map for a simple embedded CPU unit.

0x0000 - 0x8000
Program Code
0x8000 - 0xE000
Main data area for program usage
0xE000 - 0xF000
Access to device registers (Disk, Display, Keyboard etc)
0xF000 - 0xFFFF
Data area on Stack for program usage

There are two main areas of memory used for data, the main data area and the stack data area. The main data area is where any data defined outside of a function is stored. This data is shared by all functions. The stack data area is memory allocated for any functions variables.

Simple Example

#include <stdio.h>
float func1(int a, int b){
    float   r;
    r = a * b;
    return r;
}

int main(){
    int   c;
    float   f;

    // Loop incrementing c and printing it
    for(c = 0; c < 10; c++){
       printf("Hello number is: %d\n", c);
    }

    // Calling a function
    f = func1(3, 4);
    printf("Result: %f\n", f);
    return 0;
}
The program starts at the function named "main".

General Code

Each program statement is terminated with a ';' character. A set of statements are grouped using the '{' and '}' brackets. Generally mathmatical equation syntax can be used using operators. For example:
	a = (3.14159 * diameter) / (3.8 * width);
c = c + 1;
c++;
Each statement is executed line by line.

Strings

'C' does not have special handling of characters and strings. The user uses the "char" data type to store an individual character and and array of "char"'s to store a string. It does allow a string to be defined by using the double quote character. though.
char    str[] = "Hello there";
Characters are normaly defined using the ASCII coding scheme although unicode is now becoming the norm to allow multiple human language support. In ASCII 'A' = 41, 'B' = 42 ... There special characters, such as a line feed or tab character are included using a backslash character. '\n' = 10, a line feed, '\t' = 9 a tab etc.

There are a number of standard 'C' library functions that assist with string handling such as strcpy(), strcmp() etc.
char	name[64];
char ch;

strcpy(name, "Fred");
if(!strcmp(name, "Fred")){
printf("The name is Fred\n");
}

ch = name[0];
name[0] = 'N';

Loops and Control

Control can be performed with "if", "else" and "switch" statments amougst others.
if(key == 'a')
printf("A has been pressed\n");

if(key == 'b'){
printf("A has been pressed\n");
}
else {
printf"A key other than a has been pressed\n");
}
   
There are a number of looping types including for and while.
for(c = 0; c < 100; c++){
printf("C is: %d\n", c);
}

c = 0;
while(c < 100){
printf("C is: %d\n", c);
c = c + 1;
}

Style

It is important to write the code in a structured, clear and standard way. Although it is possible to write a program on a single line of text with no spaces etc, this code will be barely readable. There are a few styles in use, but most are similar. The main thing is to have one statement per line and have an indent for each block of code (normally a TAB although some use spaces).
One of the main current programing methods is to write in a high level object orientated fashion. With this the data and functions of a program parallels the real world system it is implementing as much as possible. Also programs are modularised from a high level down to low level functions.
Capetalisation is often used to help describe items.

Functions

Functions allow a set of common code to be grouped together and used from multiple places and different programs easily. It is very important when designing a program to group you code in a meaningfull way. This makes it easier for you and others to understand the code for fixing bugs or modifying its functionality in the future.
A function takes a list or arguments or parameters and returns a single value.
float func1(int a, int b){
    float   r;
    r = a * b;
    return r;
}

Printf

The "printf" (print formated) function is a very comanly used function for examples and debug. It prints out the string passed as an argument parsing any "%" parameters and displaying the appropriate values. The common "%" types include:
%d
Print out an integer
%f
Print out a floating point number
%s
Print out a string
%c
Print out a single characher in a char.

Pointers and Dynamic memory Allocation

Pointers are one of the most difficult but powerful features of 'C'. It is also the feature that causes the most bugs. It allows any data itme to be refered to by its address in memory. This can be used to effoiciently pass a pointer to some large pice of data to and from functions for example. String handling uses pointers extensively. Further reading needed here.
Variable sized Data areas cane be allocated and freed using the malloc() and free() library functions.

Libraries and Modular Programs

The core of the 'C' language is relatively simple. Producing a program just using the core of 'C' would be time consuming and difficult. In order to easily produce a program programmers make use of libraries of pre-written functions. The main library used is the standard 'C' library. Howver there are many others especially incluing the libraries for graphical user output in windows etc. A programer needs to read over the libraries list of functions to get a idea of what is available and how to use them.
All input and output of data from the program is handled by library functions be it to and from a disk, keybpoard or display. Each operating system and/or device will have its own methods of doing this.

There are two types of file used with libraries. There is the set of 'C' source files (*.c) that contain the code for the functions  and there is a set of header files (*.h). The header files declare the functions and data that are in the library. They also specify the functions arguments and return value types and any constants used by the library. They are the libraries specification.

Data Structures

Data structures allow the programer to create different data types for use in programing. They can store multiple elements of data in a single variable.
struct Contact {
char name[64];
int arge;
char address[128];
};

Contact c;

strcpy(c.name, "TerrY");
c.age = 21;
printf("Name: %s Age: %d\n", c.name, c.age);

Some Simple Examples

Below are some simple examples of embedded code from the Rotary racer Greenpower car computer. This uses 'C' on a small PIC microprocessor. The 'C' dialect is a bit special for this class of small microprocessors but the basic 'C' language can still be used. Some of this code uses a library specially written for the car computer.

testSwitch.c
Test a switch input and light a LED if pressed
testLed.c Light 4 LED's using an incrementing binary number patern
testTemp.c
Read the temperature and display it
carLog1.c
Basic car data logging program

Interrupts and Threads

A simple 'C' program simply runs through its code line statement at a time until it is finished. Sometimes we need the program to interrupt what its doing and do something else for a while before returning to its normal work. An interrupy allows this. Interrupts are normaly generated by an external event such as a key press. It is possible for the programer to define a function that is called when this event happens and return back to the program when finished. You need to be careful of the data that the interrupt code modifies as it can currupt the data being used by the main program. Often interrupts need to be disabled for critical sections of code to prevent this.
Threads allow two or more sets of code to run simultaneously. This is being used more and more with multiple core processors. As with interrupts you have to be very careful with any data accessed by more than one of the threads.

Lots More

This is just the very basics. There is a lot more to programming and to the language 'C' itself.

There are now quite a few computer languages used. Quite a few of them have been derived from 'C' or have quite a few things in common. 'C' has been developed into 'C++' which adds a number of features for object based programing and other programming paradimes.