Anthony's Blog
Just another WordPress.com weblog

Nov
22

Whenever digital data is stored or interfaced, data corruption might occur. To overcome this problem people have searched for mathematical sound mechanisms to detect multiple false bits. The CRC calculation or cyclic redundancy check was the result of this. The idea behind CRC calculation is to look at the data as one large binary number. This number is divided by a certain value and the remainder of the calculation is called the CRC. The divisor value is described as a polynomial of certain order.

Polynomial functions for common CRC’s
CRC-16 – 0x8005 x16 + x15 + x2 + 1
CRC-CCITT – 0x1021 x16 + x12 + x5 + 1
CRC-32 – 0x04C11DB7 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x1 + 1

To caluculate a CRC, the follwing steps must be followed:
1. Initialize the CRC value. For some CRC types, the initial value is zero. For others, it can be all 1s.
2. For each byte of the data, starting with the first byte, calculate the value of the CRC.

When working with a small number of bytes, this could be calculated bit by bit. This is obviously considered the slow algorithm. A faster method is to pre-calculate a table that contains all the possible division operations and use this as a lookup table for each byte. This is considered the fast algorithm and is shown in the code below.


class Program
{
//CRC-16 = x^16 + x^15 + x^2 + 1 = 0001 1000 0000 0000 0101 = (the 16th bit is dropped) = 0x8005;

//when this value is reversed/reflected, it would be 1010 0000 0000 0001 = 0xA001 - we use the normal value when left shifting bits and the reflected value when right shifting

const uint P_16 = 0xA001;
static uint[] table;
static void Main(string[] args)
{
table = new uint[256];
buildCRCTable(ref table);
uint myCRC = 0;
myCRC = calculateCRCFast(myCRC, 0x6);
myCRC = calculateCRCFast(myCRC, System.Convert.ToUInt32('A'));
}

// Builds the CRC table for the fast implementation
public static void buildCRCTable(ref uint[] myTable)
{
int i, j;
uint crc, c = 0;
for (i = 0; i < 256; i++)
{
crc = 0;
c = (uint)i;
for (j = 0; j 0)
{
crc = (crc >> 1) ^ P_16;
}
else
{
crc = crc >> 1;
}
c = c >> 1;
}
myTable[i] = crc;
}
}

// Calculates CRC (CRC-16), using the look-up table for speed
public static uint calculateCRCFast(uint crc, uint c)
{
uint tmp, short_c;
short_c = 0x00ff & c;
tmp = crc ^ short_c;
crc = (crc >> 8) ^ table[tmp];
return crc;
}
}

public static uint calculateCRCLoop(string targetString)
{
uint bCRC = 0;
int targetLength = targetString.Length;
byte[] buffer = new byte[targetLength];
buffer = System.Text.Encoding.UTF8.GetBytes(targetString); 

for (int i = 0; i < targetLength; i++)
{
bCRC = calculateCRCFast(bCRC, buffer[i]);
}
return bCRC;
}
Sep
12
Sep
09

Measure the resistence between a known ground and the point you want to check. If there is very low resistence, then it is a ground. If the resistance is infinite, then the wire is broken or the circuit is open. Note, the circuit must be unpowered.

Alternatively, you can check continuity between two points. If there is very little continuity (or your multimeter beeps), then you have a ground.

Aug
29

Sign Magnitude
Make the most significant bit the sign bit. If this bit is 1, then the value is negative. If it’s 0, the value is positive. One problem with sign magnitude is that it has two zeroes; a positive zero and a negative zero.

One’s Complement
This system is used to represent negative numbers. The ones’ complement form of a negative binary number is the bitwise NOT applied to it — the complement of its positive counterpart. Like sign magnitude representation, one’s complement has two representations of 0.

As an example, the ones’ complement form of 00101011 (43) becomes 11010100 (−43).

Two’s Complement
In two’s complement, negative numbers are represented by the bit pattern which is one greater  than the ones’ complement of the positive value.  There is also only one zero.

Negating a number (whether negative or positive) is done by inverting all the bits and then adding 1 to that result.

An easier method to get the negation of a number in two’s complement is as follows:
Example:
1. Starting from the right, find the first ‘1’ 0101001 0101100
2. Invert all of the bits to the left of that one 1010111 1010100

To store a number in two’s complement convert to binary as usual. If the number is positive store it directly. If the number is negative then firstly store the positive version, and then invert all bits and add 1 to the resulting binary number. The leftmost bit still indicates the sign of the number (but is not manipulated separately).

To convert to decimal from 2’s complement, check the sign bit. If 0 then convert as usual. If it is 1 (a negative number) then apply 2’s complement to get the positive version in binary, and convert to decimal as usual. Then put the – sign on front.

Aug
29

This sample is not my own. It was copied from http://www.codewrapper.com

This code example shows how to create XML file using XmlWriter.
The example shows how to create elements, set comment, set attributes and create child nodes.
The output of this code snippet will generate the following XML:

view source

print?

01.<?xml version="1.0" encoding="utf-8"?>

02.<!--Using XmlWriter Example.-->

03.<root>

04.  <parent0 attr0="value0">

05.    <child0>value0</child0>

06.  </parent0>

07.  <parent1 attr1="value1">

08.    <child1>value1</child1>

09.  </parent1>

10.  <parent2 attr2="value2">

11.    <child2>value2</child2>

12.  </parent2>

13.  <parent3 attr3="value3">

14.    <child3>value3</child3>

15.  </parent3>

16.  <parent4 attr4="value4">

17.    <child4>value4</child4>

18.  </parent4>

19.</root>

view source

print?

01.// You can pass settings to the XmlWriter to specify 

02.// encoding, IndentChars and ore.

03.XmlWriterSettings settings = new XmlWriterSettings();

04.

05.settings.Encoding = UTF8Encoding.UTF8;

06.settings.Indent = true;

07.            

08.// Using is very importent to terminate the XmlWriter

09.// and to close it properly.

10.using(XmlWriter writer = XmlWriter.Create("Example.xml", settings))

11.{

12.    // Start the document.

13.    writer.WriteStartDocument();

14.

15.    // Write a comment.

16.    writer.WriteComment("Using XmlWriter Example.");

17.

18.    // Create the root element.

19.    writer.WriteStartElement("root");

20.

21.    for (int i = 0; i < 5; i++)

22.    {

23.        // write element parent.

24.        writer.WriteStartElement("parent" + i);

25.        // Set parent_i attribute.

26.        writer.WriteAttributeString("attr" + i, "value" + i); 

27.

28.        // Write parent's child element.

29.        writer.WriteElementString("child" + i, "value" + i);                                                            

30.

31.        // close the parent element.

32.        writer.WriteEndElement();

33.    }

34.    

35.    // close root element.

36.    writer.WriteEndElement();

37.

38.    // close the document.

39.    writer.WriteEndDocument();

40.}

This code snippet shows how to get events such as Deleted, Changed, Renamed, Created for files on specific directory.

view source

print?

01.FileSystemWatcher watcher = new FileSystemWatcher();

02.

03.// The target directory.

04.watcher.Path = @"D:\";

05.

06.// Register to files events.

07.watcher.Changed += new FileSystemEventHandler(watcher_Changed);

08.watcher.Deleted += new FileSystemEventHandler(watcher_Deleted);

09.watcher.Renamed += new RenamedEventHandler(watcher_Renamed);

10.watcher.Created += new FileSystemEventHandler(watcher_Created);

11.

12.watcher.EnableRaisingEvents = true;

13.

14.// Filter the type of files you would like to monitor.

15.watcher.Filter = "*.txt";

Event Handlers for the events:

view source

print?

01.static void watcher_Created(object sender, FileSystemEventArgs e)

02.{

03.    Console.WriteLine(e.Name + "is added.");

04.}

05.

06.static void watcher_Renamed(object sender, RenamedEventArgs e)

07.{

08.    Console.WriteLine(e.OldName + " is renamed to " + e.Name );

09.}

10.

11.static void watcher_Deleted(object sender, FileSystemEventArgs e)

12.{

13.    Console.WriteLine(e.Name + " is deleted.");

14.}

15.

16.static void watcher_Changed(object sender, FileSystemEventArgs e)

17.{

18.    Console.WriteLine(e.Name + " is changed (type: " + e.ChangeType + ")");

19.}

.NET 4.0 Framework introduces System.IO.MemoryMappedFile for sharing memory between different processes on the same machine.
You can create multiple views of the memory mapped file, including views of parts of the file. Read more on the MSDN

From process # 1:

view source

print?

1.MemoryMappedFile mappedFileOut = MemoryMappedFile.CreateNew("Example1", 100);

2.

3.StreamWriter writer = new StreamWriter(mappedFileOut.CreateViewStream());

4.

5.writer.WriteLine("Hello Example");

6.

7.writer.Close();

From process # 2:

view source

print?

1.MemoryMappedFile mappedFileIn = MemoryMappedFile.OpenExisting("Example1");

2.

3.StreamReader reader = new StreamReader(mappedFileIn.CreateViewStream());

4.

5.Console.WriteLine(reader.ReadLine());

Aug
29

DLL compilation will produce both DLL and LIB files. The LIB file is used to link against a DLL at compile-time; it is not necessary for run-time linking. Unless your DLL is a COM server, the DLL file must be placed in one of the directories listed in the PATH environment variable, in the default system directory, or in the same directory as the program using it.

dllexport of a C++ function will expose the function with C++ name mangling. If C++ name mangling is not desired, either use a .def file (EXPORTS keyword) or declare the function as extern "C".

MyLib.h —C library

__declspec(dllexport) int adder();

MyLib.c

#include "MyLib.h"

int adder()

{

return 5;

}

MyLib.cpp  – use extern "C" to tell compiler that library is in C; otherwise remove the extern if the library was written in C++.

extern "C"

{

      #include "MySBS.h"

}

int _tmain(int argc, _TCHAR* argv[])

{

int a = adder();

return 0;

}

Aug
29

#include <bios.h>

#include <conio.h>

#define COM1       0

#define DATA_READY 0x100

#define SETTINGS ( 0xC0 | 0x02 | 0x00 | 0x00)

int main(void)

{

   int in, out, status;

   bioscom(0, SETTINGS, COM1); /*initialize the port*/

   cprintf("Data sent to you:  ");

   while (1)

   {

      status = bioscom(3, 0, COM1); /*wait until get a data*/

      if (status & DATA_READY)

           if ((out = bioscom(2, 0, COM1) & 0x7F) != 0)  /*input a data*/

              putch(out);

           if (kbhit())

           {

              if ((in = getch()) == 27)   /* ASCII of Esc*/

                 break;

              bioscom(1, in, COM1);   /*output a data*/

           }

   }

   return 0;

}

Aug
28

Quote from Donald Rumsfeld at a Press Conference at NATO Headquarters, Brussels, Belgium, June 6, 2002

There are known knowns. These are things we know that we know. There are known unknowns. That is to say, there are things that we know we don’t know. But there are also unknown unknowns. There are things we don’t know we don’t know.

This is a profound quote and I saw the application of it on a forum where people were complaining about a book on a programming language that didn’t turn them into an “expert” in short amount of time. One poster defended the book by stating “The point of this book, obviously, is to turn people’s unknown unknowns into known unknowns. Not for them to become competent programmers in 7 weeks”.

Jun
27


/* Abstract data type to encpsulate data sent to a thread */
typedef struct                          
{ 
    volatile BOOL fStayAlive;       /*Flag indicating the thread should stay alive*/ 
    volatile BOOL fThreadHasQuit;   /*Flag indicating the thread has quit*/ 
    HCORE     hCore;                 /*Handle of core*/ 
} ThreadMailbox;

/****************************************************/
/* Main function of the application */
/****************************************************/
int main(void)
{
    /* now that hardware has been verified, let's daemonize this application */
    int retVal = daemon(1, 0);
    if (retVal < 0)
    {         LogToFile("Failed to start daemon");
        exit(1);
    }
    else
    {
        LogToFile("Started daemon");
        signal (SIGTERM, signal_handler);
    }
 
 
    /* create thread for processing interrupts */
    ThreadMailbox Mailbox;
    Mailbox.hCore  = hCore; 
 
    pthread_t ThreadId;
 
    errval = pthread_create( 
        &ThreadId,                    /* ID of Thread being created */
        NULL,                         /* Default attributes */
        EventLogInterruptThread,      /* Pointer to thread function  */
        (LPVOID)&Mailbox);            /* Argument for new thread  */
 
    if (errval) 
    { 
        LogToFile("Error:  Thread creation failed (error = %d)",errval); 
        exit(1); 
    } 
 
 
    struct timespec tmReq;
    tmReq.tv_sec = 0;
    tmReq.tv_nsec = 20000000;
     
    while (TerminateProgram == 0)
    {
 
        /*suspend thread for tmReq amount of time */
         nanosleep(&tmReq,NULL);     
    }
 
    /* clear the flag that keeps the thread alive */
    Mailbox.fStayAlive = FALSE;
 
 
    /* wait for the thread to die */
    pthread_join(ThreadId,NULL);
 
 
     /* uninstall the interrupt handler */
    errval = BTICard_IntUninstall(hCore); 
 
    if (errval fStayAlive     = TRUE; 
    pMailbox->fThreadHasQuit = FALSE; 
     
    eventlog_poll.fd      = 0;
    eventlog_poll.events  = POLLIN;
    eventlog_poll.revents = 0;
 
    while(pMailbox->fStayAlive) 
    { 
        /* Wait for valid fd (after int install) */
 
        if (!eventlog_poll.fd)
        {
            eventlog_poll.fd = (INT)BTICard_IntGet(hCore);
            continue;
        }
 
     
        /* Use poll system call to know when core 
           has gotten an interrupt (return after 200ms timeout) */
 
        if (poll(&eventlog_poll,1,200) > 0) 
 
        { 
            /* Check core */
 
            if (eventlog_poll.revents)
 
            {
                eventlog_poll.revents = 0;             }
        }
    }
 
    pMailbox->fThreadHasQuit = TRUE; 
 
    LogToFile("Event Log Interrupt Thread Ended");
 
    return(0);
}

Jun
27


/****************************************************/
/* Setup the UDP/ethernet interface */
/****************************************************/
void configure_net(void)
{
 
     
    /*retrieve settings from configuration file */
    char tempBuffer[50];
    memset(&socketAddress, 0, sizeof(socketAddress));
    socketAddress.sin_family = AF_INET;
 
    if (GetValueFromCfgFile("ADDR", tempBuffer, 50) == ERR_NONE)
    {
        LogToFile("ADDRESS is %s", tempBuffer);
        if(inet_pton(AF_INET, tempBuffer, &socketAddress.sin_addr) <= 0)
        {
            /*set LED on box to visually notify of bad error */
            BTICard_ExtStatusLEDWr(1, 0, hCore);
 
            LogToFile("\nCould not convert address from config file");
            exit(1);
        }
    }
    else
    {
        /*set LED on box to visually notify of bad error */
        BTICard_ExtStatusLEDWr(1, 0, hCore);
 
        LogToFile("ERROR - could not retrieve ADDR from config file");
        exit(1);
    }
 
    if (GetValueFromCfgFile("PORT", tempBuffer, 50) == ERR_NONE)
    {
        LogToFile("PORT is %s", tempBuffer);
        DestinationPort = (unsigned short)BTICard_ValFromAscii(tempBuffer, 10);
        socketAddress.sin_port = htons(DestinationPort);
 
    }
    else
    {
        /*set LED on box to visually notify of bad error */
        BTICard_ExtStatusLEDWr(1, 0, hCore);
 
        LogToFile("ERROR - could not retrieve PORT from config file");
        exit(1);
    }
 
         
    /*  Open socket descriptor */
    socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (socketDescriptor < 0)
    {
        /*set LED on box to visually notify of bad error */
        BTICard_ExtStatusLEDWr(1, 0, hCore);
 
        LogToFile("Socket failed to return a valid socket descriptor");
        BTICard_CardClose(hCard);
        exit(1);
    }     
 
    /*  Enable Broadcast capability on Socket - must choose a broadcast address to use */
    /*char socketOption = '1'; */
    int socketOption = 1;
    int status = setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, &socketOption, sizeof(socketOption));
    if (status == -1)
    {
        /*set LED on box to visually notify of bad error */
        BTICard_ExtStatusLEDWr(1, 0, hCore);
 
        LogToFile("Failed to set Socket Options");     
        BTICard_CardClose(hCard);
        exit(1);
    }
 
     
    /*establish socket connection - this is really only necessary if we were sending with TCP/IP*/
 
/*    status = connect(socketDescriptor, (struct sockaddr *) &socketAddress, sizeof(socketAddress));  */
/*    if (status < 0)                          */
/*    {                                  */
/*        LogToFile("Socket connect failed (%d)", errno);         */
/*        LogToFile("%s", strerror(errno));             */
/*        BTICard_CardClose(hCard);                 */
/*        exit(1);                         */
/*    }                                 */
/*    else                                 */
/*    {                                 */
/*        LogToFile("Socket connected successfully");         */
/*    } */                                 
} 

Follow

Get every new post delivered to your Inbox.