2011/12/27

Usefull C macros

By couple of years of professional programming, I have collected some useful C macros which I use on daily basis. I don’t imagine programming without them. I figure out that not many people use such macros, or even if they use similar ones, their version is vulnerable for macro parameter side effects and signed overflow hacks.

Because my macros are much better ;) I decided to share. Some of them are my pure creation, some of them are copied for other places (like Linux kernel). Because of that I am obliged to release them under GPL (I hope that nobody will sue me for 4 line of C code even if he/she came onto the same obvious idea).

Some of those macros are just renaming for more robust code when you plan to migrate between different compilers. Some other are useful during C kind object-like programming. At least  some of them save some repeat coding ;)

/**

* Macro mask the "unused parameter" warning when using -Wall -Wextra compiler
* options. Those compiler options should be used to prevent typical C coding
* mistakes while unused macro allows to silent the waring when we really what
* to not use all of function parameters
*/#if defined(__GNUC__)
# define unused(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define unused(x) /*@unused@*/ x
#else
# define unused(x) x
#endif

/** likely/unlikely macro is to provide the compiler with branch prediction
* information. By explicitly giving such info you may instruct compiler
* to produce code optimized for more probable use case. As result compiler
* will move the code sections for full utilization of CPU instruction cache
* and jump elimination (CPU pipeline flush).
*/
#if __GNUC__ >= 3
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#warning Compiler is not supporting all extensions, some optimization will have no effect
#define likely(x) (x)
#define unlikely(x) (x)
#endif

/** always_inline tells GCC to inline the specified function regardless of whether optimization is enabled.
* deprecated tells you when a function has been depreciated and should no longer be used. If you attempt to
use a deprecated function, you receive a warning. You can also apply this attribute to types and

variables to encourage developers to wean themselves from those kernel assets.
* __used__ tells the compiler that this function is used regardless of whether GCC finds instances of calls

to the function. This can be useful in cases where C functions are called from assembly.
* __const__ tells the compiler that a particular function has no state (that is, it uses the arguments

passed in to generate a result to return).
* warn_unused_result forces the compiler to check that all callers check the result of the function. This

ensures that callers are properly validating the function result so that they can handle the appropriate

errors. */
#if __GNUC__ >= 3
#define __always_inline__ __attribute__((always_inline))
#define __deprecated __attribute__((deprecated))
#define __attribute_used__ __attribute__((__used__))
#define __attribute_const__ __attribute__((__const__))
#define __must_check __attribute__((warn_unused_result))
#else
#define __inline__
#define __deprecated
#define __attribute_used__
#define __attribute_const__
#define __must_check
#endif

/**
* Prefetch portable macros for cache preload by buildin uC instructions.
* This macro allows to produce more optimized code on CPU equipped with cache.
* Placing prefetch instruction before code section that use some data may
* influence on execution time, since procesor will load those data to the
* cache before the instructions request them. Without prefetch, data
* load will be done when instructions require mentioned data, while CPU will
* be staled until those data will be loaded to cache.
*/
#if __GNUC__ >= 3
#define prefetch(x) __builtin_prefetch(x)
#else
#define prefetch(x)
#endif

/**
* Restrict keyword can be used to variables which are pointers and which points
* to content not accessible by other pointers or parameters.
* The main purpose of this keyword is to instruct the compiler that content
* under the particular pointer will not be changed by other way than explicit
* pointer reference. This allows the compiler to produce more optimized code.
*
* Without restrict keyword, compiler have to assume that any two pointers may
* point to the same memory location. Because of that compiler cannot reuse
* temporary values since it may be invalidated by any other indirect (pointer)
* write access.
*/
#if __GNUC__ >= 3
#define restrict __restrict__
#else
#define restrict
#endif

/** \note gcc-4.0.1/gcc/Return-Address.html On some machines it may be
* impossible to determine he return address of any function other than the
* current one; in such cases, or when the top of the stack has been reached,
* this function will return 0 or a random value. In addition,
* __builtin_frame_address may be used to determine if the top of the stack
* has been reached, for compatibility our macro calleraddr returns only the
* return addres of current function */
#if __GNUC__ >= 3
#define calleraddr() __builtin_return_address(0)
#else
#define calleraddr() NULL
#endif

/**
* Common macro that allows to calculate the offset of field in structure
*
* @param _type Type of parent
* @param _member Name of member inside parent
*
* @return Offset in bytes (size_t) of member from the beginning of parent.
*/
#ifdef __compiler_offsetof
#define offsetof(_type,_member) __compiler_offsetof(_type, _member)
#else
#define offsetof(_type, _member) ((size_t) &(((_type *)NULL)->_member))
#endif

/** Common macro that allows to get size of member in structure or union */
#define sizeoffield(_type, _member) (sizeof(((_type *)NULL)->_member))

/**
* Common macro that allows to calculate pointer to parent,
* from pointer to member, name of the member inside parent and parent object type
* Using of temporary pointer _mptr is necessary to prevent macro side effects for
* operands like pointer++
*
* @param _prt Pointer to member
* @param _type Parent object type
* @param _member Name of the member inside parent object
*
* @return Pointer to parent
*/
#define container_of(_ptr, _type, _member) ({ \
const typeof( ((_type *)0)->_member ) *_mptr = (_ptr); \
(_type *)( (char *)_mptr - offsetof(_type,_member) );})

/*
* Common min macro with strict type-checking,
* returns the smaller value from two operands
*
* Strict type checking in important aspect of secure code,
* (sign type mixed checking is common source of exploitable bugs).
* Using of temporary values is necessary to prevent macro side effects for
* operands like variable++
*
* @param _x First value
* @param _y Second value
*
* @return Smaller of two passed values
*/
#define min(_x, _y) ({ \
typeof(_x) _min1 = (_x); \
typeof(_y) _min2 = (_y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })

/*
* Common max macro with strict type-checking,
* returns the greater value from two operands
*
* Strict type checking in important aspect of secure code,
* (sign type mixed checking is common source of exploitable bugs).
* Using of temporary values is necessary to prevent macro side effects for
* operands like variable++
*
* @param _x First value
* @param _y Second value
*
* @return Greater of two passed values
*/
#define max(_x, _y) ({ \
typeof(_x) _max1 = (_x); \
typeof(_y) _max2 = (_y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })

/**
* Macro used to calculate the ceiling(x/y), macro is type sensitive.
* Macro cannot be used with floating point types,
* for those please use ceil function from math.h
*
* @param _x dividend
* @param _y divisor
*
* @return ceil(_x/_y) with the same type as _x operand
*/
#define ceil_div(_x, _y) ({ \
typeof(_x) __x = (_x); \
typeof(_y) __y = (_y); \
(void) (&__x == &__y); \
typeof(_x) _rem = __x % __y; \
typeof(_x) _div = __x / __y; \
(_rem > 0) ? (_div + 1) : _div; })

/**
* Version of ceil_div without strict type checking, use with care
* Warning this version has common macro side effects for operands which use
* ++ or --
*/
#define ceil_div_nocheck(x, y) (((x) / (y)) + (((x) % (y)) ? 1 : 0))

/**
* Version of min without strict type checking, use with care
* Warning this version has common macro side effects for operands which use
* ++ or --
*/
#define min_nocheck(x, y) (((x) < (y)) ? (x) : (y))

/**
* Version of cmax without strict type checking, use with care
* Warning this version has common macro side effects for operands which use
* ++ or --
*/
#define max_nocheck(x, y) (((x) > (y)) ? (x) : (y))

/**
* Macro clamps the value to the given range, macro performs strict type checking.
*
* Strict type checking in important aspect of secure code,
* (sign type mixed checking is common source of exploitable bugs).
* Using of temporary values is necessary to prevent macro side effects for
* operands like variable++
*
* @param _val Clamped value
* @param _min Lower bound
* @param _max Upper boud
* @return Clamped value
*/
#define clamp(_val, _min, _max) ({ \
typeof(_val) __val = (_val); \
typeof(_min) __min = (_min); \
typeof(_max) __max = (_max); \
(void) (&__val == &__min); \
(void) (&__val == &__max); \
__val = __val < __min ? __min: __val; \
__val > __max ? __max: __val; })

/**
* Macro clamps the value to the given range using val param type
*
* This macro does no type checking and uses temporary variables of whatever
* type the input argument 'val' is. This is useful when val is an unsigned
* type and min and max are literals that will otherwise be assigned a signed
* integer type.
*
* @param _val Clamped value
* @param _min Lower bound
* @param _max Upper boud
* @return Clamped value
*/
#define clamp_val(_val, _min, _max) ({ \
typeof(_val) __val = (_val); \
typeof(_val) __min = (_min); \
typeof(_val) __max = (_max); \
__val = __val < __min ? __min: __val; \
__val > __max ? __max: __val; })

/**
* Macro returns number of table elements
*
* @param _table Table pinter
* @return Number of table elements, the return type is size_t
*/
#define element_cnt(_table) (sizeof((_table)) / sizeof((_table)[0]))

/**
* Macro rounds up the address to platform basic type alligment rules.
* As an example on 32 bit platforms it will return address aligned up to 32 bits.
*
* @param _addr Unaligned address
* @return Aligned address
*/
#define addr_allign(_addr) \
( (void*)(divtop_nocheck((unsigned long)(_addr), sizeof(long)) * sizeof(long)) )

/**
* Macro rounds up the size to platform basic type alligment rules.
* As an example on 32 bit platforms it will return size aligned up to 32 bits.
*
* @param _addr Unaligned size
* @return Aligned size
*/
#define size_allign(_size) \
( (size_t)(divtop_nocheck((size_t)(_size), sizeof(long)) * sizeof(long)) )

/**
* \brief Malloc with out of memory protection and memory cleaning
*/
#define safe_alloc(_type) ({ \
_type *ptr = malloc(sizeof(_type)); \
assert(NULL != ptr); \
memset(ptr, 0, sizeof(_type)); \
ptr; })

/**
* \brief free with "reference after free" protection
*/
#define safe_free(_ptrtype) \
do { \
memset(_ptrtype, 0xAB, sizeof(*(_ptrtype))); /* 0xAB is a safe patern */ \
free(_ptrtype); \
(_ptrtype) = NULL;\
} while(0)

/**
* Compile-time assertion useful for check done during the compilation time.
* It provides similar functionality to assert macro (which is calculated
* during the execution time). static_assert is evaluated during the compilation
* stage (not during the preprocessing). Because of that it may be used with
* conjunction to cost variables or C expresions like sizeof(type).
*
* \remarks It relies on 'unused' macro and assumes that 'unused' macro
* adds "UNUSED_" prefix to name. It might generate "unused variable"
* warning in case of disabled 'unused' macro.
*/
#define static_assert(expr) \
static const char unused(unique_name [(expr)?1:-1]) = {'!'}
#define unique_name make_name(__LINE__)
#define make_name(line) make_name2(line)
#define make_name2(line) constraint_ ## line

2011/12/20

Modular embedded development with mbeddr C previewed

Check this mbeddr C Extension Guide. It seem to be a try to deal with embedded development problems which came from C lang.

2011/12/15

Implicit type casting in C - aka signed overflow bug

I just made small discovery, that any ANSI C compiler by default don't warn about implicit conversions. This convention accustomed many programers to freely use of signed and unsigned variables. The most common practice is to pass the signed variable as a parameter of function which expect the unsigned one. Another bad habit is to compare the signed and unsigned variables. This is commonly known source of bug (at least in hacker world) ;)

For instance:
$ cat main.c
#include
#include

void func(size_t param)
{
    printf("done %zu\n", param);
}

int main()
{
    int param = -1;
    func(param);
    return 0;
}

$ gcc -o main -Wall -Wextra main.c

$ gcc -o main -Wall -Wextra -Wconversion main.c
main.c: In function 'main':
main.c:12: warning: passing argument 1 of 'func' with different width due to prototype

As we see even with -Wall -Wextra compilation parameters, there will be no compilation warning. The warning will appear only if we explicitly request -Wconversion option.

Signed param  will be passed to func with implict cast to unsigned type. This in certain circumstances may cause serious security flaw. In code above we will get 18446744073709551615 (on X64) as a result instead of -1. (not very insecure but I'm sure that you get the base).

More destructive effect of this rule can be presented by following code:

void func(size_t param)
{
   if(param < 5)
      printf("param less then 5\n");
   else
            printf("param grater then 5\n");
}

In we run this code we will see "param greater then 5", which is not what we expect, since we pass -1 as function param. This can happen if we don't make enough attention for the variable types before passing it to function. In this particular case if we want to remain the original param value to be signed, we have to make additional value checking code (assert) before we call the func.

It is worth to mention that with compiler flags -Wall -Wextra we will warn about signed/unsigned compare operation, while it will not warn about implicit type casting for function params. Like in below code, we will get warning for line with "if" while we will not get a warning for line with func(-1, 5).

void func(size_t param, size_t limit)
{ 
   if( param > limit ) 
      printf("greater\n");
}

int main()
{
    int param = -1;
    unsigned int limit = 5;

    if( param > limit )
        printf("greater\n");

    func(-1, 5);

    return 0;
}

2011/11/29

sig_atomic_t

I found following document for GNU libc. This particular chapter describes how to write the signal procedure. However it may seem to be straight forward, there are many rules which have to be followed.

For instance to exchange the data between the signal handler and user code, up to now I used the int type. This method is not portable and may be unsafe. The reason is because the int type may have from 16 to 64 bits, depending on architecture and types model (for more info please read this document).
The obvious fact is that your int variable access may be atomic on one platform, while non atomic on other.
To solve this issue, you need to use the sig_atomic_t (here is short info) This type does not have strictly defined number of bits but it guarantee that read/write access will be done in atomic manner. Therefore it can be used to exchange the data between the signal handler and user code.

This type does not have associated increment/decrement functions (opposite to similar atomic_t in kernel). Because of this you cannot base on fact that increment operation of the sig_atomic_t variable will be atomic.
The sig_atomic_t type doesn't provide atomic updates. The ++ operator may read the object, and then store a new value on some architectures. That two-access transaction isn't atomic. A signal handler may be invoked between the read and write, and that signal handler may read the old value and act on it or it may store a new value which is about to be overwritten.


2011/11/18

Three 0-day bugfixes from M$

It seems that recent fixes from M$ are very interesting. (one for IP stack!)

2011/11/17

An Analysis of Underground Forums

If you wonder how officials sees the underground world of cyber crimes you may be interested for that document.

Neverwet

Did you wonder why your clothes making dirty ? Or how the Goretex fabric is working ?
Everything is about the surface tension, and this product can enhance it to the limits. This can be used for instance to make your clothes "water repellent".



DARPA = Skynet ?

Did you heard about Darpa Bigdog ? Well, now we have the Ostrich
The world becomes a creepy place :O


2011/11/16

Programing font

Looking for perfect programming font ? here is the whole site about that.

2011/05/28

Lock-free vs Wait-free

Ostatnimi czasy interesuje się algorytmami lock-free i wait-free. Dla ciekawych podrzucam kilka artykułów oraz krótka notkę wprowadzająca.

To ensure consistency of a shared data object in a concurrent environment,
the most common method is mutual exclusion, i.e. some form of locking. Mutual
exclusion degrades the system’s overall performance as it causes blocking,
i.e. other concurrent operations can not make any progress while the access to
the shared resource is blocked by the lock. Mutual exclusion can also cause
deadlocks, priority inversion and even starvation.
In order to address these problems, researchers have proposed non-blocking
algorithms for shared data objects. Non-blocking algorithms do not involve mutual
exclusion, and therefore do not suffer from the problems that blocking could
generate. Lock-free implementations are non-blocking and guarantee that regardless
of the contention caused by concurrent operations and the interleaving of
their sub-operations, always at least one operation will progress. However, there
is a risk for starvation as the progress of some operations could cause some other
operations to never finish. Wait-free algorithms are lock-free and moreover
they avoid starvation as well, as all operations are then guaranteed to finish
in a limited number of their own steps. Recently, some researchers also include
obstruction-free [3] implementations to the non-blocking set of implementations.
These kinds of implementations are weaker than the lock-free ones and do not
guarantee progress of any concurrent operation.

http://www.cs.brown.edu/~mph/Herlihy93/herlihy93methodology.pdf
http://www2.research.att.com/~bs/lock-free-vector.pdf
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.140.4693&rep=rep1&type=pdf
http://www.cse.chalmers.se/~tsigas/papers/NBMalloc-algorithmica.pdf

2011/04/01

Kod powrotu z obsługi sygnału

Wczoraj natknęliśmy się w naszej aplikacji na problem odwołania do nieprawidłowego segmentu pamięci przy obsłudze sygnału. Początkowo wyglądało to jak próba wykonywania kodu ze stosu. Jak się okazało jest to standardowe rozwiązanie stosowane w celu powrotu wywołania do Kernela po zakończeniu procedury obsługi sygnału. Problem polegał na niedeterministycznym wykonaniu takiego samomodyfikującego się kodu.

Jak narazie nie mam pełnego statusu tego problemu. Opisze problem jak tylko będę w stanie bez wątpliwych założeń go wytłumaczyć ;)

Więcej na temat wstrzykiwania kodu na stos przy powrocie z procedury obsługi sygnału, można przeczytać tutaj

A tutaj zamieszczam link do małego kursu wstawek asemblerowych z wykorzystaniem GCC.

2011/03/22

Bionic - Android C like library

Bionic to implementacja libC (lub przynajmniej tak powinna być kojarzona) w Android. Głównymi powodami stworzenia niezależnej implementacji były:
- pozbycie się licencji GNU z libC
- uszczuplenie i przyśpieszenie implementacji

Bardzo przypadły mi do gustu rozwiązania użyte w Bionic, jako że zajmuję się rozwiązaniami embedded. Z krótkim opisem można się zapoznać tutaj

Ciekawe jest że autorzy uznali np międzyprocesowe semafory i zmienne warunkowe za zbyt "ciężkie" i postanowili nie implementować ich obsługi w wywołaniach POSIX-like.

Ciekawe są również następujące stwierdzenia "Note that Posix mandates a minimum of 128 (thread local storage) slots, but we do not claim to be Posix-compliant"

Jeszcze innym ciekawym rozwiązaniem są tzw property, coś co starałem się wprowadzić w naszej firmie. "Android provides a simple shared value/key space to all processes on the system. It stores a liberal number of 'properties', each of them being a simple size-limited string that can be associated to a size-limited string value".

Najciekawsze jest jednak poniższe stwierdzenie "Bionic intentionally does not provide support for System-V IPCs mechanisms, like the ones provided by semget(), shmget(), msgget(). The reason for this is to avoid denial-of-service.". Ciekawe podejście do problemu :)

2011/03/21

Przeziebienie

Z racji mojego przeziębienia, wszystkim chorym dedykuje poniższy motywator:

2011/03/18

Skimming numerów PIN możliwy na kartach chipowych

Skimming numerów PIN możliwy na kartach chipowych: "Czwórka ekspertów zademonstrowała praktyczne możliwości zastosowania skimmingu wymierzonego w karty chipowe – i to zarówno w przypadku układów niechronionej klasy, jak też klasy DDA.


"

2011/03/10

Biblioteka ebookow o Linux

The Linux Documentation Project


http://tldp.org/guides.html

Sygnaly

Przyszedł czas na odświeżenie wiedzy o sygnałach.

http://www.kernel.org/doc/man-pages/online/pages/man7/signal.7.html

Streszczenie:
Sygnały dostarczane do procesu traktujemy jak przerwania w systemie z bezpośrednim dostepem do procesora.
W Linuxie występują 2 rodzaje sygnałów, Standardowe i RealTime. Cytujac zródło:

"Real-time signals are distinguished by the following:
1.  Multiple instances of real-time signals can be queued.  By contrast, if multiple instances of a standard signal are  delivered  while that signal is currently blocked, then only one instance is queued.
2.  If  the signal is sent using sigqueue(2), an accompanying value (either an integer or a pointer) can be sent with the signal.  If the receiving process establishes a handler for this signal using the SA_SIGINFO flag to sigaction(2) then it can obtain  this  data  via the  si_value  field  of  the  siginfo_t  structure passed as the second argument to the handler.  Furthermore, the si_pid and si_uid fields of this structure can be used to obtain the PID and real user ID of the process sending the signal.

3.  Real-time signals are delivered in a guaranteed order.  Multiple real-time signals of the same type are delivered in the  order  they were  sent.   If  different  real-time  signals  are  sent to a process, they are delivered starting with the lowest-numbered signal. (I.e., low-numbered signals have highest priority.)  By contrast, if multiple standard signals are pending for a process,  the  order in which they are delivered is unspecified.

If both standard and real-time signals are pending for a process, POSIX leaves it unspecified which is delivered first.  Linux, like many other implementations, gives priority to standard signals in this case."

Sygnały mogą zostać wysłane do procesu lub wątku. Zazwyczaj funkcje pozwalające wysłać sygnał do wątku posiadają przedrostek pthread- . Sygnał wysłany do procesu zostanie dostarczony do dowolnego z wątków który w danym momencie go nie blokuje. Jeśli wszystkie wątki blokują sygnał skierowany do procesu, pozostanie on nieobsłużony do czasu aż przynajmniej jeden z wątków zezwoli na jego przetwarzanie.
Nalezy pamietać że istnieja 2 pojęcia dotyczące sygnałów, dyspozycje oraz maska. Dyspozycja sygnałów określa czy sygnał ma wykonać domyślna akcje (zależna od sygnału np zakończyć proces lub wykonać core dump), czy należny go zignorować czy  przechwycić/dostarczyć. Natomiast maska pozwala na tymczasowe skolejkowanie sygnału w przypadku dyspozycji dostarczenia, do czasu kiedy nie zostanie wyczyszczona (maska). Sygnał skolejowany nazwany jest sygnałem w stanie "pending".
Dyspozycja jest peer aplikacja, natomiast maski sygnałów są peer watek.

Inną ważną informacją jest to że biblioteka pthread używa 2 lub 3 pierwsze sygnały typu real time, do implementacji jej wewnętrznych usług. Dlatego też należy bezwzględnie używać makra SIGRTMIN aby w aplikacji nie użyć przypadkiem numerów sygnałów wykorzystywanych w bibliotece pthread. Inna rzeczą o której trzeba pamiętać jest to że kernel ogranicza też maksymalna ilość kolejkowanie sygnałów (w zależności od wersji jest do ograniczenie typu system-wide (do 2.6.7) lub user-wide (od 2.6.8)).

Należy pamiętać ze w funkcji obsługi sygnału nie wolno wykonywać dowolnie zdefiniowanego kodu. POSIX wprowadza w tym celu pojęcie Async-"signal-safe" functions.

Następna sprawa są wywołania funkcji systemowych przerwane sygnałami. Wywołania systemowe przerwane sygnałami mogą być automatycznie wznawiane (bez powiadamiania aplikacji o błędzie wywołania) w niektórych przypadkach o ile użyto flagi SA_RESTART w wywoływaniu sigaction lub podobnym.
Następujące funkcje klasyfikują się do wymienionego przypadku:

- read(2), readv(2), write(2), writev(2), and ioctl(2) calls on "slow" devices.  A "slow" device is one where the I/O call may  block for  an indefinite time, for example, a terminal, pipe, or socket.  (A disk is not a slow device according to this definition.)  If an I/O call on a slow device has already transferred some data by the time it is interrupted by a signal  handler,  then  the  call will return a success status (normally, the number of bytes transferred)
- open(2), if it can block (e.g., when opening a FIFO; see fifo(7)).
- wait(2), wait3(2), wait4(2), waitid(2), and waitpid(2).
- Socket  interfaces:  accept(2),  connect(2), recv(2), recvfrom(2), recvmsg(2), send(2), sendto(2), and sendmsg(2), unless a timeout has been set on the socket (see below).
- File locking interfaces: flock(2) and fcntl(2) F_SETLKW.
- POSIX message queue interfaces: mq_receive(3), mq_timedreceive(3), mq_send(3), and mq_timedsend(3).
- futex(2) FUTEX_WAIT (since Linux 2.6.22; beforehand, always failed with EINTR).
- POSIX semaphore interfaces: sem_wait(3) and sem_timedwait(3) (since Linux 2.6.22; beforehand, always failed with EINTR).

Ważne zaznaczenia jest to ze dysk nie jest uznany za "wolne" urządzenie, dlatego przy pisaniu lub czytaniu z pliku zawsze należny sprawdzać kod powrotu oznaczający ilość wpisanych lub odczytanych danych. 0 nie jest kodem błędu! ale informacja ze żadne dane nie zostały zapisane w momencie przyjęcia sygnału.

2011/02/14

Sojusz przegranych, jak błyskawica ...

Jeśli śledzicie rynek urządzeń mobilnych, zapewne wiecie ze Windows 7 Mobile jest postrzegany jako produkt spóźniony i niedopracowany. W internecie można znaleźć informacje o brakach i błędach tego systemu. To nie przeszkadza jednak M$ w promowaniu W7 jako "niszczyciela iOS" . Wg mnie to hipokryzja choćby ze względu braku kompatybilności wstecz z linia Windows Mobile (żegnaj Automapo). Jest też inny przegrany, Nokia. Firma ta w segmencie smartphone postawiła na system Symbian, który jak się okazało nie jest lubiany przez użytkowników i programistów (chyba nie bez powodu, ręka w górę kto ma to badziewie ;). Efektem tego jest spadek sprzedaży produktów Noki opartych o ten system, co negatywnie odbiło się na kondycji finansowej fińskiego producenta (m.in ze stanowisk polecieli szefowie sektora). Szybko jednak okazało się że Nokia nie załamuje rąk i podpisała umowę o współpracy, zgadnijcie z kim :).

Moim zdaniem będzie to ciekawe widowisko, ostatni okrzyk gigantów przed katastrofą, jednak czas pokaże jaki będzie wynik tej batalii z Androidem. Tymczasem szefowie obu firma maja bardzo podnoszące na duchu hasło:

"Istnieją inne ekosystemy mobilne. My je zniszczymy. Stoją przed nami wyzwania. My im sprostamy. Sukces wymaga szybkości. Będziemy jak błyskawica. Obydwaj widzimy szanse; mamy wolę, środki i motywację, aby odnieść sukces"

Moim zdaniem będzie to dosłownie jak błyskawica (dużo huku - czyli wielka kampania reklamowa), delikatny wzrost sprzedaży i wielka feta ala M$ ... i ... no właśnie ... wielkie nic, następne miliony użytkowników zostawione bez wsparcia technicznego i aplikacji użytkowych.
Balmer, sprzedawaj szybciej te akcje!!!!

2011/02/12

Algorytmy wielodostepu bez blokowania

Często podczas tworzenia oprogramowania z wykorzystaniem wątków musimy zadbać o wielodostęp do sekcji danych lub kodu. Najprostszym sposobem jest zabezpieczenie z wykorzystaniem semafora lub mutex'a. jednak takie podejście ma podstawowy problem, tworzy wąskie gardło dla przetwarzania współbieżnego. Problem ten jest bardzo poważny w systemach z duża liczba procesorów gdzie wymagana jest duża skalowalność. W przypadku systemów RTOS dochodzi dodatkowo problem nieprzewidywalności czasu wykonania, co jest głównym powodem problemów w takich systemach.

Rozwiązaniem jest szereg algorytmów które realizują założone zadanie (umożliwiają wielodostęp) ale nie wymagają blokowania. Bardzo dobre opracowanie znajdziecie tutaj

http://www.makelinux.net/ldd3/chp-5-sect-7.shtml

Sterowanie silnikiem krokowym

Fajny artykuł o sterowaniu silnikami krokowymi.

http://www.codeproject.com/KB/system/MotorController.aspx

Design patterns

Polecam strone m.in. o design patterns, bardzo dobrze przygotowany materiał.

http://sourcemaking.com/

2011/01/31

ARM w SIM

Szukałem informacji na temat Cortex-M0 a tym czasem trafiłem na coś takiego:

Jak się okazuje można opchnąć 320KB flash i Cortexa-M3 w karcie SIM!!! Ciekawe czy zwykły zjadacz chleba może sobie kupić parę sztuk tych czipów. Już widzę urządzenia do podpisu cyfrowego Made In Home :D, lub inteligentne karty SIM do GSM. Ehhh ... gdyby tylko wróciły stare czasy wyciągania kluczy z SIM :)

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/CD00252313.pdf

2011/01/30

Skróty klawiaturowe konsoli

Nie wiem czy znacie następujące skróty klawiaturowe konsoli:

!!
Powtórzenie ostatniego polecenia
!foo
Powtórzenie polecenia zaczynającego się od ‘foo…’ (np. !ps, !mysqladmin)
Ctrl-a
Skocz na początek linii
Ctrl-e
Skocz na koniec linii
Ctrl-l
Wyczyść ekran
Ctrl-r
Wyszukaj polecenie w historii (szukanie wstecz). Jeżeli chcemy edytować polecenie - wciskamy strzałkę w prawo
Alt-?
Podpowiedzi uzupełnienia komend
Ctrl-k
Wytnij tekst do końca linii
Ctrl-u
Wytnij tekst ad początku linii do kursora
Ctrl-y
Wklej wycięty tekst

ARM w pigułce

Kto chce się szybko i w skrócie zapoznać z asemblerem i kodem startowym dla ARM polecam:
http://www.bravegnu.org/gnu-eprog/index.html

Dla mnie najciekawsze było streszczenie architektury rozkazów ARM:
http://www.bravegnu.org/gnu-eprog/arm-iset.html


Do tego polecam
http://www.stm32.eu/index.php?option=com_content&view=category&layout=blog&id=35&Itemid=57