영어고전을 pdf 파일로 받아볼 수 있는 곳 : http://www.planetebook.com/



GTK+ 프로그래밍 기초 자료2

1257069526_lf-2004_03-0332.pdf

GTK+ 프로그래밍 기초 자료

1257069392_gtk.pdf

2009.10.25 카라( Kara ) 용산 CGV 공연 실황



[출처] http://aima.cs.berkeley.edu/python/readme.html

AIMA Python Code

This file gives an overview of the Python code for the algorithms in the textbook AI: A Modern Approach. The code is Copyright (c) 2002 by Peter Norvig and is offered free of charge for your use. As you may know, the textbook presents algorithms in pseudo-code format; as a supplement we provide this Python code as well as Lisp code. The intent is to implement all the algorithms in both languages, so that you can choose whichever language you prefer. As yet neither implementation is complete, but the Lisp version is closer.

Installation Instructions

Here is how to download the files and make them ready for use. You only need to do this once, and if you are taking a course, your instructor may have set this up for you.
  1. Create a directory where you want the code to reside on your local machine. You can call this whatever you want; we'll call it home.
  2. Get the data.zip, store it in home file and unzip it. Your browser may unzip automatically, or you can give the command "unzip aima-python.zip" or drag the file to your zip program icon. In the end, just make sure you have files in the directory home/data.
  3. Download the file aima-python.zip into home.
  4. Unzip it, creating files in home/python.
  5. You must have Python (version 2.2 or later) installed. Python comes preinstalled on most versions of Linux and Mac OS. Versions are also available for Windows, Solaris, and other operating systems. If your system does not have Python installed, you can download and install it.
  6. Make sure that home/python is in your module search path. You do this either by always starting Python from the directory where you keep the files, or by editing the environment variable PYTHONPATH.
  7. Test the code. There are unit tests interspersed in the code. They follow the Python doctest conventions and can be run with the command line "python doctests.py -v *.py". The "-v" is optional; it means "verbose". Various output is printed, but if all goes well there should be no instances of the word "Failure", nor of a long line of "*****". If you do use the "-v" option, the last line printed should be "Test passed."

User's Guide

Once you have the files installed, you can use them in several ways.
  • Read the code. This can enhance your understanding of the algorithms, and clarify parts that were not spelled out in the book's pseudo-code.
  • Run the existing code on your own data. For the module(s) you want, do "import module" and then run the functions you want on the data you want.
  • Experiment with extending the code.

Code File Summary

You can
  • Browse through the python/ directory to see all the files.
  • Look at the .txt files to see some unit tests (doctests) and their expected output.
  • See the code repository index to see what functions and data types are available, and how they map to the pseudocode figures in the book.
The following table lists the code files (modules), the chapters in the book to which they refer, the number of lines of code in each file, and a brief description of each file. Each module name links to a pretty, colorized version of the Python source code, and the Files column lists the original .py file and (in some cases) a .txt file of doctests.

Chapter Module Files Lines Description
1-2 agents .py 532 Implement Agents and Environments (Chapters 1-2).
3-4 search .py .txt 735 Search (Chapters 3-4)
5 csp .py .txt 449 CSP (Constraint Satisfaction Problems) problems and solvers. (Chapter 5).
6 games .py 285 Games, or Adversarial Search. (Chapters 6)
7-10 logic .py .txt 887 Representations and Inference for Logic (Chapters 7-10)
11-12 planning .py 6 Planning (Chapters 11-12)
13-15 probability .py .txt 170 Probability models. (Chapter 13-15)
17 mdp .py .txt 141 Markov Decision Processes (Chapter 17)
18-20 learning .py 585 Learn to estimate functions from examples. (Chapters 18-20)
21 rl .py 14 Reinforcement Learning (Chapter 21)
22 nlp .py .txt 169 A chart parser and some grammars. (Chapter 22)
23 text .py .txt 364 Statistical Language Processing tools. (Chapter 23)
doctests .py .txt 42 Run all doctests from modules on the command line. For each
py2html .py 109 Pretty-print Python code to colorized, hyperlinked html.
utils .py .txt 713 Provide some widely useful utilities. Safe for "from utils import *".
5201

Developer's Guide

If you'd like to contribute to this project, we could really use the help. Read the guidelines and then let me know what you'd like to contribute.

Acknowledgements

Many thanks for the bug reports, corrected code, and other support from Phil Ruggera, Peng Shao, Amit Patil, Ted Nienstedt, Jim Martin, Ben Catanzariti, and others.
[출처] http://www.jetcafe.org/jim/c-style.html
$Id: c-style.html,v 1.3 1996/12/31 18:24:36 larson Exp $
Back to the home page.

Standards and Style for Coding in ANSI C

Overview

This d0cument describes the coding standards we'd like to have for all of our C code. It has rules for both formatting and content, together with occasional rationale (or rationalization) for those rules. Although you may disagree with many of the decisions made here, please try to swallow your indignation and conform to these standards. It is very important that everyone can read and understand the software, so uniformity is a goal. Also, some of the style suggestions will help you avoid the pitfalls of the C language.

There are many rules and suggestions here. Too many, it seems, to satisfy while still getting your code to actually work. This is intentional - it is better to work under too many constraints than too few. Your code will look better if you have spent your time deciding on which stylistic rule to relax than if you have been making choices in a vacuum.

The coding style espoused here is strict and traditional. Some of the requirements (especially 8-space tabs and non-nested include files) will cause grief for many programs, but they will not be a problem for most well-written programs. This style makes poorly-written programs blatantly ugly. It will occasionally inconvenience well-written code, but that is a tradeoff we accept in order to encourage good style in general.

Lastly, like rules of etiquette, these guidelines are not an end in themselves, but rather they attempt to move you to be mindful of your actions, for they are not private - they affect others (future readers and maintainers), and ultimately you are responsible to a higher authority (ISO WG14).

This d0cument is stolen from the work of Mike Haertel, Richard O'Keefe, and Rob Pike.

ANSI Standard C

The C dialect we will be using is ANSI standard C, or C89. If you are not familiar with this dialect, buy the second edition of Kernighan and Ritchie's The C Programming Language and Harbison and Steele's C: A Reference Manual. Both of these books are required reading for any C programmer.

The major improvements to the C language made in this standard are:

  • The types of function arguments are now specified in function declarations.
  • Several new types, such as void's and enum's have been added.
  • Structures can be passed as arguments and returned from functions.
  • A rich library has been mandated and standardized.
Please try to stay within ANSI standard C as much as possible. If you need to write system-dependent code, try to modularize and isolate it as much as possible.

Fighting With C

Many of the characteristics of the C language are controversial, or even outright mistakes. Some of these are worth fighting, some are not worth fighting, and some are arguably good decision.

The following are mistakes of C which we advocate fighting.

What follows are some controversial aspects of C which are nonetheless integral to the language and can't be fought.

The syntax for type declarations can get kind of beastly, but it's okay if you just remember that declaration follows use, as in:

int (*apfi[])();

C is a language with pointers; don't go into denial over this. The fact that a[i] is equivalent to *(a + i) is one of the defining characteristics of C, and should be embraced.

Some people recommend creating abstract data types of the form:

typedef struct T *T;
Then values of the abstract type can be declared as:
T t;
making t look like an object in its own right. However this obscures the fact that t is a reference to an object, rather than an object itself. This also prevents passing t by value rather than by reference.

Lastly, C is an imperative language. Although some compilers implement tail recursion, loops should be written as iterative loops. Functional language programming techniques which madly allocate memory will not work will with current C technology.

Comments

Comments can add immensely to the readability of a program, but used heavily or poorly placed they can render good code completely incomprehensible. It is far better to err on the side of too few comments rather than too many - at least then people can find the code! Also, if your code needs a comment to be understood, then you should look for ways to rewrite the code to be clearer. And comments that aren't there won't get out of date. (An inaccurate or misleading comment hurts more than a good comment helps! Be sure that your comments stay right.)

That being said, good places to put comments are:

  • a broad overview at the beginning of a module
  • data structure definitions
  • global variable definition
  • at the beginning of a function
  • tricky steps within a function
If you do something weird, a comment to explain why can save future generations from wondering what drug you were on and where to get it. If you do something clever, brag about it. Not only will this inflate your ego, but it will also subtly tip off others as to where to look first for bugs. Finally, avoid fancy layout or decoration.
/* single line comments look like this *//* * Important single line comments look like multi-line comments. *//* * Multiline comments look like this.  Put the opening and closing * comment sequences on lines by themselves.  Use complete sentences * with proper English grammar, capitalization, and punctuation. *//* but you don't need to punctuate or capitalize one-liners */
The opening / of all comments should be indented to the same level as the code to which it applies, for example:
if (fubar()) {	/*	 * Fouled up beyond all recognition.  Print a nastygram	 * and attempt to clean up.  If that doesn't work,	 * die horribly, and try to crash the system while	 * we're at it.	 */	...}
If you put a comment on the same line as code, set it off from the code with a few tabs. Don't continue such a comment across multiple lines. For example:
printf("hi\n");		/* hello revisited */
In fact, try to avoid such comments altogether - if it`s not important enough to warrant a complete sentence, does it really need to be said?

The size of the comment should be proportional to the size of the code that it refers to. Consequently, properties of code that can fit within a single 24-line screen should not be commented unless they are not obvious. By contrast, even obvious global properties and invariants may need to be made explicit. This doesn't have to be through comments, though. The assert() macro is an excellent ``executable comment''.

Source File Organization

Use the following organization for source files:
includes of system headers
includes of local headers
type and constant definitions
global variables
functions
A reasonable variation might be to have several repetitions of the last three sections.

Within each section, order your functions in a ``bottom up'' manner - defining functions before their use. The benefit of avoiding redundant (hence error-prone) forward declarations outweighs the minor irritation of having to jump to the bottom of the file to find the main functions.

In header files, use the following organization:

type and constant definitions
external object declarations
external function declarations
Again, several repetitions of the above sequence might be reasonable. Every object and function declaration must be preceded by the keyword extern. (See below for why.)

Now, for a very important rule: Avoid having nested includes, ever. I mean it. If you've ever tried to track a bug through the SunOS /usr/include maze, you'll understand why. Consider using the makedepend tools to help maintain your source file dependencies in your Makefile.

Declarations and Types

Avoid exporting names outside of individual C source files; i.e., declare as static every function and global variable that you possibly can. (I consider it a design flaw that C doesn't do this by default.)

When declaring a global function or variable in a header file, use an explicit extern. For functions, provide a full ANSI C prototype. For example:

extern int errno;extern void free(void *);
Do not use parameter names in function prototypes - you are increasing the risk of a name collision with a previously-defined macro, e.g.:
#define fileptr stdin...extern int foo(FILE *fileptr);
Instead, d0cument parameter names only as necessary using comments:
extern void veccopy(double * /*dst*/, double * /*src*/, size_t);

Why the extern? It is OK to declare an object any number of times, but in all the source files there can be only one definition. The extern says ``This is only a declaration.'' (A definition is something that actually allocates and initializes storage for the object.) Historically,

int foo;
was ambiguously treated as either a declaration or both declaration and definition depending on linker magic. However, ANSI C allows it to be an error for this to appear at file scope in more than one place in a program. Header files should never contain object definitions, only type definitions and object declarations. This is why we require extern to appear everywhere except on the real definition.

In function prototypes, try not to use const. Although the ANSI standard makes some unavoidable requirements in the standard library, we don't need to widen the problem any further. What we are trying to avoid here is a phenomenon known as ``const poisoning'', where the appearance of const in some prototype forces you to go through your code and add const all over the place.

Don't rely on C's implicit int typing; i.e., don't say:

extern foo;
say:
extern int foo;
This is poor style and should be completely avoided (and might go away in C9X!). Similarly, don't declare a function with implicit return type. If it returns a meaningful integer value, declare it int. If it returns no meaningful value, declare it void. (By the way, the C standard requires you to declare main() as returning int.)

Provide typedefs for all struct and union types, and put them before the type declarations. Creating the typedef eliminates the clutter of extra struct and union keywords, and makes your structures look like first-class types in the language. Putting the typedefs before the type declarations allows them to be used when declaring circular types. It is also nice to have a list of all new reserved words up front.

typedef struct Foo Foo;typedef struct Bar Bar;struct Foo {	Bar *bar;};struct Bar {	Foo *foo;};

This give a particularly nice scheme of exporting opaque objects in header files.

In header.h:

typedef struct Foo Foo;
In source.c:
#include "header.h"struct Foo { .. };
Then a client of header.h can declare a
Foo *x;
but cannot get at the contents of a Foo. In addition, the user cannot declare a plain (non pointer) Foo, and so is forced to go through whatever allocation routines you provide. We strongly encourage this modularity technique.

If an enum is intended to be declared by the user (as opposed to just being used as names for integer values), give it a typedef too. Note that the typedef has to come after the enum declaration.

Don't mix any declarations in with type definitions; i.e., don't say:

struct foo {	int x;} object;
Also don't say:
typedef struct {	int x;} type;
(It's important for all typedefs to stand out by themselves.)

Declare each field of a structure on a line by itself. Think about the order of the fields. Try to keep related fields grouped. Within groups of related fields, pick some uniform scheme for organizing them, for example alphabetically or by frequency of use. When all other considerations are equal, place larger fields first, as C's alignment rules may then permit the compiler to save space by not introducing "holes" in the structure layout.

Use of the Preprocessor

For constants, consider using:
enum { Red = 0xF00, Blue = 0x0F0, Green = 0x00F };static const float pi = 3.14159265358;
instead of #defines, which are rarely visible in debuggers.

Macros should avoid side effects. If possible, mention each argument exactly once. Fully parenthesize all arguments. When the macro is an expression, parenthesize the whole macro body. If the macro is the inline expansion of some function, the name of the macro should be the same as that of the function, except fully capitalized. When continuing a macro across multiple lines with backslashes, line up the backslashes way over on the right edge of the screen to keep them from cluttering up the code.

#define OBNOXIOUS(X)					\	(save = (X),					\	 dosomethingwith(X),				\	 (X) = save)
Try to write macros so that they are syntactically expressions. C's comma and conditional operators are particularly valuable for this. If you absolutely cannot write the macro as an expression, enclose the macro body in do { ... } while (0). This way the expanded macro plus a trailing semicolon becomes a syntactic statement.

If you think you need to use #ifdef, consider restricting the dependent code to a single module. For instance, if you need to have different code for Unix and MS_DOS, instead of having #ifdef unix and #ifdef dos everywhere, try to have files unix.c and dos.c with identical interfaces. If you can't avoid them, make sure to d0cument the end of the conditional code:

#ifdef FUBAR	some code#else	other code#endif /* FUBAR */
Some sanctioned uses of the preprocessor are:
  • Commenting out code: Use #if 0.
  • Using GNU C extensions: Surround with #ifdef __GNUC__.
  • Testing numerical limits: Feel free to conditionalize on the constants in the standard headers <float.h> and <limits.h>.
If you use an #if to test whether some condition holds that you know how to handle, but are too lazy to provide code for the alternative, protect it with #error, like this:
#include <limits.h>#if INT_MAX > UCHAR_MAXenum { Foo = UCHAR_MAX + 1, Bar, Baz, Barf };#else#error "need int wider than char"#endif
(This example also illustrates a reasonable use of <limits.h>.)

Naming Conventions

Names should be meaningful in the application domain, not the implementation domain. This makes your code clearer to a reader who is familiar with the problem you're trying to solve, but is not familiar with your particular way of solving it. Also, you may want the implementation to change some day. Note that well-structured code is layered internally, so your implementation domain is also the application domain for lower levels.

Names should be chosen to make sense when your program is read. Thus, all names should be parts of speech which will make sense when used with the language's syntactic keywords. Variables should be noun clauses. Boolean variables should be named for the meaning of their "true" value. Procedures (functions called for their side-effects) should be named for what they do, not how they do it. Function names should reflect what they return, and boolean-valued functions of an object should be named for the property their true value implies about the object. Functions are used in expressions, often in things like if's, so they need to read appropriately. For instance,

if (checksize(s))
is unhelpful because we can't deduce whether checksize returns true on error or non-error; instead
if (validsize(s))
makes the point clear and makes a future mistake in using the routine less likely.

Longer names contain more information than short names, but extract a price in readability. Compare the following examples:

for (elementindex = 0; elementindex < DIMENSION; ++elementindex)	printf("%d\n", element[elementindex]);for (i = 0; i < DIMENSION; ++i)	printf("%d\n", element[i]);
In the first example, you have to read more text before you can recognize the for-loop idiom, and then you have to do still more hard work to parse the loop body. Since clarity is our goal, a name should contain only the information that it has to.

Carrying information in a name is unnecessary if the declaration and use of that name is constrained within a small scope. Local variables are usually being used to hold intermediate values or control information for some computation, and as such have little importance in themselves. For example, for array indices names like i, j, and k are not just acceptable, they are desirable.

Similarly, a global variable named x would be just as inappropriate as a local variable named elementindex. By definition, a global variable is used in more than one function or module (otherwise it would be static or local), so all of it's uses will not be visible at once. The name has to explain the use of the variable on its own. Nevertheless there is still a readability penalty for long names: casefold is better than case_fold_flag_set_by_main.

In short, follow "Mike's Rule" to make variable name size proportional to scope:

	length(name(variable)) ~ log(countlines(scope(variable)))

Use some consistent scheme for naming related variables. If the top of memory is called physlim, should the bottom be membase? Consider the suffix -max to denote an inclusive limit, and -lim to denote an exclusive limit.

Don't take this too far, though. Avoid ``Hungarian''-style naming conventions which encode type information in variable names. They may be systematic, but they'll screw you if you ever need to change the type of a variable. If the variable has a small scope, the type will be visible in the declaration, so the annotation is useless clutter. If the variable has a large scope, the code should modular against a change in the variable's type. In general, I think any deterministic algorithm for producing variable names will have the same effect.

Nevertheless, if the type name is a good application-domain description of the variable, then use it, or a suitable abbreviation. For instance, when implementing an ADT I would write:

/* * Execute registered callback and close socket. */voidchan_close(Chan *chan)	/* No better name for parameter than "chan" */{	(*chan->deactivate)(chan->arg);	(void) close(chan->fd);}
but when using the ADT I would write:
/* * Log a message when the watched-for event happens. */struct Monitor {	int (*trigger)(void *region);	void *region;	char *message;	Chan *log;		/* describes how Chan is used */};

There are weaknesses in C for large-scale programming - there is only a single, flat name scope level greater than the module level. Therefore, libraries whose implementations have more than one module can't guard their inter-module linkage from conflicting with any other global identifiers. The best solution to this problem is to give each library a short prefix that it prepends to all global identifiers.

Abbreviations or acronyms can shorten things up, but may not offer compelling savings over short full words. When a name has to consist of several words (and it often doesn't), separate words by underscores, not by BiCapitalization. It will look better to English-readers (the underscore is the space-which-is-not-a-space). Capitalization is reserved for distinguishing syntactic namespaces.

C has a variety of separately maintained namespaces, and distinguishing the names by capitalization improves the odds of C's namespaces and scoping protecting you from collisions while allowing you to use the same word across different spaces. C provides separate namespaces for:

Preprocessor Symbols
Since macros can be dangerous, follow tradition fully capitalize them, otherwise following the conventions for function or variable names.
	#define NUSERTASKS 8	#define ISNORMAL(S) ((S)->state == Normal)	
Any fully capitalized names can be regarded as fair game for #ifdef, although perhaps not for #if.
Labels
Limited to function scope, so give it a short name, lowercase. Give meaningful name such that the corresponding goto statement can be read aloud, and name it for why you go there, not what you do when you get there. For instance,
	goto bounds_error;	
is more helpful than
	goto restore_pointer;	
Structure, Union, or Enumeration Tags
Having these as separate namespaces creates an artificial distinction between structure, union, and enumeration types and ordinary scalar types. i.e. you can't simplify a struct type to a scalar type by replacing
	struct Foo { long bar; };	
with
	typedef long Foo;	
since you still have the "struct" keyword everywhere, even when the contents are not being examined. The useless "struct" keywords also clutter up the code. Therefore we advocate creating a typedef mirror of all struct tags:
	typedef struct Foo Foo;	
Capitalize the tag name to match the typedef name.
Structure or Union Members
Each structure or union has a separate name space for its members, so there is no need to add a distinguishing prefix. When used in expressions they will follow a variable name, so make them lowercase to make the code look nice. If the type of a member is an ADT, the name of the type is often a good choice for the name of the variable (but in lowercase). You do not prefix the member names, as in:
		struct timeval { unsigned long tv_sec; long tv_usec; };	
for they are already in a unique namespace.
Ordinary Identifiers
all other ordinary identifiers (declared in ordinary declarators, or as enumerations constants).
Typedef Names
Capitalized, with no _t suffix or other cutesy thing to say ``I'm a type'' - we can see that from it's position in the declaration! (Besides, all names ending with _t are reserved by Posix.) The capitalization is needed to distinguish type names from variable names - often both want to use the same application-level word.
Enumeration Constants
Capitalize. If absolutely necessary, consider a prefix.
		enum Fruit { Apples, Oranges, Kumquats };		
Function Names
Lowercase. If they are static (and most should be), make the name short and sweet. If they are externally-visibly, try to give then a prefix unique to the module or library.
Function Parameters
Since they will be used as variables in the function body, use the conventions for variables.
Variables
Lowercase.

Lastly, develop some standard idioms to make names automatic. For instance:

int i, j, k;	/* generic indices */char *s, *t;	/* string pointers */char *buf;	/* character array */double x, y, z;	/* generic floating-point */size_t n, m, size;	/* results of sizeof or arguments to malloc */Foo foo, *pfoo, **ppfoo;	/* sometimes a little hint helps */

Indentation and Layout

Try to stay inside the mythical 79 column limit. If you can't, look for a tasteful place to break the line (there are some ideas below). Avoid ideas that would lead to indenting that doesn't align on a tab stop. If worst comes to worst, grit your teeth and tolerate the long line.

Use real tab characters for indenting. Tabs are always 8 spaces. This policy has the following advantages:

  • It doesn't require a fancy editor; not everyone uses emacs.
  • It is easy to write miscellaneous program text processing tools that count leading tabs.
  • It encourages you to break deeply nested code into functions.
If you use short names and write simple code, your horizontal space goes a long way even with tab indenting.

Use the One True Brace Style (1TBS) as seen in K&R. The following quotation from Henry Spencer's Ten Commandments for C Programmers says it better than I can:

Thou shalt make thy program's purpose and structure clear to thy fellow man by using the One True Brace Style, even if thou likest it not, for thy creativity is better used in solving problems than in creating beautiful new impediments to understanding.

- The Eighth Commandment

The rationale behind this brace style, straight from the horse's (Dennis') mouth, is that the braces are just line noise to make the compiler happy, and so don't deserve to be specially set apart. (The GNU style is a particularly bad offender in this regard!) Also, the 1TBS conserves vertical space, which is important for those of us working on 24 line displays. (It also helps avoid excessive eye movement on big displays.)

Purists point out that 1TBS is inconsistent since it has one style for statements and another for functions. That's okay since functions are special anyway (you can't nest them). It's also good to know that with most editors you can get to the top of the current function by searching backward for the regexp ^{.

Avoid unnecessary curly braces, but if one branch of an if is braced, then the other should be too, even if it is only a single line. If an inner nested block is braced, then the outer blocks should be too.

Some examples:

if (foo == 7) {	bar();} else if (foo == 9) {	barf();	bletch();} else {	boondoggle();	frobnicate();}do {	for (i = 0; i < n; ++i)		a[i] = 0;	plugh();	xyzzy();} while (!blurf());

In switch statements, be sure every case ends with either a break, continue, return, or /* fall through */ comment. Especially don't forget to put a break on the last case of a switch statement. If you do, I promise someone will forget to add one someday when adding new cases.

switch (phase) {case New:	printf("don't do any coding tonight\n");	break;case Full:	printf("beware lycanthropes\n");	break;case Waxing:case Waning:	printf("the heavens are neutral\n");	break;default:	/*	 * Include occasional sanity checks in your code.	 */	fprintf(stderr, "and here you thought this couldn't happen!\n");	abort();}
This last example also illustrates how to handle labels, including case labels and goto labels: put each label on a line by itself, and outdent it by a tab stop. However, if outdenting a label would take it all the way out to the left edge of the screen, insert a leading space.

Use goto sparingly. Two harmless places to use it are to break out of a multilevel loop, or to jump to common function exit code. (Often these are the same places.)

Lay out your functions like this:

/* * Optional comment describing the function. */typename(args){	declarations	code}
It is important that the name of the function be in the first column of text with no indentation. Some text processing utilities (e.g. etags) rely on this to find function definitions. Even if you don't use such tools, it's extremely helpful to know that the regular expression ^name matches the single definition of the function.

Note that we will not be using old-style function definitions where the args are declared outside the parameter list. Include a blank line between the local variable declarations and the code. Also feel free to include other blank lines, particularly to separate major blocks of code.

Multiple declarations can go on one line, but if the line gets too long don't try to continue it in some fancy way, just start a new declaration on the next line. Avoid declarations in all but the most complex inner blocks. Avoid initializations of automatic variable in declarations, since they can be mildly disconcerting when stepping through code with a debugger. Don't declare external objects inside functions, declare them at file scope. Finally, don't try to go into denial over C's ``declaration by example'' syntax. Say:

char *p;
not:
char* p;
In the long run, such fights with the language will only cause you grief. (One of the reason's Stroustrup's original C++ book was practically unreadable was because he was constantly fighting with C.)

Use spaces around keywords. Use spaces around binary operators, except . and ->, for they are morally equivalent to array subscripts, and the ``punctuation'' operator ','. Don't use spaces around unary operators, except sizeof and casts. Example:

x = -y + z + sizeof (Foo) + bar();
Note that function call is a unary operator, so don't use a space between a function name and the opening parenthesis of the arguments. The reason for making an exception for sizeof is that it is a syntactic keyword, not a function. These rules lead to:
if (something)
for syntactic keywords, and
foo(something)
for functions. Don't parenthesize things unnecessarily; say
return 7;
not
return (7);
and especially not
return(7);
Remember, return is the exact antonym of function call! The parsing precedence of the bitwise operations (&, |, ^, ~) can be surprising. See Ritchie's explanation for the reasons why. Always use full parentheses around these operators.

Some C style guides take this a bit too far, though. One author went as far as to suggest that C programmers should rely on * and / bind more tightly than + and -, and parenthesize the rest. This is a good way to write Lisp code, but it makes C look ugly. A C programmer should be able to recognize its idioms and be able to parse code like:

while (*s++ = *t++)	;

If an expression gets too long to fit in a line, break it next to a binary operator. Put the operator at the beginning of the next line to emphasize that it is continued from the previous line. Don't add additional indenting to the continued line. This strategy leads to particularly nice results when breaking up complicated conditional expressions:

if (x == 2 || x == 3 || x == 5 || x == 7|| x == 11 || x == 13 || x == 17 || x == 19)	printf("x is a small prime\n");
This example also illustrates why you shouldn't add additional indenting when continuing a line - in this case, it could get confused with the condition body. Avoid breakpoints that will give the reader false notions about operator precedence, like this:
if (x == 2 || x > 10&& x < 12 || x == 19)
If you're breaking an expression across more than two lines, try to use the same kind of breakpoint for each line. Finally, if you're getting into really long expressions, your code is probably in need of a rewrite.

Avoid sloppiness. Decide what your style is and follow it precisely. I often see code like this:

struct foo {	int baz ;	int  barf;	char * x, *y;};
All those random extra spaces make me wonder if the programmer was even paying attention!

The indent utility can automatically check most of these indentation conventions. The style given here corresponds to the indent options

-bap -bad -nbc -bs -ci0 -di1 -i8
which can be specified in a file named indent.pro in your home directory. Note that indent tends to mess up typedef-defined identifiers unless they are explicitly given on the command line.

Expressions and Statements

In C, assignments are expressions, not statements. This allows multiple assignment
a = b = c = 1;
and assignment within expressions
if (!(bp = malloc(sizeof (Buffer)))) {	perror("malloc");	abort();}
This capability can sometimes allow concise code, but at other times it can obscure important procedure calls and updates to variables. Use good judgement.

The C language lacks a true boolean type, therefore its logic operations (! == > < >= <=) and tests (in the conditional operator ?: and the if, while, do, and for statements) have some interesting semantics. Every boolean test is an implicit comparison against zero (0). However, zero is not a simple concept. It represents:

  • the integer zero for all integral types
  • the floating point 0.0 (positive or negative)
  • the nul character
  • the null pointer
In order to make your intentions clear, explicitly show the comparison with zero for all scalars, floating-point numbers, and characters. This gives us the tests
(i == 0)	(x != 0.0)	(c == '\0')
instead of
(i)		(!x)		(c)
An exception is made for pointers, since 0 is the only language-level representation for the null pointer. (The symbol NULL is not part of the core language - you have to include a special header file to get it defined.) In short, pretend that C has an actual boolean type which is returned by the logical operators and expected by the test constructs, and pretend that the null pointer is a synonym for false.

Write infinite loops as:

for (;;)	...
not
while (1)	...
The former is idiomatic among C programmers, and is more visually distinctive.

Feel free to use a for loop where some of the parts are empty. The purpose of for is to centralize all loop control code in one place. If you're thinking ``for each of these things, we have to do something,'' use a for loop. If a for statement gets too long to fit in a line, turn it into a while. If your loop control is that complicated, it probably isn't what for is for (pun intended).

Never return from the function main(), explicitly use exit(). They are no longer equivalent - there is an important distinction when using the atexit() feature with objects declared locally to main(). Don't worry about the details, just use this fact to program consistently. This does spoil the potential for calling main() recursively, which is usually a silly thing to do.

Functions

Functions should be short and sweet. If a function won't fit on a single screen, it's probably too long. Don't be afraid to break functions down into smaller helper functions. If they are static to the module an optimizing compiler can inline them again, if necessary. Helper functions can also be reused by other functions.

However, sometimes it is hard to break things down. Since functions don't nest, variables have to be communicated through function arguments or global variables. Don't create huge interfaces to enable a decomposition that is just not meant to be.

Complexity and Performance

There is a temptation to use all sorts of clever techniques to optimize the code. However, this optimization comes at a penalty. Rob Pike says it better than me:
Rule 1
You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is.
Rule 2
Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.
Rule 3
Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. (Even if n does get big, use Rule 2 first.)
Rule 4
Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures.
Rule 5
Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
Rule 6
There is no Rule 6.

The Standard Library

The standard library is your friend. There's no excuse for writing code which already exists there. Not only will the standard library's code be tested, often it will be more efficient, and will certainly be more familiar to your fellow programmers. The best book on the subject is Plaugher's The Standard C Library. Some notes on using particular functions:
gets
Never use this. Use fgets instead so that you can be sure that you don't overflow your buffer.
malloc
Don't cast the return value of calls to malloc, It has type void *, so it will be compatible with anything. K&R2, p. 142 gives contrary advice, but it has since been retracted by Dennis Ritchie:
In any case, now that I reread the stuff on p. 142, I think it's wrong; it's written in such a way that it's not just defensive against earlier rules, it misrepresents the ANSI rules.
(From the newsgroup comp.std.c on August 15, 1995.)

Further Reading

There is a wonderful Web page on Programming in C which features such goodies as Rob Pike's Notes on Programming in C, Henry Spencer's The Ten Commandments for C Programmers, and the ANSI C Rationale. These are all required reading.
Back to the home page.
Send comments to Jim Larson.

한글필기체 폰트 입니다.

한글 옛날버전이 다시금 생각나서..

1254631719_pilgi.zip



[출처] http://ccnga.uwaterloo.ca/~jscouria/GSM/gsmreport.html

Overview of the Global System for Mobile Communications

John Scourias
jscouria@www.shoshin.uwaterloo.ca


Table of Contents

1. History of GSM
2. Services provided by GSM
3. Architecture of the GSM network

4. Radio link aspects

5. Network aspects

6. Conclusion and comments


History of GSM

During the early 1980s, analog cellular telephone systems were experiencing rapid growth in Europe, particularly in Scandinavia and the United Kingdom, but also in France and Germany. Each country developed its own system, which was incompatible with everyone else's in equipment and operation. This was an undesirable situation, because not only was the mobile equipment limited to operation within national boundaries, which in a unified Europe were increasingly unimportant, but there was also a very limited market for each type of equipment, so economies of scale and the subsequent savings could not be realized.

The Europeans realized this early on, and in 1982 the Conference of European Posts and Telegraphs (CEPT) formed a study group called the Groupe Spécial Mobile (GSM) to study and develop a pan-European public land mobile system. The proposed system had to meet certain criteria:

  • Good subjective speech quality
  • Low terminal and service cost
  • Support for international roaming
  • Ability to support handheld terminals
  • Support for range of new services and facilities
  • Spectral efficiency
  • ISDN compatibility
In 1989, GSM responsibility was transferred to the European Telecommunication Standards Institute (ETSI), and phase I of the GSM specifications were published in 1990. Commercial service was started in mid-1991, and by 1993 there were 36 GSM networks in 22 countries [6]. Although standardized in Europe, GSM is not only a European standard. Over 200 GSM networks (including DCS1800 and PCS1900) are operational in 110 countries around the world. In the beginning of 1994, there were 1.3 million subscribers worldwide [18], which had grown to more than 55 million by October 1997. With North America making a delayed entry into the GSM field with a derivative of GSM called PCS1900, GSM systems exist on every continent, and the acronym GSM now aptly stands for Global System for Mobile communications.

The developers of GSM chose an unproven (at the time) digital system, as opposed to the then-standard analog cellular systems like AMPS in the United States and TACS in the United Kingdom. They had faith that advancements in compression algorithms and digital signal processors would allow the fulfillment of the original criteria and the continual improvement of the system in terms of quality and cost. The over 8000 pages of GSM recommendations try to allow flexibility and competitive innovation among suppliers, but provide enough standardization to guarantee proper interworking between the components of the system. This is done by providing functional and interface descriptions for each of the functional entities defined in the system.

Services provided by GSM

From the beginning, the planners of GSM wanted ISDN compatibility in terms of the services offered and the control signalling used. However, radio transmission limitations, in terms of bandwidth and cost, do not allow the standard ISDN B-channel bit rate of 64 kbps to be practically achieved.

Using the ITU-T definitions, telecommunication services can be divided into bearer services, teleservices, and supplementary services. The most basic teleservice supported by GSM is telephony. As with all other communications, speech is digitally encoded and transmitted through the GSM network as a digital stream. There is also an emergency service, where the nearest emergency-service provider is notified by dialing three digits (similar to 911).

A variety of data services is offered. GSM users can send and receive data, at rates up to 9600 bps, to users on POTS (Plain Old Telephone Service), ISDN, Packet Switched Public Data Networks, and Circuit Switched Public Data Networks using a variety of access methods and protocols, such as X.25 or X.32. Since GSM is a digital network, a modem is not required between the user and GSM network, although an audio modem is required inside the GSM network to interwork with POTS.

Other data services include Group 3 facsimile, as described in ITU-T recommendation T.30, which is supported by use of an appropriate fax adaptor. A unique feature of GSM, not found in older analog systems, is the Short Message Service (SMS). SMS is a bidirectional service for short alphanumeric (up to 160 bytes) messages. Messages are transported in a store-and-forward fashion. For point-to-point SMS, a message can be sent to another subscriber to the service, and an acknowledgement of receipt is provided to the sender. SMS can also be used in a cell-broadcast mode, for sending messages such as traffic updates or news updates. Messages can also be stored in the SIM card for later retrieval [2].

Supplementary services are provided on top of teleservices or bearer services. In the current (Phase I) specifications, they include several forms of call forward (such as call forwarding when the mobile subscriber is unreachable by the network), and call barring of outgoing or incoming calls, for example when roaming in another country. Many additional supplementary services will be provided in the Phase 2 specifications, such as caller identification, call waiting, multi-party conversations.

Architecture of the GSM network

A GSM network is composed of several functional entities, whose functions and interfaces are specified. Figure 1 shows the layout of a generic GSM network. The GSM network can be divided into three broad parts. The Mobile Station is carried by the subscriber. The Base Station Subsystem controls the radio link with the Mobile Station. The Network Subsystem, the main part of which is the Mobile services Switching Center (MSC), performs the switching of calls between the mobile users, and between mobile and fixed network users. The MSC also handles the mobility management operations. Not shown is the Operations and Maintenance Center, which oversees the proper operation and setup of the network. The Mobile Station and the Base Station Subsystem communicate across the Um interface, also known as the air interface or radio link. The Base Station Subsystem communicates with the Mobile services Switching Center across the A interface.

Figure 1. General architecture of a GSM network

Mobile Station

The mobile station (MS) consists of the mobile equipment (the terminal) and a smart card called the Subscriber Identity Module (SIM). The SIM provides personal mobility, so that the user can have access to subscribed services irrespective of a specific terminal. By inserting the SIM card into another GSM terminal, the user is able to receive calls at that terminal, make calls from that terminal, and receive other subscribed services.

The mobile equipment is uniquely identified by the International Mobile Equipment Identity (IMEI). The SIM card contains the International Mobile Subscriber Identity (IMSI) used to identify the subscriber to the system, a secret key for authentication, and other information. The IMEI and the IMSI are independent, thereby allowing personal mobility. The SIM card may be protected against unauthorized use by a password or personal identity number.

Base Station Subsystem

The Base Station Subsystem is composed of two parts, the Base Transceiver Station (BTS) and the Base Station Controller (BSC). These communicate across the standardized Abis interface, allowing (as in the rest of the system) operation between components made by different suppliers.

The Base Transceiver Station houses the radio tranceivers that define a cell and handles the radio-link protocols with the Mobile Station. In a large urban area, there will potentially be a large number of BTSs deployed, thus the requirements for a BTS are ruggedness, reliability, portability, and minimum cost.

The Base Station Controller manages the radio resources for one or more BTSs. It handles radio-channel setup, frequency hopping, and handovers, as described below. The BSC is the connection between the mobile station and the Mobile service Switching Center (MSC).

Network Subsystem

The central component of the Network Subsystem is the Mobile services Switching Center (MSC). It acts like a normal switching node of the PSTN or ISDN, and additionally provides all the functionality needed to handle a mobile subscriber, such as registration, authentication, location updating, handovers, and call routing to a roaming subscriber. These services are provided in conjuction with several functional entities, which together form the Network Subsystem. The MSC provides the connection to the fixed networks (such as the PSTN or ISDN). Signalling between functional entities in the Network Subsystem uses Signalling System Number 7 (SS7), used for trunk signalling in ISDN and widely used in current public networks.

The Home Location Register (HLR) and Visitor Location Register (VLR), together with the MSC, provide the call-routing and roaming capabilities of GSM. The HLR contains all the administrative information of each subscriber registered in the corresponding GSM network, along with the current location of the mobile. The location of the mobile is typically in the form of the signalling address of the VLR associated with the mobile station. The actual routing procedure will be described later. There is logically one HLR per GSM network, although it may be implemented as a distributed database.

The Visitor Location Register (VLR) contains selected administrative information from the HLR, necessary for call control and provision of the subscribed services, for each mobile currently located in the geographical area controlled by the VLR. Although each functional entity can be implemented as an independent unit, all manufacturers of switching equipment to date implement the VLR together with the MSC, so that the geographical area controlled by the MSC corresponds to that controlled by the VLR, thus simplifying the signalling required. Note that the MSC contains no information about particular mobile stations --- this information is stored in the location registers.

The other two registers are used for authentication and security purposes. The Equipment Identity Register (EIR) is a database that contains a list of all valid mobile equipment on the network, where each mobile station is identified by its International Mobile Equipment Identity (IMEI). An IMEI is marked as invalid if it has been reported stolen or is not type approved. The Authentication Center (AuC) is a protected database that stores a copy of the secret key stored in each subscriber's SIM card, which is used for authentication and encryption over the radio channel.

Radio link aspects

The International Telecommunication Union (ITU), which manages the international allocation of radio spectrum (among many other functions), allocated the bands 890-915 MHz for the uplink (mobile station to base station) and 935-960 MHz for the downlink (base station to mobile station) for mobile networks in Europe. Since this range was already being used in the early 1980s by the analog systems of the day, the CEPT had the foresight to reserve the top 10 MHz of each band for the GSM network that was still being developed. Eventually, GSM will be allocated the entire 2x25 MHz bandwidth.

Multiple access and channel structure

Since radio spectrum is a limited resource shared by all users, a method must be devised to divide up the bandwidth among as many users as possible. The method chosen by GSM is a combination of Time- and Frequency-Division Multiple Access (TDMA/FDMA). The FDMA part involves the division by frequency of the (maximum) 25 MHz bandwidth into 124 carrier frequencies spaced 200 kHz apart. One or more carrier frequencies are assigned to each base station. Each of these carrier frequencies is then divided in time, using a TDMA scheme. The fundamental unit of time in this TDMA scheme is called a burst period and it lasts 15/26 ms (or approx. 0.577 ms). Eight burst periods are grouped into a TDMA frame (120/26 ms, or approx. 4.615 ms), which forms the basic unit for the definition of logical channels. One physical channel is one burst period per TDMA frame.

Channels are defined by the number and position of their corresponding burst periods. All these definitions are cyclic, and the entire pattern repeats approximately every 3 hours. Channels can be divided into dedicated channels, which are allocated to a mobile station, and common channels, which are used by mobile stations in idle mode.

Traffic channels

A traffic channel (TCH) is used to carry speech and data traffic. Traffic channels are defined using a 26-frame multiframe, or group of 26 TDMA frames. The length of a 26-frame multiframe is 120 ms, which is how the length of a burst period is defined (120 ms divided by 26 frames divided by 8 burst periods per frame). Out of the 26 frames, 24 are used for traffic, 1 is used for the Slow Associated Control Channel (SACCH) and 1 is currently unused (see Figure 2). TCHs for the uplink and downlink are separated in time by 3 burst periods, so that the mobile station does not have to transmit and receive simultaneously, thus simplifying the electronics.

In addition to these full-rate TCHs, there are also half-rate TCHs defined, although they are not yet implemented. Half-rate TCHs will effectively double the capacity of a system once half-rate speech coders are specified (i.e., speech coding at around 7 kbps, instead of 13 kbps). Eighth-rate TCHs are also specified, and are used for signalling. In the recommendations, they are called Stand-alone Dedicated Control Channels (SDCCH).

Figure 2. Organization of bursts, TDMA frames, and multiframes for speech and data

Control channels

Common channels can be accessed both by idle mode and dedicated mode mobiles. The common channels are used by idle mode mobiles to exchange the signalling information required to change to dedicated mode. Mobiles already in dedicated mode monitor the surrounding base stations for handover and other information. The common channels are defined within a 51-frame multiframe, so that dedicated mobiles using the 26-frame multiframe TCH structure can still monitor control channels. The common channels include:
Broadcast Control Channel (BCCH)
Continually broadcasts, on the downlink, information including base station identity, frequency allocations, and frequency-hopping sequences.
Frequency Correction Channel (FCCH) and Synchronisation Channel (SCH)
Used to synchronise the mobile to the time slot structure of a cell by defining the boundaries of burst periods, and the time slot numbering. Every cell in a GSM network broadcasts exactly one FCCH and one SCH, which are by definition on time slot number 0 (within a TDMA frame).
Random Access Channel (RACH)
Slotted Aloha channel used by the mobile to request access to the network.
Paging Channel (PCH)
Used to alert the mobile station of an incoming call.
Access Grant Channel (AGCH)
Used to allocate an SDCCH to a mobile for signalling (in order to obtain a dedicated channel), following a request on the RACH.

Burst structure

There are four different types of bursts used for transmission in GSM [16]. The normal burst is used to carry data and most signalling. It has a total length of 156.25 bits, made up of two 57 bit information bits, a 26 bit training sequence used for equalization, 1 stealing bit for each information block (used for FACCH), 3 tail bits at each end, and an 8.25 bit guard sequence, as shown in Figure 2. The 156.25 bits are transmitted in 0.577 ms, giving a gross bit rate of 270.833 kbps.

The F burst, used on the FCCH, and the S burst, used on the SCH, have the same length as a normal burst, but a different internal structure, which differentiates them from normal bursts (thus allowing synchronization). The access burst is shorter than the normal burst, and is used only on the RACH.

Speech coding

GSM is a digital system, so speech which is inherently analog, has to be digitized. The method employed by ISDN, and by current telephone systems for multiplexing voice lines over high speed trunks and optical fiber lines, is Pulse Coded Modulation (PCM). The output stream from PCM is 64 kbps, too high a rate to be feasible over a radio link. The 64 kbps signal, although simple to implement, contains much redundancy. The GSM group studied several speech coding algorithms on the basis of subjective speech quality and complexity (which is related to cost, processing delay, and power consumption once implemented) before arriving at the choice of a Regular Pulse Excited -- Linear Predictive Coder (RPE--LPC) with a Long Term Predictor loop. Basically, information from previous samples, which does not change very quickly, is used to predict the current sample. The coefficients of the linear combination of the previous samples, plus an encoded form of the residual, the difference between the predicted and actual sample, represent the signal. Speech is divided into 20 millisecond samples, each of which is encoded as 260 bits, giving a total bit rate of 13 kbps. This is the so-called Full-Rate speech coding. Recently, an Enhanced Full-Rate (EFR) speech coding algorithm has been implemented by some North American GSM1900 operators. This is said to provide improved speech quality using the existing 13 kbps bit rate.

Channel coding and modulation

Because of natural and man-made electromagnetic interference, the encoded speech or data signal transmitted over the radio interface must be protected from errors. GSM uses convolutional encoding and block interleaving to achieve this protection. The exact algorithms used differ for speech and for different data rates. The method used for speech blocks will be described below.

Recall that the speech codec produces a 260 bit block for every 20 ms speech sample. From subjective testing, it was found that some bits of this block were more important for perceived speech quality than others. The bits are thus divided into three classes:

  • Class Ia 50 bits - most sensitive to bit errors
  • Class Ib 132 bits - moderately sensitive to bit errors
  • Class II 78 bits - least sensitive to bit errors
Class Ia bits have a 3 bit Cyclic Redundancy Code added for error detection. If an error is detected, the frame is judged too damaged to be comprehensible and it is discarded. It is replaced by a slightly attenuated version of the previous correctly received frame. These 53 bits, together with the 132 Class Ib bits and a 4 bit tail sequence (a total of 189 bits), are input into a 1/2 rate convolutional encoder of constraint length 4. Each input bit is encoded as two output bits, based on a combination of the previous 4 input bits. The convolutional encoder thus outputs 378 bits, to which are added the 78 remaining Class II bits, which are unprotected. Thus every 20 ms speech sample is encoded as 456 bits, giving a bit rate of 22.8 kbps.

To further protect against the burst errors common to the radio interface, each sample is interleaved. The 456 bits output by the convolutional encoder are divided into 8 blocks of 57 bits, and these blocks are transmitted in eight consecutive time-slot bursts. Since each time-slot burst can carry two 57 bit blocks, each burst carries traffic from two different speech samples.

Recall that each time-slot burst is transmitted at a gross bit rate of 270.833 kbps. This digital signal is modulated onto the analog carrier frequency using Gaussian-filtered Minimum Shift Keying (GMSK). GMSK was selected over other modulation schemes as a compromise between spectral efficiency, complexity of the transmitter, and limited spurious emissions. The complexity of the transmitter is related to power consumption, which should be minimized for the mobile station. The spurious radio emissions, outside of the allotted bandwidth, must be strictly controlled so as to limit adjacent channel interference, and allow for the co-existence of GSM and the older analog systems (at least for the time being).

Multipath equalization

At the 900 MHz range, radio waves bounce off everything - buildings, hills, cars, airplanes, etc. Thus many reflected signals, each with a different phase, can reach an antenna. Equalization is used to extract the desired signal from the unwanted reflections. It works by finding out how a known transmitted signal is modified by multipath fading, and constructing an inverse filter to extract the rest of the desired signal. This known signal is the 26-bit training sequence transmitted in the middle of every time-slot burst. The actual implementation of the equalizer is not specified in the GSM specifications.

Frequency hopping

The mobile station already has to be frequency agile, meaning it can move between a transmit, receive, and monitor time slot within one TDMA frame, which normally are on different frequencies. GSM makes use of this inherent frequency agility to implement slow frequency hopping, where the mobile and BTS transmit each TDMA frame on a different carrier frequency. The frequency hopping algorithm is broadcast on the Broadcast Control Channel. Since multipath fading is dependent on carrier frequency, slow frequency hopping helps alleviate the problem. In addition, co-channel interference is in effect randomized.

Discontinuous transmission

Minimizing co-channel interference is a goal in any cellular system, since it allows better service for a given cell size, or the use of smaller cells, thus increasing the overall capacity of the system. Discontinuous transmission (DTX) is a method that takes advantage of the fact that a person speaks less that 40 percent of the time in normal conversation [22], by turning the transmitter off during silence periods. An added benefit of DTX is that power is conserved at the mobile unit.

The most important component of DTX is, of course, Voice Activity Detection. It must distinguish between voice and noise inputs, a task that is not as trivial as it appears, considering background noise. If a voice signal is misinterpreted as noise, the transmitter is turned off and a very annoying effect called clipping is heard at the receiving end. If, on the other hand, noise is misinterpreted as a voice signal too often, the efficiency of DTX is dramatically decreased. Another factor to consider is that when the transmitter is turned off, there is total silence heard at the receiving end, due to the digital nature of GSM. To assure the receiver that the connection is not dead, comfort noise is created at the receiving end by trying to match the characteristics of the transmitting end's background noise.

Discontinuous reception

Another method used to conserve power at the mobile station is discontinuous reception. The paging channel, used by the base station to signal an incoming call, is structured into sub-channels. Each mobile station needs to listen only to its own sub-channel. In the time between successive paging sub-channels, the mobile can go into sleep mode, when almost no power is used.

Power control

There are five classes of mobile stations defined, according to their peak transmitter power, rated at 20, 8, 5, 2, and 0.8 watts. To minimize co-channel interference and to conserve power, both the mobiles and the Base Transceiver Stations operate at the lowest power level that will maintain an acceptable signal quality. Power levels can be stepped up or down in steps of 2 dB from the peak power for the class down to a minimum of 13 dBm (20 milliwatts).

The mobile station measures the signal strength or signal quality (based on the Bit Error Ratio), and passes the information to the Base Station Controller, which ultimately decides if and when the power level should be changed. Power control should be handled carefully, since there is the possibility of instability. This arises from having mobiles in co-channel cells alternatingly increase their power in response to increased co-channel interference caused by the other mobile increasing its power. This in unlikely to occur in practice but it is (or was as of 1991) under study.

Network aspects

Ensuring the transmission of voice or data of a given quality over the radio link is only part of the function of a cellular mobile network. A GSM mobile can seamlessly roam nationally and internationally, which requires that registration, authentication, call routing and location updating functions exist and are standardized in GSM networks. In addition, the fact that the geographical area covered by the network is divided into cells necessitates the implementation of a handover mechanism. These functions are performed by the Network Subsystem, mainly using the Mobile Application Part (MAP) built on top of the Signalling System No. 7 protocol.

Figure 3. Signalling protocol structure in GSM

The signalling protocol in GSM is structured into three general layers [1], [19], depending on the interface, as shown in Figure 3. Layer 1 is the physical layer, which uses the channel structures discussed above over the air interface. Layer 2 is the data link layer. Across the Um interface, the data link layer is a modified version of the LAPD protocol used in ISDN, called LAPDm. Across the A interface, the Message Transfer Part layer 2 of Signalling System Number 7 is used. Layer 3 of the GSM signalling protocol is itself divided into 3 sublayers.

Radio Resources Management
Controls the setup, maintenance, and termination of radio and fixed channels, including handovers.
Mobility Management
Manages the location updating and registration procedures, as well as security and authentication.
Connection Management
Handles general call control, similar to CCITT Recommendation Q.931, and manages Supplementary Services and the Short Message Service.
Signalling between the different entities in the fixed part of the network, such as between the HLR and VLR, is accomplished throught the Mobile Application Part (MAP). MAP is built on top of the Transaction Capabilities Application Part (TCAP, the top layer of Signalling System Number 7. The specification of the MAP is quite complex, and at over 500 pages, it is one of the longest d0cuments in the GSM recommendations [16].

Radio resources management

The radio resources management (RR) layer oversees the establishment of a link, both radio and fixed, between the mobile station and the MSC. The main functional components involved are the mobile station, and the Base Station Subsystem, as well as the MSC. The RR layer is concerned with the management of an RR-session [16], which is the time that a mobile is in dedicated mode, as well as the configuration of radio channels including the allocation of dedicated channels.

An RR-session is always initiated by a mobile station through the access procedure, either for an outgoing call, or in response to a paging message. The details of the access and paging procedures, such as when a dedicated channel is actually assigned to the mobile, and the paging sub-channel structure, are handled in the RR layer. In addition, it handles the management of radio features such as power control, discontinuous transmission and reception, and timing advance.

Handover

In a cellular network, the radio and fixed links required are not permanently allocated for the duration of a call. Handover, or handoff as it is called in North America, is the switching of an on-going call to a different channel or cell. The execution and measurements required for handover form one of basic functions of the RR layer.

There are four different types of handover in the GSM system, which involve transferring a call between:

  • Channels (time slots) in the same cell
  • Cells (Base Transceiver Stations) under the control of the same Base Station Controller (BSC),
  • Cells under the control of different BSCs, but belonging to the same Mobile services Switching Center (MSC), and
  • Cells under the control of different MSCs.
The first two types of handover, called internal handovers, involve only one Base Station Controller (BSC). To save signalling bandwidth, they are managed by the BSC without involving the Mobile services Switching Center (MSC), except to notify it at the completion of the handover. The last two types of handover, called external handovers, are handled by the MSCs involved. An important aspect of GSM is that the original MSC, the anchor MSC, remains responsible for most call-related functions, with the exception of subsequent inter-BSC handovers under the control of the new MSC, called the relay MSC.

Handovers can be initiated by either the mobile or the MSC (as a means of traffic load balancing). During its idle time slots, the mobile scans the Broadcast Control Channel of up to 16 neighboring cells, and forms a list of the six best candidates for possible handover, based on the received signal strength. This information is passed to the BSC and MSC, at least once per second, and is used by the handover algorithm.

The algorithm for when a handover decision should be taken is not specified in the GSM recommendations. There are two basic algorithms used, both closely tied in with power control. This is because the BSC usually does not know whether the poor signal quality is due to multipath fading or to the mobile having moved to another cell. This is especially true in small urban cells.

The 'minimum acceptable performance' algorithm [3] gives precedence to power control over handover, so that when the signal degrades beyond a certain point, the power level of the mobile is increased. If further power increases do not improve the signal, then a handover is considered. This is the simpler and more common method, but it creates 'smeared' cell boundaries when a mobile transmitting at peak power goes some distance beyond its original cell boundaries into another cell.

The 'power budget' method [3] uses handover to try to maintain or improve a certain level of signal quality at the same or lower power level. It thus gives precedence to handover over power control. It avoids the 'smeared' cell boundary problem and reduces co-channel interference, but it is quite complicated.

Mobility management

The Mobility Management layer (MM) is built on top of the RR layer, and handles the functions that arise from the mobility of the subscriber, as well as the authentication and security aspects. Location management is concerned with the procedures that enable the system to know the current location of a powered-on mobile station so that incoming call routing can be completed.

Location updating

A powered-on mobile is informed of an incoming call by a paging message sent over the PAGCH channel of a cell. One extreme would be to page every cell in the network for each call, which is obviously a waste of radio bandwidth. The other extreme would be for the mobile to notify the system, via location updating messages, of its current location at the individual cell level. This would require paging messages to be sent to exactly one cell, but would be very wasteful due to the large number of location updating messages. A compromise solution used in GSM is to group cells into location areas. Updating messages are required when moving between location areas, and mobile stations are paged in the cells of their current location area.

The location updating procedures, and subsequent call routing, use the MSC and two location registers: the Home Location Register (HLR) and the Visitor Location Register (VLR). When a mobile station is switched on in a new location area, or it moves to a new location area or different operator's PLMN, it must register with the network to indicate its current location. In the normal case, a location update message is sent to the new MSC/VLR, which records the location area information, and then sends the location information to the subscriber's HLR. The information sent to the HLR is normally the SS7 address of the new VLR, although it may be a routing number. The reason a routing number is not normally assigned, even though it would reduce signalling, is that there is only a limited number of routing numbers available in the new MSC/VLR and they are allocated on demand for incoming calls. If the subscriber is entitled to service, the HLR sends a subset of the subscriber information, needed for call control, to the new MSC/VLR, and sends a message to the old MSC/VLR to cancel the old registration.

For reliability reasons, GSM also has a periodic location updating procedure. If an HLR or MSC/VLR fails, to have each mobile register simultaneously to bring the database up to date would cause overloading. Therefore, the database is updated as location updating events occur. The enabling of periodic updating, and the time period between periodic updates, is controlled by the operator, and is a trade-off between signalling traffic and speed of recovery. If a mobile does not register after the updating time period, it is deregistered.

A procedure related to location updating is the IMSI attach and detach. A detach lets the network know that the mobile station is unreachable, and avoids having to needlessly allocate channels and send paging messages. An attach is similar to a location update, and informs the system that the mobile is reachable again. The activation of IMSI attach/detach is up to the operator on an individual cell basis.

Authentication and security

Since the radio medium can be accessed by anyone, authentication of users to prove that they are who they claim to be, is a very important element of a mobile network. Authentication involves two functional entities, the SIM card in the mobile, and the Authentication Center (AuC). Each subscriber is given a secret key, one copy of which is stored in the SIM card and the other in the AuC. During authentication, the AuC generates a random number that it sends to the mobile. Both the mobile and the AuC then use the random number, in conjuction with the subscriber's secret key and a ciphering algorithm called A3, to generate a signed response (SRES) that is sent back to the AuC. If the number sent by the mobile is the same as the one calculated by the AuC, the subscriber is authenticated [16].

The same initial random number and subscriber key are also used to compute the ciphering key using an algorithm called A8. This ciphering key, together with the TDMA frame number, use the A5 algorithm to create a 114 bit sequence that is XORed with the 114 bits of a burst (the two 57 bit blocks). Enciphering is an option for the fairly paranoid, since the signal is already coded, interleaved, and transmitted in a TDMA manner, thus providing protection from all but the most persistent and dedicated eavesdroppers.

Another level of security is performed on the mobile equipment itself, as opposed to the mobile subscriber. As mentioned earlier, each GSM terminal is identified by a unique International Mobile Equipment Identity (IMEI) number. A list of IMEIs in the network is stored in the Equipment Identity Register (EIR). The status returned in response to an IMEI query to the EIR is one of the following:

White-listed
The terminal is allowed to connect to the network.
Grey-listed
The terminal is under observation from the network for possible problems.
Black-listed
The terminal has either been reported stolen, or is not type approved (the correct type of terminal for a GSM network). The terminal is not allowed to connect to the network.

Communication management

The Communication Management layer (CM) is responsible for Call Control (CC), supplementary service management, and short message service management. Each of these may be considered as a separate sublayer within the CM layer. Call control attempts to follow the ISDN procedures specified in Q.931, although routing to a roaming mobile subscriber is obviously unique to GSM. Other functions of the CC sublayer include call establishment, selection of the type of service (including alternating between services during a call), and call release.

Call routing

Unlike routing in the fixed network, where a terminal is semi-permanently wired to a central office, a GSM user can roam nationally and even internationally. The directory number dialed to reach a mobile subscriber is called the Mobile Subscriber ISDN (MSISDN), which is defined by the E.164 numbering plan. This number includes a country code and a National Destination Code which identifies the subscriber's operator. The first few digits of the remaining subscriber number may identify the subscriber's HLR within the home PLMN.

An incoming mobile terminating call is directed to the Gateway MSC (GMSC) function. The GMSC is basically a switch which is able to interrogate the subscriber's HLR to obtain routing information, and thus contains a table linking MSISDNs to their corresponding HLR. A simplification is to have a GSMC handle one specific PLMN. It should be noted that the GMSC function is distinct from the MSC function, but is usually implemented in an MSC.

The routing information that is returned to the GMSC is the Mobile Station Roaming Number (MSRN), which is also defined by the E.164 numbering plan. MSRNs are related to the geographical numbering plan, and not assigned to subscribers, nor are they visible to subscribers.

The most general routing procedure begins with the GMSC querying the called subscriber's HLR for an MSRN. The HLR typically stores only the SS7 address of the subscriber's current VLR, and does not have the MSRN (see the location updating section). The HLR must therefore query the subscriber's current VLR, which will temporarily allocate an MSRN from its pool for the call. This MSRN is returned to the HLR and back to the GMSC, which can then route the call to the new MSC. At the new MSC, the IMSI corresponding to the MSRN is looked up, and the mobile is paged in its current location area (see Figure 4).

Figure 4. Call routing for a mobile terminating call

Conclusion and comments

In this paper I have tried to give an overview of the GSM system. As with any overview, and especially one covering a standard 6000 pages long, there are many details missing. I believe, however, that I gave the general flavor of GSM and the philosophy behind its design. It was a monumental task that the original GSM committee undertook, and one that has proven a success, showing that international cooperation on such projects between academia, industry, and government can succeed. It is a standard that ensures interoperability without stifling competition and innovation among suppliers, to the benefit of the public both in terms of cost and service quality. For example, by using Very Large Scale Integration (VLSI) microprocessor technology, many functions of the mobile station can be built on one chipset, resulting in lighter, more compact, and more energy-efficient terminals.

Telecommunications are evolving towards personal communication networks, whose objective can be stated as the availability of all communication services anytime, anywhere, to anyone, by a single identity number and a pocketable communication terminal [25]. Having a multitude of incompatible systems throughout the world moves us farther away from this ideal. The economies of scale created by a unified system are enough to justify its implementation, not to mention the convenience to people of carrying just one communication terminal anywhere they go, regardless of national boundaries.

The GSM system, and its sibling systems operating at 1.8 GHz (called DCS1800) and 1.9 GHz (called GSM1900 or PCS1900, and operating in North America), are a first approach at a true personal communication system. The SIM card is a novel approach that implements personal mobility in addition to terminal mobility. Together with international roaming, and support for a variety of services such as telephony, data transfer, fax, Short Message Service, and supplementary services, GSM comes close to fulfilling the requirements for a personal communication system: close enough that it is being used as a basis for the next generation of mobile communication technology in Europe, the Universal Mobile Telecommunication System (UMTS).

Another point where GSM has shown its commitment to openness, standards and interoperability is the compatibility with the Integrated Services Digital Network (ISDN) that is evolving in most industrialized countries, and Europe in particular (the so-called Euro-ISDN). GSM is also the first system to make extensive use of the Intelligent Networking concept, in in which services like 800 numbers are concentrated and handled from a few centralized service centers, instead of being distributed over every switch in the country. This is the concept behind the use of the various registers such as the HLR. In addition, the signalling between these functional entities uses Signalling System Number 7, an international standard already deployed in many countries and specified as the backbone signalling network for ISDN.

GSM is a very complex standard, but that is probably the price that must be paid to achieve the level of integrated service and quality offered while subject to the rather severe restrictions imposed by the radio environment.

References

[1]
Jan A. Audestad. Network aspects of the GSM system. In EUROCON 88, June 1988.

[2]
D. M. Balston. The pan-European system: GSM. In D. M. Balston and R.C.V. Macario, editors, Cellular Radio Systems. Artech House, Boston, 1993.

[3]
David M. Balston. The pan-European cellular technology. In R.C.V. Macario, editor, Personal and Mobile Radio Systems. Peter Peregrinus, London, 1991.

[4]
M. Bezler et al. GSM base station system. Electrical Communication, 2nd Quarter 1993.

[5]
David Cheeseman. The pan-European cellular mobile radio system. In R.C.V. Macario, editor, Personal and Mobile Radio Systems. Peter Peregrinus, London, 1991.

[6]
C. Déchaux and R. Scheller. What are GSM and DCS. Electrical Communication, 2nd Quarter 1993.

[7]
M. Feldmann and J. P. Rissen. GSM network systems and overall system integration. Electrical Communication, 2nd Quarter 1993.

[8]
John M. Griffiths. ISDN Explained: Worldwide Network and Applications Technology. John Wiley &Sons, Chichester, 2nd edition, 1992.

[9]
I. Harris. Data in the GSM cellular network. In D. M. Balston and R.C.V. Macario, editors, Cellular Radio Systems. Artech House, Boston, 1993.

[10]
I. Harris. Facsimile over cellular radio. In D. M. Balston and R.C.V. Macario, editors, Cellular Radio Systems. Artech House, Boston, 1993.

[11]
Thomas Haug. Overview of the GSM project. In EUROCON 88, June 1988.

[12]
Josef-Franz Huber. Advanced equipment for an advanced network. Telcom Report International, 15(3-4), 1992.

[13]
Hans Lobensommer and Helmut Mahner. GSM - a European mobile radio standard for the world market. Telcom Report International, 15(3-4), 1992.

[14]
Bernard J. T. Mallinder. Specification methodology applied to the GSM system. In EUROCON 88, June 1988.

[15]
Seshadri Mohan and Ravi Jain. Two user location strategies for personal communication services. IEEE Personal Communications, 1(1), 1994.

[16]
Michel Mouly and Marie-Bernadette Pautet. The GSM System for Mobile Communications. Published by the authors, 1992.

[17]
Jon E. Natvig, Stein Hansen, and Jorge de Brito. Speech processing in the pan-European digital mobile radio system (GSM) - system overview. In IEEE GLOBECOM 1989, November 1989.

[18]
Torbjorn Nilsson. Toward a new era in mobile communications. http://193.78.100.33/ (Ericsson WWW server).

[19]
Moe Rahnema. Overview of the GSM system and protocol architecture. IEEE Communications Magazine, April 1993.

[20]
E. H. Schmid and M. Kähler. GSM operation and maintenance. Electrical Communication, 2nd Quarter 1993.

[21]
Marko Silventoinen. Personal email, quoted from European Mobile Communications Business and Technology Report, March 1995, and December 1995.

[22]
C. B. Southcott et al. Voice control of the pan-European digital mobile radio system. In IEEE GLOBECOM 1989, November 1989.

[23]
P. Vary et al. Speech codec for the European mobile radio system. In IEEE GLOBECOM 1989, November 1989.

[24]
C. Watson. Radio equipment for GSM. In D. M. Balston and R.C.V. Macario, editors, Cellular Radio Systems. Artech House, Boston, 1993.

[25]
Robert G. Winch. Telecommunication Transmission Systems. McGraw-Hill, New York, 1993.

Copyright © John Scourias 1996-1999
Written by John Scourias
Last modified October 14, 1997.

[출처] http://www.geocities.com/KindlyRat/GWBASIC.html

GW-BASIC

Download GW-BASIC here! Below we have GWBASIC 3.23, GW-BASIC Manual, Compiler, tutorials, examples and games, all absolutly free. Just click on the blue lettered selection, save and un-zip.

Welcome Modern School of Nagpur

--DIRECTIONS--

Click, download and unzip the following zip files:

GWBASIC.EXE.zip - the complete GW-BASIC 3.23 ( 60.3K )

GWBASIC_Help.zip - a complete GW-BASIC manual by Microsoft in "help" format with indexes and easy to use format. Many thanks to Tom Cloud!

gw-man.zip - a complete GW-BASIC manual by Microsoft in html files. Thanks to Thomas Shaffner. Click on index 2 after downloading. It is an excellent linked index.

Another manual for GW-BASIC.

COMPILER.zip - a GW-BASIC compiler. Read the "read me" for all the information that I know. It outputs a stand alone exe file when compiled with the /O option and linked.

OptionList.zip - a list of options for the GW-BASIC compiler (BASCOM). Some do not work.

Compiling GW-BASIC -porting GW-BASIC to QuickBasic2.0 ( probably our compiler ).

GWCOM.html - an optional list of commands. 12 Jun 2002 by KindlyRat before the above manual was recieved.

exil- a Linux / GW-BASIC converter.

basictut.zip - an optional tutorial by Castcoly Software. After unzipping click BT1 and BT2 and press "page up" and "page down" to read.

Free BASIC Compilers and Interpreters

Norman DeForest - deep research into the GW-BASIC language.

Scott's GW-BASIC / Windows solutions!

IconToBasic - run your favorite BASIC programs from desktop Icons!

BASICtoTEXT - change BASIC to Text (Notepad) files.

GWscan - a program from ScottServer that does the same thing. Check out the other programs too!

Here's another good GW-BASIC tutorial.

Here's a link to a TRS-80 (RadioShack) to Windows translator by AW Software.

hbasic.zip - A version of GW-BASIC for Hercules graphics

Commodore Basic for Windows.

Microsoft Small Basic A new BASIC for Windows!.

font.zip - a font set for GW-BASIC for Hercules graphics

Here's some new fonts for the DOS Box that we use with GW-BASIC, Thanks to Matt Gregory!


-- HINTS --

GW-BASIC was once the main language used on home computers and is still useful in learning the fundamentals of computer programming and smaller utility programs. It still runs on Microsoft Windows computers thru WindowsXP, though not in a window, but on the black screen used for MS-DOS programming above that will pop up when you click on the GWBASIC icon.

GW-BASIC is an interpreted language which means that it isn't compiled. You type the program in or copy and paste it into a text ( Notepad ) file saved with the name and a .BAS suffix, surrounded by quotation marks. Entering "run" will start the program. GW-BASIC uses line numbers and runs and saves files with a ".BAS" suffix in the same file as the interpreter. You can also run a program by "dragging and dropping" the program on top of the interpreter.

You can find a Users Guide and Reference at any good garage sale or library. Also don't forget to check Amazon.com's used books and I found a "Microsoft GW-BASIC Users Guide and Reference" at Half.com for $0.75! If all else fails I have a list of GW-Basic commands for download above and several tutorials and links to tutorials.


---GWBASIC GAMES---

note: these games are for GW-BASIC, BUT can be "LIST"ed and clipboarded and saved to notepad. Then you can load them into other BASIC languages. You may have to change a few lines.

dominoes.zip...a good dominoes game
chess1.zip...chess game by RAKASKA
SLOT.zip...slot machine game by ROCHE FAHLANEIGH
MNPLY.zip...monoply game by ROCHE FAHLANEIGH
bluesbox.zip...a song writing / playing program
checkers.zip...a good but dumb game
SantaParavia.zip...( UNDER DEVELOPMENT )
lemonade.zip...run a lemonade stand
HAMURABI.zip...rule a primitive society
HAMURABI3.zip...rule a primitive society
Slot6.zip...a good slot machine game
Pic3.zip...draws random colorful rectangles
BATNUM.zip...a good math game. add line "110 RANDOMIZE TIMER" for better random numbers
23mtch.zip... an old 23 Match game
aceydu.zip... acey deucy anyone?
buzzwd.zip... a buzzword creator
chomp.zip... two or more players. from ScientificAmerican
craps.zip... a good craps game
stars.zip... a number guessing game
fibonacc.zip... a Fibonacci Series Calculator
mugwmp.zip... find the mugwmp on a 10 X 10 grid
eliza.zip... an artificial intelligence game
nim.zip... a good NIM game, use caps
Scott...BASIC programs
salvo1.zip...an artillery game

---CODE EXAMPLES---

archie.zip...learn Structured BASIC Programming!
BAS-INT.zip...C code for a tiny BASIC interpreter.
gwup07.zip...decodes protected GW-BASIC programs
sequential.zip...demonstrates search, list first and read
circles.zip... random circles in SCREEN1
SDOFRND2.zip... predict future by random generators
snails.zip...population sampeling theory test
PIBAS.zip...PI calculation by the casino method
RootSumSquare.zip... prove a calculation method
factor.zip... finds the factors of numbers
demo2.zip... old Zenith BASIC graphics demo
menuet.zip... PLAY music demonstration
binary.zip...demonstrates search, list first and read
dietest.zip...checks the Random Generator
two-buffer.zip...demonstrates sort of A$, list first and read
bubble.zip...demonstrates sort of A$, list first and read
Mandelbrot.zip...Mandelbrot Fractal demonstration
ListDisk.zip... by Eric Tchong, formats BASIC programs for listing or printing.
SortThem... another Eric Tchong QuickBASIC program that demonstrates sorts.
RanHex.zip...random hexadecimal generator
Cypher.zip...a text encoding program
AnimalVegtableMineral.zip...a game/example that learns
99bob.zip...demonstrates messing around in BASIC
combinations.zip...possible combinations of three numbers
MorseConverter...converts a message to Morse Code.

KindlyRat

Refactoring Tools Review - Part I

By Uri Lavi

Cross post from IRefactor

Don Roberts and John Brant stated in the book Refactoring - Improving the Design of Existing Code:

"Refactoring with automated tool support feels different from manual refactoring".
Indeed - It is!
Having an automated tool that helps you to change the code without the fear of breaking it - is invaluable.

That's why, I wanted to summarize several available options for .NET developers.

Let's start with the obvious one: Visual Studio Refactoring Tool.
As usual Microsoft concentrates on the core business, leaving the field to other players.

Visual Studio Refactoring Tool

Visual Studio comes with a very simple Refactoring Tool, available from the Refactor
toolbar or from the Refactor context menu.



As you can see, all the refactoring steps have keyboard shortcuts.
In addition, Visual Studio triggers some of the aforementioned refactoring steps behind the scene, when a certain change is detected.
Those changes are mostly underlined with a double red line, as here:
Using the combination Shift-Alt-F10 will fire the correct refactoring step menu, allowing smooth and quick refactoring.
(In the case above - Rename refactoring step).

The Refactoring Tool provides pretty basic refactring steps:
  • Rename -
    The tool effectively changes the names (variables, methods, types and etc...) across projects in the same solution.
    The changes can be easily reviewed (checked/unchecked) prior the modification through the Preview Changes menu.

  • Extract Method -
    Visual Studio provides a basic method extraction mechanism. Extract Method generates a new method with correctly inferred parameters (from the extracted scope) and substitutes the extracted block code with a call to the method. In addition, Extract Method identifies whether a method uses local class members and if not, suggests marking the extracted method as static.
    In the Refactoring process this often indicates that the method should Move to a different class, but Visual Studio Refactoring Tool doesn't provide any suggestions to where such a move is possible.
    (There are other tools that do provide the suggestions - patience, patience...).
  • Encapsulate Field -
    Creates properties for existing members.
  • Extract Interface -
    Enables extraction of an interface from a type.
  • Promote Local Variables to Parameter -
    Promotes a local variable to a method's parameter.
    When a local variable declaration isn't selected correctly, the tool will prompt with an explanatory menu (first screenshot).
    Also, the tool will alert when it cannot guarantee that all the callers pass a legal value to the newly promoted parameter (second screenshot).


  • Remove Parameters/Reorder Parameters -
    Adjusts a method's parameters.
Clearly, as stated above, this is a very simplistic refactoring tool, especially when comparing to Eclipse. As you can see below, Eclipse comes with much more refactoring steps available out of the box.
There are more than 20 refactoring steps in the Refactor menu.

In addition, one can utilize additional Visual Studio "Refactoring" features.

Visual Studio Additional "Refactoring" Features
  • Source Code Length -


    Adding Guides to the Vusial Studio IDE will allow to visually emphasis the length of the source code line.
    In order to add Guides, you should edit the "HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\X.X\Text Editor" key in the registry (where X.X is the VS version).
    Create a string key called "Guides" with the value "RGB(255,0,0), 80" in order to have a red line at column 80 in the text editor.
  • Code Definition -
    Using the Go To Definition each time you want to examine the referenced method or type is very tedious. That's why the Code Definition Window is handy! As you move the insertion point in the editor, or change the selection in Class View, the Object Browser, or Call Browser, the content of the Code Definition window is updated and displays the definition of a symbol referenced by the selection.

  • Code Metrics -
    Knowing the code complexity can help writing a more clean and refactored code. Visual Studio provides the Code Metrics Window that provides a better insight into the developed code. I would suggest to pay attention especially on the following metrics:
    1. Cyclomatic Complexity - Measures the structural complexity of the code.
      A program that has complex control flow (and thus a high cyclomatic score) will require more unit tests to achieve good code coverage and will be less maintainable.
    2. Class Coupling - Measures the coupling to unique classes through parameters, local variables, return types, method calls and etc...
      High coupling (and thus a high class coupling score) indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types.



Here is the combined IDE view with all the additional "refactoring" features:



Of course, an experienced Software Engineer can create a clean and refactored code, even with the skim Visual Studio Refactoring Tool and additional "Refactroing" features. The experience though isn't going to be smooth and easy. The refactoring features are scattered and as overall not so user friendly.

Summary:
  • The Visual Studio Refactoring Tool is rather simplistic.
  • Most used refactoring steps are: Rename and Extract Method. Those steps provide fairly good functionality (though extra behavior is possible when extracting a method).
  • Other significant refactoring steps don't exist; Microsoft leaves the stage to other players.
  • Additional refactoring features, as: Source Code Length, Code Definition and Code Metrics exist and provide complementary ways to understand and refine your code. The features, though, scattered across different places which makes it hard to simultaneously work with all of them.
In the next post we will examine additional automatic refactoring tools.<!-- codeproject -->

http://www.the-software-experts.de/e_dta-sw-refact-maintenance.htm

Refactoring Methods

General Remarks

On this page we only want to give an overview on some of the methods we apply in the refactoring of C code. These methods differ from the methods decribed e.g. in Martin Fowlers book about refactoring. One of the reasons is that we developed the methods for C where as Martin Fowler describes them for Java. Another even more relevant reason is that we set up the methods for safety critical microcontroller applications which have to use MISRA C and usually use a defined rigid architecture and design rules. Refactoring in this environment has to follow defined rules. For more details we recommend to read the page on refactoring principles where we go into more details on this subject.

Make the Code Error free according to the MISRA checking Tool

I discussed the ideas of a safe coding in C on the pages about design, therefore I will not repeat it here. The main goal of this refactoring step is to let an automatic code checking tool run on your code and analyze its output log file. These tools come up with most of the important errors you can bring into a C-program while you code. These are potential erros like the:

if (a = b){... some code ...}

where almost certainly it was meant to be:

if (a == b){... some code ...}

The tool will also come up with error messages concerning suspicious type casts. If you have:

void my_function(void)
{
unsigned char x;
unsigned short y;

... some code ...
x = y;
... some code ...
}

The assignment of y to the variable x will lead to a loss of the upper 8 data bits. This may be perfectly o.k. because your data range of y is within 8 bit. Then you can do a simple type cast to solve the problem:

void my_function(void)
{
unsigned char x;
unsigned short y;

... some code ...
x = (unsigned char)y;
... some code ...
}

Refactoring at this point has to check the possible data ranges and find a satisfying solution for the problem. This may be a simple type cast to keep the checking tool silent, but it also may mean a bigger re-design of the code portion to avoid the loss of bits in an assignment.
The overall goal is to work on the code util the checking tool does not report any more errors. This will guarantee a certain quality of the code, which is suitable for safety critical systems.

Get rid of Bitfields

The bitfields in focus here are the so called ANSI-bitfields. They are commonly named that way because they already have been defined in the old ANSI-C standard (1989). They are defined as follows:

struct BF {
int bit0:1;
int bit1:1;
int bit2:1;
int bit3:3;
int bit4:1;
int bit5:1;
int bit6:1;
} bitfield;

The access to the individual bit is done as:

bitfield.bit1 = 1;

There are several problems involved in these bitfields. First of all not all compilers allow the same kind of definitions. Some compilers allow multiple data types as e.g. "unsigned short" or "unsigned char" for the definition of the individual bits. The data types can be all basic data types and they can be mixed in the same struct definition. Other compilers rigidly stick to the old ANSI definition which only allows the datatype "int" for the bits and multibit fields in the struct (multibit fields have e.g. the size of 3 bits in our example). However if you are forced to use the data type "int" in reality it makes the individual bit a signed number of the value -1. Therefore if you use a bit in any calculation it will use the -1 or 0 for the calculation although you most likely would expect it to be 1 and 0. This means you have a problem due to unexpected values in your calculation but you also may have a problem with the portability of your code. Only if you restriced yourself to using "int" as datatype for the bits you can be sure that your code is portable across all compilers.

Another problem is that the memory representation of your ANSI-bitfield is completely implementation dependent. You simply do not know how the stuff is stored in the memory. This means you can not access it as a complete word, character or long variable. Such a way of accessing the bitfield may come in handy if you think of a fast initialization. You could initialize the bitfiled by writing to it as a word variable and assigning 0 to it. Since you do not know how it is represented in memory you are forced to initialize it bit by bit via the symbolic expression. Another problem due to the various memory representations may occur if you have to store memory data e.g. to a file in one CPU environment and reload the data in another environment with a different memory representation of bitfields.

Because of these problems I came up with a method to use normal variables such as unsigned short or unsigned long as bitfields. With some smart macros I can set a bit e.g. with the expression bitfiled |= 0x8000; and reset the same bit with the expression bitfield &=~ 0x8000; With a couple of defines for the bits and the operations this leads to an easy to use method for bitfields which can be also accessed as normal variables. Their size is the size of the basic datatype used in the definition. I also came up with some functions to read and write the multibit fields inside a bitfield. They look a bit complex, but runtime measurements showed that this way of dealing with bitfields is even faster than the operations on ANSI-bitfields.

Because of these problems you should have a refactoring step which replaces all ANSI-bitfields with the smarter and less problematic solution.

Data Types have to be used according to the Design Rules

In the design rules I set up we first of all prohibited all floating point variables. Only a few microcontrollers have a floating point unit and can handle them without overhead. A micro which does not have a FPU will go into quite lengthy library calls to deal with them. This is simply a runtime killer. On top of it there was never a series application which really required the precision and data range of floats. Another problem is that floats are a bit tricky in compare operations (if, for, while, etc.). The expression if (a == b) will be rarely fulfilled if both or one of the variables is a float. The same is true for loops. For these reasons I banned floating point values completely out of all systems I was responsible for.

Other datatype issues are mainly related to the mixing of datatypes. You should avoid mixing signed and unsigned calculations. Bring everything to the one kind. However if you are forced to mix them you should make sure that the conversions are save and e.g. the signed value is definitely not negative before you assign it to an unsigned value. Or have you ever seen this example?:

int main(void)
{

unsigned char x;

x = ~0xAA;

if (x == ~0xAA)
{
printf("I should come out here\n\n");
}
else
{
printf("I should not be here\n\n");
}
getchar();
}

Everybody would expect to come out in the "I should come out here" branch. But it doesn't! The problem comes from the implicit promotion (8bit -> 16bit) the C compiler performs and then it casts it back to 8bit. A problem due to the implicit mixing of datatypes. The refactoring should take care of this and bring the code into a save condition.

No Global Variables

I described the danger of global variables sufficiently in the design section of this web-site and there is no need to repeat it here. It is also against the idea of object orientation to have global variables. One of the outstanding features of object orientation is that the data are combined with the operative code lines in the same module and that these data are encapsulated. This means that they can not be accessed from other modules (object) except via the defined get-function. If your code needs global variables it is suffering from much more serious design sins and should be refactored to conform to a true object oriented design. After you have done this it should be no problem to make the global variables at least static and thus not linkable for other modules.

Standard C-Libraries avoided?

Most programmers will be puzzled by this demand to get rid of the use of standard C-Libraries. But here I am talking about safety critical microcontroller applications. The demands of the related international standards show clearly that your source code has to undergo certain quality and test measures before it can be certified in the used system. In other words there is a big fuzz about the code YOU wrote and then you just use the code SOMEBODY ELSE wrote in the form of standard libraries. And on top of it, in most cases you do not even have the source code of the library so that you are not even able to see how it was done. What? Do you believe this code is perfect just because it was sold to you when you bought your compiler? Fairytales! It was done by programmers and they make mistakes. If you want to have the control of what is happening in your safety critical system you must not use third party software and if you have to use it for some reason it has to be transparent regarding the source code, the tests which have been performed on it and the other quality measures which were employed. Usually you do not get this proof. You just get a heap of binaries. Make your own libraries, test them according to the required measures by the international standards and make sure by refactoring that it is used everywhere in your code.

Check the Control and Data Flow

As indicated in the design section a good system should be data flow driven in its design and the data flow should be uni-directional as far as possible. This means that the outputs which have to be generated by the system need certain data. The output should aquire the data it needs to perform the output. This data is processed in some way and in turn relies on further data, until you reach the inputs of your system. In other words your objects should have get-functions but preferably no set-functions. Make sure in the refactoring phase that this design princple is adhered to. It may mean bigger changes in the design if you have to restructure the code, but it is worth while.

Use defined Naming Conventions

Naming conventions are a bit formalistic and thus not very highly esteemed. However if you name your variables, functions and modules consistently and according to a defined system you will have the great benefit that everybody will immediately know what the code is all about. Starting from the programmer himself, the colleagues who does a review, the next programmer who wants to re-use it or do maintenance on it, the tester, all will benefit from it. I will not go into the naming convention itself since I did this on another page, but use this refactoring method and apply the naming convention to make the code better understandable.

Use defined Templates

Define templates for your code and use them! There should be clearly identified sections where you put typedefs, defines, function prototypes, the source code itself, etc. etc. The reasons are similar to those for using defined names for variables and functions. It makes the whole code better understandable and everybody knows where to find what.

Keep the Header Structure simple

Some years ago I came as a newcomer into a project and tried to get all the code and headers collected and tried them to compile. It took me three days to succeed! O.k. there were some configuration managent problems and I had to get some files from certain colleagues instead of beeing able to get it from the code repository. But most of the time I wasted with finding out which headers I needed to get in which of their versions. Finally, after I succeeded, I found that for the literal handful of source code modules I needed almost 50 different header files which were nested, had cross includes and all sorts of dependencies. Many of the headers were included because a single define was needed out of the hundreds it contained. I cleaned it out after I was put in charge of the design. Now the same software needs 5 headers and they do not have any dependencies, cross includes or circular includes. And they are single level includes i.e. there are no nestings. The refactoring step needs to be based on a clear concept and "design" of your headers. You need to know what headers there shall be and what they have to contain. Then make sure that they do not depend on each other. Include them in the right sequence rather than making nestings. The following example shows how to reduce the nestings:

The header file macros.h makes use of a basic data types in the form of a redefinition of "unsigned short"

#define HIGEST_BIT(T_UWORD)0x8000

In order to be able to do this the file macros.h should include the file which contains the redefinition of "unsigned short"

#include"datatypes.h"
#define HIGEST_BIT(T_UWORD)0x8000

The datatype.h file contains the following define:

typedef unsigned shortT_UWORD;

But the problem is that many other headers will also need these data type redefinitions. Now imagine that the same happens with other defines which are located in other headers. The result is a nested header structure with circular and cross includes, like the one I described above. The solution is quite simple. You just have to prohibit sub-includes completely, and then after you have set up a clear concept what shoud be in which header, simply include the headers in the right sequence in your source files:

#include"datatypes.h"
#include"macros.h"

Then all headers which are included after the inclusion of the datatypes have them available and do not need to include it for themselves.

Split up C-Functions

There are a few indicators which tell you if a C-function should be split up or not. One of the indicators is the parameter list. If the pass parameters to a function are more than 4 then you should have a closer look to find a way to split up the function. The number of 4 is based on the usual number of parameters which can be passed to a function in CPU registers. If you have more parameters they go on the stack. This value may differ depending on the CPU and compiler you use. In some cases this may be six parameters, but not more. This rule is concerned about the runtime and resources of your application, but at the same time it can be said that the more parameters a function has the more complex it is. A condidate to be split in several smaller functions.

I have seen functions with 40 input interface variables. Not as pass parameters but as global variables. A closer look showed that the function contained a number of independent sections. Each section had e.g. 10 code lines and used 5 of the variables, but the sections were not related to each other in any way. This was an ideal candidate to make a function out of each of these sections and use a pass parameter interface to hand them the needed data. Generally speaking if a functions is bigger than what you can display on a single screen page you should find a way to split it up.

Use temporary Variables the Right Way

There are some commonly practiced sins concerning local variables. First of all you should not write to a variable which came in by the pass parameter interface. It is an input and a good programming style is that you never ever ovewrite an input. Neither a temporary variable which came in via the pass parameter interface nor static or global data. Always open a new variable if you have to modify something on your inputs. If you do not observe this it may be hard to test your software.

Secondly avoid to reuse the same local variable for different purposes. I saw programs which had a variable called "temp" and it was used in sequence as a loop counter, for storing intermediate calculation results, etc. etc. Open an own variable for each of these purposes. If you fear that you end up with too many local variables in your function and that they are therefore put on the stack, you should split the function!

Use local variables for all operations in your function and interface to the outside world i.e. static variables or get-functions of other objects at the beginning and at the end of your function. This advise is contrary to what you find in other refactoring literature but there are some good reasons for it. First of all there is the subject of runtime again. If you call a get-function multiple times in a piece of code, the function will a be always called and executed. This generates some overhead because in order to call a function the address of the next instruction after the function call will be stored on the stack, some registers may be saved to the stack, there has to be a jump to the called function and finally a jump back to the stored next instruction of your calling program part. All this is some overhead if you compare it to simply accessing a variable in memory. Therefore call the sub-function once and use the value which will be held in a register throughout your part of the program. This is a trade off between an object oriented design on the one hand and an optimized speed on the other hand. The same is true for the use of static data in your piece of code. If a variable which is residing permanent in the memory is used multiple times the program will always do a fetch from the memory each time it comes across the variable. This fetch operation will also consume extra time which you can avoid if the value is loaded to a register (local variable) and then used in the program. The following example will illustrate this. It uses a pseudo Assembler code to illustrate what operations are performed by the CPU on the memory to run through a sequence of code lines:

void my_function()
{
... some code ...

if (My_StaticValue < -8191) Register1 = Memory(My_StaticValue)
Register2 = -8191
Register1 COMPARE TO Register2
{
My_StaticValue = -8191; Memory(My_StaticValue) = Register2
}
else
{
if (My_StaticValue > 8191)Register1 = Memory(My_StaticValue)
Register2 = 8191
Register1 COMPARE TO Register2
{
My_StaticValue = 8191;Memory(My_StaticValue) = Register2
}
}
}

Now I show the example of the same code lines if the value is not residing in memory, but is coming in by the pass parameter interface:

void my_function(My_Value)Register1 contains My_Value
{
... some code ...

if (My_Value < -8191)
Register2 = -8191
Register1 COMPARE TO Register2
{
My_Value = -8191; Register1 = Register2
}
else
{
if (My_Value > 8191)
Register2 = 8191
Register1 COMPARE TO Register2
{
My_Value = 8191;Register1 = Register2
}
}
}

As you can see the second design option uses less code lines and therefore executed faster. Less code simply means faster execution. But on top of it you have to consider that the access to the memory is a slow operation. A line accessing the memory can take double or even more of the time that an operation using registers would take. There are influences like the waitstates and other bus issues which slow down these operations.

But there is another subject which gives us a good reason for interfacing to the outside world and using temporary variables inside the function. As you can see in the above example concerning the data types the implicit promotion and type casting mechanism of C-compilers can play quite nasty tricks on you. By interfacing every used variable to locals you can use local variables which are of the natural bit size of the registers and thus avoid automatic promotion by the compiler. With other words you simply perform a step explicitly which would be done by the compiler anyway implicitly without you being aware of it. The casting and promotion between the various bit sized variable types is under your control after you did this refactoring step. In a code for a 16 bit CPU could look like:

unsigned short my_function(unsigned char my_offset)
{

unsigned short x;
unsigned short y;

x = (unsigned short)my_StaticCharacterX;
y = (unsigned short)my_StaticCharacterY;

if (x <= y)
{
x = y + (unsigned short)my_offset;
}
else
{
x = y - (unsigned short)my_offset;
}
return(x);
}

Resolve multiple Definitions

Have you ever seen data definitions using a struct in a struct in a struct in a blabla and so on?

There is the feeling of the programmer or some other reason to group data together in structs. Certainly there is a place for structs in C but nesting them over more than one level turns into a nightmare. The access to an element would then look like:

My_struct.my_first_substruct.my_second_substruct.yet_another_struct.element = 1;

Because this is quite a mouth full and turns unreadable in the code smart programmers tend to have the idea to make defines to shorten the "mouth full". Then they do something like this:

#define STRUCT_L1 My_struct.my_first_substruct
#define STRUCT_L2 STRUCT_L1.my_second_substruct.yet_another_struct
#define MY_ELEMENT STRUCT_L2.element

And after they did this proud piece of redefinitions they are going to use "MY_ELEMENT" in their code. The result is that the person doing maintenance or testing on these structures and their redefinitions will simply go coo coo after a day of work trying to find the bottom of this swamp. No joke, I have seen nestings of ten levels and more! Get rid of this. Beak it up. There is no logical reason for grouping every single variable or constant used in the system in ONE struct. There are ways you can convince your linker to pack stuff together in the memory, and there are ways to break up the monster structs into smaller ones. Simple basic data types, simple and small structs, if needed a few arrays, that's what you should go for and your refactoring should achieve this.

Use Defines instead of Fixed Numbers

This is a simple refactoring method. Instead of using fixed values like 3.14 you should make a define like:

#define PI 3.14

Then in your code you should write "PI" instead of typing "3.14" at the places you need the constant. This makes the code better understandable, especially if your defines have sensible names. Further you can easily change the define at one place and all your code uses the updated value. Of course only if you used the define consequently at all places. This will avoid to have inconsistencies in case a constant changes. No need to look through all the modules in this case. The change is effiective at all places.

Avoid Function like Macros

Some programmers love function like macros. They seem to use them at every possible occasion. However they have a number of problems and therefore I prohibited them in all projects I was responsible for. Let's look at one of the problems. Imagine we have the following macro to do an absolute value calculation:

#define abs(x) (x>0)?x:-x

Then we use the macro in the follwoing code lines:

int main(void)
{
int b;
int c;
int y;

b = 5;
c = 7;

y = abs(b-c);
}

What you would expect is the result of 2 being assigned to y, because 5 - 7 equals to -2 and the absolute value of -2 is 2. But the function like macro does not do the trick. The actual result is -12 which is simply wrong. The reson for this is that the macro undergoes a text replace and thus the code line y = abs(b-c); extends to:

y = (b-c>0)?b-c:-b-c

Therefore the result is -b-c which is -12.

There are other problems with macros. If you do not explicitly use type casts to make the involved variables the data types you define, they will be automaitcally promoted to "int", which could involve the change of the sign and the bitsize of the value. This also leads to anwanted effects. I simply prohibited them because there is no logical reason for having them. Just make a simple function out of it and if you fear the overhead make the function "inline" and it will be extended to every code portion where the function is called, just like a macro would be, however without the dangers I just pointed out. Just one further hint. Inline functions need to be in the same module as the code which makes use of them, but if you put the inline function into a header it even can be used by every module which includes the header. For this subject you should disregard the MISRA standard. MISRA has no problem to allow function like macros (although they come up with some restrictions) but the 2004 MISRA it prohibits in rule 8.2 to put code into a header. At this point the standard is simply stupid and incorrect and you should do your own sensible rules here, like I pointed out in this refactoring step.

Simplify logical Conditions

Some multiple conditions in C-programms can be very hard to comprehend, and they are even harder to be tested. The same is true for nested "if" conditions. The following line may serve as an example:

if((a == b) || (c == y) || (z != a)) { printf("hello world");}

You can split this up into a few simple if conditions which make it much easier to see what is going on:

tmp = 0;
if(a == b) tmp = 1;
if(c == y) tmp = 1;
if(z != a) tmp = 1;

if (tmp == 1) printf("hello world");

Sorry for this simple example. It should show the principle of this refactoring step. If you look at the assembler lines the compiler makes out of the two examples you will find that the effort is almost the same and runtime or other resource issues can not be an argument against it. But it is much easier to be understood and it is much easier to modify it and test it.

Cut your Modules the Right Way

How should your modules look like? There are a few simple metrics which can help you to set them up in a way that they have a good size. As already mentioned each function in a module should not be bigger than what can be displayed on on screen page. Then there is the number of get-functions in a module. More than 20 is definitely too much and it is an indicator that you should find a way to split it up. Between 10 and 20 is o.k. if it can be justified that the module is good this way. 10 or less get-functions is ideal. Set-functions should be the exception in order to keep the data flow unidirectional. The number of private functions (sub-functions only used inside the same module) can be as much as needed. Again their size should be not bigger than a screen page. If there are very many very little ones you should also have a look into the design of the module. The number of public functions (except get-functions) should not exceed 3. In addition to that there may be a init-function which initializes the module. These numbers are values from experience and could be found in good design I saw so far.

In addition to that you should have a look at the interfaces of a module (object). The best is if they have basic data types. If you have arrays and structs (i.e. pointers to them) at the interfaces you should have a second look to see if this can be avoided. Very often you can get rid of such an interface by simply moving one function from one module to another.

Last but not least you should always make sure that your modules constitute objects in the sense of object orientation. I.e. they should represent an object of the real world, e.g. a sensor, a switch, a solenoid. Of course you should also make sure that you have an architecture which defines layers in your software (e.g. a HW-abstraction layer). All these principles should influence your refactoring activities on the size and shape of your modules.

하드웨어적 관점에서 접근한
휴대폰 개발 프로세스

휴대폰 개발은 다른 임베디드 시스템 이상으로 방대한 특성 탓에 각 분야마다 많은 전문 인력이 투입되어 개발이 진행된다. 이 글에서는 하드웨어를 중심으로 휴대폰 개발의 개괄적인 현황과 개발 프로세스를 설명하고, 다른 임베디드 시스템 개발에도 적용될 수 있는 소프트웨어 기법 몇 가지를 추가로 소개한다.

박찬민 eacs@hanback.co.kr

먼저 프로토콜, 플랫폼 등을 기준으로 휴대폰의 변화 과정을 설명하면서 개발 프로세스를 이해하는 데 필요한 기본 지식을 점검해 본다.

프로토콜에 따른 구분

먼저 프로토콜에 따라 휴대폰 서비스를 구분해 보면 다음과 같다.

CDMA와 GSM

무선 구간에서 기지국과 단말기 사이의 신호 전송방식은 동기식과 비동기식으로 구분되는데 북미 방식인 동기식은 기지국에서 GPS(Global Positioning System)의 시간과 위치정보를 이용하고, 유럽방식인 비동기식은 GPS를 사용하지 않는다. CDMA (Code Division Multiple Access)로 대표되는 동기식의 경우 IS-95 프로토콜을 포함한 cdmaOne과, IS-2000 프로토콜을 근간으로 한 cdma2000이 있으며, 비동기식은 GSM(Global Service for Mobile Telecommunication)과 이를 기반으로 한 UMTS가 있다. cdma2000과 UMTS는 IMT-2000의 규격에 부합되는 프로토콜이다.

IMT-2000

1996년 5월 10월 TG8/1 회의에서 승인된 IMT-2000은 CDMA와 GSM으로 양분되어 국제로밍이 어려웠던 점을 극복하고자 전 세계적으로 동일한 주파수(2GHz) 대역을 사용해 로밍할 수 있게 하는 방식이다. 유럽방식인 비동기식 CDMA와 북미방식인 동기식 CDMA로 구분되며 비동기식 CDMA를 W-CDMA(Wideband CDMA), 동기식 CDMA를 MC-CDMA(Multi Carrier CDMA)라고 한다. 음성통화 중심의 2G (Generation)에서는 전 세계 80% 이상이 GSM을 사용하고 있으므로 고속 데이터 서비스를 포함해 부가 서비스가 강화된 3G는 대부분의 국가가 유럽방식인 W-CDMA를 채택하고 있다.

W-CDMA와 HSDPA

영상통화와 VOD, VoIP, UCC, 내비게이션에 이르기까지 무선 인터넷 기반의 새로운 서비스를 제공하는 IMT-2000은 CDMA와 GSM으로부터 진화했다. CDMA에서 출발한 동기식은 주파수 효율과 데이터 서비스 속도를 개선해 CDMA2000 1x, CDMA2000 1x EVDO를 거쳐 CDMA2000 1x EVDO Revision A로 진화하고 있으며, GSM을 기반으로 한 비동기식은 WCDMA, HSDPA를 거쳐 HSUPA로 진화하고 있다. HSDPA는 다운로드 속도에 비해 업로드 속도가 제한적이었으나 HSUPA에서는 업로드 속도까지 함께 개선되어 영상통화를 비롯한 본격적인 양방향 초고속 데이터 서비스 시대를 열고 있다.

플랫폼에 따른 구분

이어서 플랫폼을 이용한 구분을 살펴보면 다음과 같다.

휴대폰 플랫폼

휴대폰 플랫폼은 타깃에 따라 Value, Multi media, Enhanced, Convergence로 나눌 수 있는데 휴대폰 기능에 충실한 Value는 아프리카나 동남아, 중국과 같은 저가 시장을 목표로 하고, 최상위 플랫폼인 Convergence는 휴대폰용 프로세서의 비약적인 발전에 힘입어 PC 성능을 접목한 지능적인 휴대폰을 목표로 한다.

지금까지의 휴대폰 플랫폼은 디지털 카메라나 MP3 플레이어, 휴대용 TV, 내비게이션, 게임기 등의 융합에 필요한 멀티미디어 처리 능력의 향상에 주력해 왔다. 하지만 최근에는 PC에서 수행하던 업무들을 이동 중에도 수행할 수 있도록 휴먼 인터페이스를 포함한 대화면 터치스크린, HSDPA/HSUPA 고속 데이터 서비스, WiFi를 결합한 MID(Mobile Internet Device) 형태의 Convergence 플랫폼으로 발전하고 있다. 또 다른 측면에서는 RFID나 각종 센서와 결합해 모바일 RFID나 홈 네트워크, 헬스케어와 같은 특수 분야까지 진출하기도 한다.

<그림1> 프로토콜에 따른 구분

모바일 프로세서

기능성과 이동성이 강조된 휴대용 플랫폼에 대한 수요가 급증함에 따라 스마트폰을 중심으로 한 MID 제품군에 많은 관심이 집중되고 있는데, 기존 휴대폰에 채용된 ARM9 코어에 모뎀 제어와 2D 그래픽 처리용 DSP가 결합된 형태로는 한계에 부딪힐 수밖에 없다. 이를 해결하기 위해 최근 인텔은 1.8GHz 성능을 제공하는 CISC 기반의 초소형 기기용 프로세서인 Atom을 출시한 바 있고, ARM 역시 ARM11을 비롯해 1GHz의 성능과 밀리와트(mW) 급 전력 소모를 나타내는 Cortex-A8을 공급하고 있다. 특히 MID에서 자유로운 인터넷 환경을 구축하기 위해서는 고성능 프로세서와 함께 향상된 그래픽 구현 시스템이 제공되어야 하는데 ARM의 경우 Mali GPU를 통해 모바일 시스템 개발에 필요한 대부분의 기능을 제공하고 있다. Mali GPU는 CPU와 별도로 동작할 수 있는 3D 엔진 소프트웨어로 OpenGL ES와 OpenVG를 지원한다.

스마트폰

PDA에 이동전화 기능이 포함된 PDA폰과 달리 스마트폰은 이동전화에 인터넷 기능을 포함한 것으로 SMS뿐만 아니라 PIMS(Personal Information Management System), MMS(Multimedia Messaging Service), 이메일 전송, MPEG 및 MP3 플레이어 등이 구현됨에 따라 사용자들이 스마트폰에서도 PC에 버금가는 기능들을 체험할 수 있게 되었다. 최근 관심을 끌고 있는 스마트폰 운영체제로는 심비안, 블랙베리, OS X 포터블, 윈도우 모바일, 안드로이드 등을 꼽을 수 있으며 이중 심비안과 윈도우 모바일, 안드로이드가 리더 그룹을 형성하며 경쟁을 펼치고 있다.

휴대폰 개발 프로세스

휴대폰은 프로세서가 무선 프로토콜 처리 기능이 포함된 베이스밴드 프로세서(Baseband Processor)라는 점을 제외하면 모바일 게임기나 내비게이션과 마찬가지로 프로세서와 메모리, LCD, 사운드 칩, 키패드 등이 결합된 디지털 전자제품으로 볼 수 있다. 하지만 이동통신 장비의 특성상 기지국 장비와 RF 신호를 주고받으므로 전파 및 프로토콜과 관련된 까다로운 인증 절차가 따른다.

휴대폰 개발 프로세스는 일반적인 전자제품과 유사하다. 먼저 시장과 고객층을 분석하고 소프트웨어와 하드웨어의 사양 및 가격, 출시 시점을 결정하는 제품기획 단계를 수행한다. 이어서 하드웨어와 소프트웨어, 그리고 기구물 개발 단계를 거쳐 기능과 성능 및 인증 테스트 단계를 통과하면 최종적으로 양산에 들어간다.

제품 기획

제품 기획 단계에는 기획자 외에 하드웨어, 소프트웨어 개발자 및 디자이너가 참여하게 되는데 하드웨어 개발자는 원하는 기능을 구현하기 위해 적절한 부품을 찾아보고 사용 가능성, 납기, 가격 등을 확인한다. 소프트웨어 개발자는 구현하려는 기능에 대한 검토와 더불어 선정한 기능이 하드웨어에서 지원하는지를 하드웨어 개발자와 협의한다. 디자이너는 기구물 형태, 재질 등이 하드웨어 부품 배치와 전파 감도에 영향을 미치지 않는지를 하드웨어 개발자와 협의하고 실물 형상을 검토하기 위해 목업(Mock up)을 제작한다.

하드웨어 설계 및 제작

하드웨어의 설계 및 제작은 회로 설계, 보드 제작, 검토, 완료로 세분화된다. 회로 설계 단계에서는 RF 엔지니어와 베이스밴드 엔지니어로 분류된 하드웨어 개발자에 의해 베이스밴드 프로세서 제조사에서 제공하는 레퍼런스 회로도를 참조해 <화면 1>의 EDA 툴 같은 전문 설계 툴로 회로도를 작성한 후 보드 제작을 위해 PCB Artwork 담당자에게 전달한다. PCB Artwork 담당자는 PCB 제작을 위해 RF 성능을 고려해 부품의 배치와 연결선의 경로를 결정하는 Artwork 작업을 수행한다.

<화면1> PowerPCB를 이용한 PCB 설계

이후 PCB가 완성되면 부품과 함께 SMT(Surface Mount tech/nology) 업체에 전달해 PCB 위에 부품을 납땜함으로써 보드를 완성한다. SMT 작업은 PCB 위에 납 분말을 도포한 후 부품을 올려놓고 뜨거운 열풍으로 납땜하는 방법으로 이뤄진다. SMT 작업이 완료되면 육안검사와 더불어 전원을 인가해 쇼트나 단락의 문제가 없는지를 확인한다. 소프트웨어 개발자는 보드의 검증을 위해 부트로더를 이용해 부품을 테스트하는 코드를 작성함으로써 테스트를 수행한다.

소프트웨어 개발 및 테스트

소프트웨어 개발자는 베이스밴드 칩 제조업체에서 소스 코드 형태로 제공하는 레퍼런스 보드에 대한 소프트웨어 패키지를 이용해 필요한 기능을 구현한다. 베이스밴드 칩 제조사에서 권장하는 레퍼런스 보드와 유사한 방법으로 하드웨어를 설계한 경우에는 GPIO 및 메모리 매핑 부분과 LCD 드라이버만 수정하면 초기화면을 띄울 수 있다. 휴대폰 UI의 경우 BREW나 WIPI와 같은 표준 미들웨어를 이용하기도 하지만 대부분 독자적인 UI 시스템을 개발해 사용한다. WAP 브라우저나 게임과 같은 콘텐츠들은 써드파티 업체에서 라이선스를 받아 장착하는데 소스 코드가 제공되지 않으므로 상호 인터페이스를 잘 정의하고 긴밀한 협의를 거쳐 진행된다.

개발 단계에서는 테스트를 전담하는 인력에 의해 수많은 검증 과정을 거쳐 소프트웨어 안정성과 신뢰성을 검증한다. 가이드북에 따라 모든 항목을 반복 테스트한 후 결과를 개발자에게 전달해 오류나 버그가 수정될 수 있게 한다. RF 프로토콜과 Call에 관련된 소프트웨어 기능들은 공인 인증기관들에 의해 정해진 규격에 따라 인증절차를 거치게 된다. 휴대폰이 사용되는 지역의 통신사업자들도 자체적인 인증규격을 가지고 있으므로 최종적으로는 사업자의 인증과정을 다시 한 번 거쳐야 한다.

기구물 제작

케이스로 대표되는 기구물은 키패드, 버튼, 커버 등으로 구성된다. 기구물은 고객이 상품을 평가하는 첫 번째 요소이므로 제품의 상품성을 높이기 위해 최근에는 외부의 검증된 상품 디자이너를 참여시켜는 등 품질 향상에 노력하고 있다. ID(Industrial Design)는 손으로 그린 스케치를 2D 이미지로 변환하고 최종적으로는 3D로 렌더링한 디자인 프로파일을 얻어 최종 휴대폰 디자인을 결정하는 작업이다. ID 작업에 대한 실물 검토를 위해 목업 업체에 시안을 의뢰하기도 하는데 이 과정에서 ID 결과물을 플라스틱 등으로 제작해 디자인의 완성도를 실물로 확인할 수 있다.

기구 설계 작업이 끝나면 결과물을 가지고 대량 생산을 할 수 있도록 금형 설계를 진행하는데 금형 설계자는 품질을 고려해 금형을 설계한다.

제품 검증

휴대폰은 특성상 작은 하자에도 큰 문제를 발생시킬 수 있으므로 기능 테스트와 성능 테스트, 신뢰성 테스트, 인증으로 이어지는 매우 철저한 검증 작업이 요구된다. 이중 가장 먼저 수행하는 기능 테스트는 제품의 정상 동작 여부를 확인하는 과정으로 기능 테스트를 통과하면 제품의 성능을 확인하고 이를 극대화시키는 성능 테스트를 수행한다. 제품을 사용하는 소비자의 다양한 실제 환경을 고려한 신뢰성 테스트까지 마치면 공인 인증기관을 통해 CDG-1, CDG-2, CDG-3 인증을 의뢰한다. 여기서 CDG-1은 하드웨어 성능에 대한 인증이고 CDG-2는 통신 프로토콜과 같은 소프트웨어 성능에 대한 인증이며 CDG-3은 기지국 장비 연동 성능에 대한 인증이다.

양산

제품 검증까지 완료되면 개발 제품을 대량으로 생산하는 양산을 진행한다. 양산이 시작되기 전에 개발팀과 협력해 품질 관리에 걸림돌이 되는 부분을 수정하는데, 양산 전에 미처 발견하지 못한 문제점들에 대해서는 양산을 진행하면서 빠른 시간 안에 수정 또는 개선하는 작업을 병행해 진행한다. 대부분 소프트웨어와 관련된 수정이므로 제작사 홈페이지나 AS센터를 통해 무상 업그레이드를 진행한다.

휴대폰 개발 기술

휴대폰 개발 기술은 빠르게 진화하고 있으며 제품 라이프 사이클도 6개월 이내로 짧아지고 있다. 모든 제조업체들은 가장 성능이 좋으면서 가격 경쟁력이 있는 부품을 선택하고자 노력하고 있으며 초대형 부품 회사들이 모든 휴대폰 제조사를 상대로 부품을 공급하고 있으므로 경쟁사들의 최신 휴대폰 성능이나 사양은 크게 차이나지 않는 것이다.

베이스밴드 프로세서

휴대폰의 가장 핵심 부품인 베이스밴드 프로세서는 전 세계 시장의 95% 이상이 ARM 코어를 기반으로 DSP를 내장한 ASIC 형태의 제품이다. ARM 코어는 ARM9이 주로 사용되었으며, 최근에는 ARM11과 ARM9이 듀얼로 결합한 Conversions용 제품의 출시가 늘고 있다. 함께 포함된 DSP는 주로 2D나 3D 처리와 같은 그래픽 프로세서의 역할과 이동통신 프로토콜 처리를 담당하는 모뎀 역할을 수행한다. 내부 버스나 외부 버스 구조는 일반적인 ARM 아키텍처와 동일하다.

메모리

휴대폰에서는 공간 집적도를 높이기 위해 PSRAM(Pseude-SRAM), SDRAM(Synchronous-DRAM), NAND Flash를 결합해 하나의 패키지로 구성한 MCP(Multi-Chip Package) 메모리를 사용한다. 이중 PSRAM은 NAND Flash 기반의 부팅 과정에서 복사된 커널 이미지를 실행하는 용도로 사용되는데 DRAM에 충전회로를 하나의 패키지로 결합해 SRAM처럼 만들었다고 해서 PSRAM이라 부른다. NOR Flash보다 값이 저렴해 많이 채택되는 NAND Flash는 읽기 시간이 상대적으로 길다는 단점이 있으나 쓰기 효율은 좋은 편이므로 카메라 사진이나 동영상 데이터, MP3와 같은 데이터를 저장하는 용도로 많이 사용한다.

표준 DRAM에 비해 4배 이상 빠른 속도로 동작하는 SDRAM은 행 주소와 열 주소로 나눠 진 Matrix 형태의 주소 방식을 사용한다. 따라서 한 주소를 접근하려면 2회에 걸쳐 어드레싱해야 하므로 타이밍이 복잡한 회로가 되지만, 주소 개수를 절반 가까이 줄일 수 있어 칩의 핀 개수가 줄어드는 이점이 있다. 그 밖에 SDRAM은 Interleaved Cell 뱅크와 Burst 모드를 제공하는데 Interleaved Cell은 두 개로 분리된 셀 뱅크가 동시에 동작할 수 있다. 그러므로 연속되는 정보의 흐름이 뱅크 사이에서 변화하면서 진행될 수 있어 전체 메모리 사이클을 줄이고 전송 속도를 높일 수 있다. Burst 모드는 프로세서가 시작 주소만 지정하면 자동으로 연속적인 나머지 주소 공간을 접근할 수 있게 하는 기능이다. 따라서 메모리 접근 사이클에서 주소 지정에 따른 주소 로딩 시간을 단축시켜 대용량 데이터의 고속 전송이 이뤄질 수 있다.

LCD 모듈 인터페이스

LCD는 LDI(LCD Driver ID)를 통해 프로세서와 연결되는데 LDI는 프로세서가 보내는 데이터를 LCD 패널에 뿌려주는 기능을 수행한다. 프로세서는 LDI에 데이터와 명령을 보내는 방식으로 원하는 화면을 출력하는데, 일반적으로 프로세서와 LDI 사이에 데이터나 명령을 송수신하는 방법에는 CPU 인터페이스와 RGB 인터페이스가 적용된다.

먼저 CPU 인터페이스 방식에서는 LDI에 포함된 프레임 버퍼에 데이터를 전송하면 LDI가 그 안에 저장된 이미지 데이터를 주기적으로 LCD 패널에 뿌려 주므로 프로세서 입장에서는 LCD에 표시되는 그림을 변경하고 싶을 경우에만 LDI에 새로운 이미지 데이터를 보내 주면 된다. 따라서 LCD 화면을 관리하는 데 그다지 큰 부하가 발행하지 않는다. 그에 반해 RGB 인터페이스 방식은 프로세서가 프레임 버퍼를 만들어 두고 그 안에 저장된 이미지를 주기적으로 LDI로 전달해야 한다. 따라서 LCD 화면에 보이는 그림이 변하지 않는 상황에서도 동일한 데이터를 LDI로 주기적으로 전송해야 하는 탓에 부하가 많이 걸린다. 일반적으로 RGB 인터페이스 방식은 LCD 컨트롤러를 내장한 고속 프로세서에서 사용되므로 동영상 디스플레이와 같이 빠르게 변화하는 화면을 LCD로 출력하는 경우에 적합하다.

카메라

CIS(Camera Image Sensor), ISP(Image Signal Processor), 컨트롤러로 구성된 카메라 모듈은 이미 휴대폰의 필수 디바이스로 자리 잡았다. CIS는 렌즈로 입사된 이미지를 디지털 데이터로 변환하는 센서로 인간의 망막과 같은 역할을 한다. ISP는 CIS에서 변환한 디지털 데이터에 여러 가지 연산을 수행하는데 명도, 채도, 조도 등을 조작해 인간의 눈에 비치는 것과 가장 유사한 이미지를 만들어 낸다. 최근에는 카메라 컨트롤러에 ISP가 포함되기도 한다. 캡처, JPEG 압축과 변환, 확대, 축소, 오버레이 등 카메라 기능을 제어하고 LCD로 이미지를 출력하는 기능은 카메라 컨트롤러가 수행하는데 이 역시 베이스밴드 프로세서에 포함되기도 한다. 하지만 별도의 컨트롤러를 사용하는 것이 카메라의 성능을 더 높일 수 있으므로 외부에 별도로 장착하는 경우가 많다.

카메라 컨트롤러는 카메라 기능이 사용되지 않는 동안에는 프로세서에서 전송한 이미지가 그대로 LCD에 출력되도록 By-pass 모드로 설정되며, 카메라가 동작할 때에는 카메라 모듈로부터 입력된 데이터를 LCD로 출력하는 캡처, 프리뷰, OSD(On Screen Display) 모드 중 하나의 상태로 설정된다. 캡처 모드는 사진 촬영에 사용되는데 ISP로부터 전송 받은 데이터를 JPEG로 인코딩해 베이스밴드 프로세서로 보낸다. 프리뷰 모드는 카메라 렌즈에 잡힌 모습을 그대로 LCD로 보내며, OSD는 배경 그림을 놓고 촬영한 것과 같은 오버레이 기능이 필요할 때 사용한다.

오디오

휴대폰 환경에서 사운드 포맷은 음성 통화를 위한 음성 코덱인 보코더(Vocoder)와 MP3나 AAC(Advanced Audio Coding)와 같은 일반적인 사운드를 처리하는 오디오 코덱, 그리고 MIDI와 같이 음을 만들어 내는 합성음(synthetic audio) 코덱으로 구분된다. 음성 코덱으로는 QCELP(QualComm Code Excited Linear Predictive Coding)와 AMR(Adaptive Multi Rate)이 대표적이다. AAC는 MPEG-2의 오디오 레이어를 가리키는 96Kbps 정도의 가변 비트율을 지원하므로 고정 비트율인 MP3의 128Kbps보다 압축률이 높은 편이다. 전자악기의 연주 정보 등을 상호 전달하기 위해 정해진 하드웨어 및 통신 프로토콜의 국제적 표준규격인 MIDI는 악기 종류, 음색 수, 음색 번호, 음의 길이나 세기, 효과음 등의 여러 가지 요소를 디지털화함으로써 전자음악의 보급에 많은 기여를 했으며 전자악기, 컴퓨터, 휴대폰 등에서 광범위하게 사용되고 있다.

안테나

최근의 휴대폰 디자인은 더 얇고 가벼우며 작은 형태를 지향하고 있다. 기존의 Stubby 안테나와 같은 돌출형 구조는 휴대폰의 디자인에 많은 제약을 줄 수 있어 최근에 출시되는 대부분의 신형 휴대폰은 내장형 안테나(Intenna)를 장착해 출시되고 있다. 특히 휴대폰의 두께가 10mm 이하로 얇아지면서 안테나의 소형화는 더욱 중요한 이슈가 되었다.

최근에는 DMB, GPS, WLAN 등의 서로 다른 주파수 대역의 통신 서비스를 모두 지원하는 휴대폰까지 등장하고 있다. 따라서 하나의 휴대폰에 여러 개의 안테나가 장착되거나, 동시에 여러 주파수 대역을 다룰 수 있는 멀티밴드(Multiband) 안테나를 적용하고 있다.

윈도우 모바일 아키텍처

퀄컴은 MSM7xxx 베이스밴드 프로세서에 ARM11과 ARM9을 듀얼로 집적해 윈도우 모바일이나 임베디드 리눅스를 응용 운영체제로 추가 설치할 수 있게 지원한다. <그림 2>에서 보는 것처럼 기존의 휴대폰 소프트웨어들은 ARM9과 가상화 운영체제 상에서 레거시 운영체제 에뮬레이션을 통해 동작하고, 응용프로그램은 ARM11 기반의 응용 운영체제 상에서 동작하는 형태다.

윈도우 모바일의 경우는 디바이스 드라이버를 포함한 주요 휴대폰 서비스 부분은 퀄컴에서, 윈도우 커널을 포함한 응용 부분은 마이크로소프트에서 각각 제공하고 있다.

<그림2> MSM7xxx 윈도우 모바일 아키텍처

심비안

심비안은 마이크로소프트를 견제하기 위해 사이온, 모토롤라, 노키아, 파나소닉, 소니, 에릭슨, 삼성전자, 지멘스 등의 8개 업체가 공동으로 설립한 기업의 이름이자 운영체제의 이름으로 사이온이 현재 최대 주주이다. 객체지향 개념으로 설계된 심비안은 휴대폰 서비스에 최적화된 스마트폰 플랫폼으로 C++로 구현되어 있다. 마이크로 커널 아키텍처 기반으로 디바이스 드라이버 계층은 윈도우 모바일과 같이 물리 계층과 논리 계층으로 구분되어 있으며, 우수한 32비트 RTOS 능력을 갖춰 창을 여러 개 띄워 놓고 편집 작업을 할 수 있다. 특히 메모리나 저장장치 등의 리소스가 부족하거나 통신이 불안정한 환경에서도 신속하게 사용자 데이터로의 접근이 가능하도록 지원한다.

<그림3> 심비안 아키텍처

파일시스템을 배제한 GUI 개발

임베디드 리눅스나 윈도우 모바일과 같은 스마트폰 환경과 달리 일반적인 휴대폰 환경은 파일시스템을 사용하지 않고 소스 코드 상에 BMP나 WAV, 심지어 DSP 펌웨어까지 C 언어의 배열 형태로 변환해 사용하는 경우가 있다. 이러한 방법은 파일시스템에 대한 접근을 필요로 하지 않으므로 빠른 결과를 얻을 수 있고, 부팅시 파일시스템이 초기화되지 않은 상태에서도 효과음 처리나 LCD에 관련 이미지를 출력하는 등의 작업을 할 수 있다는 장점을 지닌다. 단 커널 사이즈가 커지는 것이 단점이다.

BMP 이미지 적용

일반적으로 스마트폰에서는 GUI를 만들 때 그림 이미지인 BMP 파일을 이용해 버튼이나 대화상자를 만든다. 하지만 BMP 파일을 C 언어의 배열 형태로 변환해 커널 이미지에 포함하면 파일시스템에 대한 접근 없이 빠르게 LCD로 해당 이미지를 출력할 수 있어 성능을 중요시하는 영역에서는 효과적이다. LCD가 5:6:5 포맷을 사용하는 16비트 컬러를 사용한다면 기존 BMP 이미지에서 그림을 나타내는 부분을 워드(16비트) 단위로 읽어 16진수로 변환하는 프로그램을 사용하면 된다. 이런 프로그램은 인터넷에서 무료로 구할 수 있으므로 직접 작성할 필요가 없다. <리스트 1>은 <화면 2>를 C 언어 배열로 변환한 결과이다.

<화면2> BMP 이미지

<리스트 1> BMP 이미지를 C 배열로 변환한 결과

unsight char logo[1024] =
{
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF,
0xFF , 0xFF , 0xC0 , 0x5D , 0x4B , 0x42 , 0xB0 , 0x88
//중략
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
};

WAV 적용

휴대폰 부팅 과정에 효과음을 넣기 위해 WAV 포맷을 많이 사용하며, WAV 파일도 C 언어 배열로 변환해 사용할 수 있다. 일반적으로 WAV 포맷의 경우 ARM 코어에서 코덱을 제공하므로 I2S(Inter IC Sound)를 사용해 WAV 데이터를 DAM Transfer로 전송하면 된다. WAV 파일 변환 역시 BMP 파일 변환과 동일하다.

폰트 적용

GUI에서 글자를 출력하려면 폰트 파일이 필요하다. 일반적으로 폰트 파일은 상업용 파일을 많이 사용하므로 제품 개수당 로열티가 있다. 또한 사용하는 언어에 따라 수 KB에서 수십 MB 정도의 용량을 가지므로 필요한 폰트만 선택할 필요가 있다. 보통 .ttf 확장자를 갖는 트루타입 폰트를 BMP 파일 변환과 유사한 방법으로 변환해 사용한다.

최근 지식경제부는 ‘지식·혁신 주도형 산업 강국으로의 전환’을 비전으로 모바일 산업을 초일류 주력산업으로 선정하고, 5대 주력 기간산업과 IT 융합을 위한 기술 개발을 통해 경쟁력을 지속적으로 확보하겠다는 전략을 발표했다. 이미 세계 시장과 산업은 급변하고 있으며 세계 모바일 시장에서 모바일 산업의 지속적인 경쟁력을 유지하고 우위를 확보하기 위해서는 모바일 분야 개발자들의 선택과 집중이 어느 때보다 절실한 시점이다.

제공 : DB포탈사이트 DBguide.net

출처명 : 한국마이크로소프트 [2008년 5월호]

+ Recent posts