Posts Tagged ‘C’

Eudyptula-utmaningen

januari 31, 2016

Who is behind this?

A set of convoluted shell scripts that are slow to anger and impossible to debug.

I slutet av november fick jag höra om Eudyptula-utmaningen, och har sedan dess försökt beta av de uppgifter som har tickat in över e-post.

Den stora utmaningen från början var att konfigurera e-posten korrekt. Html-formaterade e-postmeddelanden är förbjudna och gmails webmail rekommenderas inte. Det slutade med att jag installerade Mutt, kommandoradsbaserad e-postklient. (Bitvis besvärlig men fullt fungerande.)

Efter det lilla skriptet hade godkänt min förfrågan om att deltaga började uppgifterna trilla in. Jag kan inte gå in i detaljer om uppgifterna eftersom det skulle bryta mot reglerna. Lite svävande kan jag säga att jag hitintills har genomfört fyra uppgifter av varierande slag. Jag har fått bygga en enkel modul och kompilera min egen kärna utifrån Linus git-repository. Jag har blivit tvungen att läsa lång torr dokumentation och jag har fått söka på nätet.

Jag har inte alltid lämnat in en acceptabel lösning på första försöket utan fått kritik och ledtrådar för att kunna fortsätta arbetet. Kritiken kommer alltid på ett bra sätt som inte fått mig att känna mig dum utan endast pekar ut knasigheter eller brister. Hela utmaningen är väldigt rolig och trots det lugna tempot i början lär jag mig mer än jag trodde.

Det som är bitvis problematiskt är att ibland tar det tid innan feedback lämnas eller att en korrekt lösning godkänns. Uppgift fem lämnades in den 15:e Januari och jag väntar fortfarande med spänning på att få reda på ifall jag klarat den eller inte.

Remember, this is not a race, there is no rush, if tasks take a while to
be graded, enjoy the time to go do something else.  There is a lot more
in life other than Linux kernel programming.

… Ett litet skript med svar på allt …

C64-programmering

maj 26, 2015

För ett par veckor sedan hittade jag cc65, en c kompilator för 6502-processorn. 6502-chip och dess varianter hittas i många retro-datorer däribland Commodores C64 (MOS6510). Tillsammans med boken Programming the Commodore 64, ett antal hjälpsamma hemsidor kom jag snabbt igång med ett litet hello world-program.

Installationen är relativt enkel:

Klona git-arkivet

git checkout https://github.com/cc65/cc65.git

gå till katalogen och bygg kompilatorn

cd cc65
make

Ifall man vill kan man installera den i systemet

sudo make install prefix=/usr/local/

När kompilatorn är installerad är det bara att börja programmera

#include 

int main(void)
{
    printf("Hello World!");
    return 0;
}

Programmet kompileras sedan enklast med

cl65 -t c64 hello.c -o hello.prg

När programmet är kompilerat kan det föras över till en fysisk c64 (exempelvis med uberCasette eller 1541 Ultimate). Dock har jag inte kommit så långt ännu utan kör mina program i vice.

Hello World

När man lär sig mer om c64ans olika minnes regioner kan man börja med diverse enkla effekter på texten:

Text som blinkar i regnbågens färger är inte alls lika imponerande som stillbild.

Text som blinkar i regnbågens färger är inte alls lika imponerande som stillbild.

Se koden här, den är kort och ganska enkel men har ett par rader assembler.

Nästa steg blir att utforska bitmap mode, avrottshantering och kanske lite sköna vågformer i SID-chippet.

Lagom medelvärdesbildning

juni 21, 2010

I mitt arbete springer man på löpande* medelvärden titt som tätt, och de är oftast ganska enkla historier men som kan kräva mycket minne ifall en stor data mängd skall användas (dvs. medelvärdet skall bildas över en längre tid). Detta kan ställa till problem i inbyggda system där det är snålt med minne. Jag har därför designat ett litet nätt objekt för medelvärden som man kan byta uppdateringshastighet mot minneskrav utan att tappa sampel-frekvens. Systemet är jag dock inte först med utan det har till exempel använts av en kamrat som var på Alfvén-laboratoriet samtidigt som mig och det var i ärlighetens namn hon som fick mig i dessa tankegångar.

Systemet har en buffer med delmedelvärden och en buffer med sampels. Mätvärden läggs in i sampel-bufferten och när den är full medelvärdesbildas dessa och läggs in i ett element i delmedelvärdes-buffern. när man sedan vill ha medelvärdet för samtliga sampel tas ett medelvärde av de befintliga delmedelvärdena.

Minneskravet för medelvärde på de senaste 300 mätvärden går från 300 ord** till 30 + 10 ord ifall vi kan nöja oss med uppdateringar var 10:e sample.

#include <stdio.h>
#include <stdlib.h>

#define MEAN_FULL 0x08

typedef struct meanStruct {
  signed short *s;  // Sample-array
  signed short *m;  // array of sub-mean-values
  unsigned char sLen; // Number of samples before a new sub-mean is generated
  unsigned char mLen; // total number of sub-means
  unsigned char sPtr; // pointer to current sample
  unsigned char mPtr; // pointer to current mean
  unsigned char status;
} mean_t;

void meanInit(mean_t *mean, signed short *meanArr, unsigned char maLen, signed short *sampleArr, unsigned char saLen)
{
  mean->mLen = maLen;
  mean->sLen = saLen;

  mean->mPtr = 0;
  mean->sPtr = 0;

  mean->m = meanArr;
  mean->s = sampleArr;

  mean->status = 0x00;
}

void meanAddSample(mean_t *mean, signed short sample)
{
  unsigned char index;
  signed long subMean = 0;

  mean->s[mean->sPtr] = sample;

  mean->sPtr++;

  if (mean->sPtr >= mean->sLen)
  {
    mean->sPtr = 0; // reset sample pointer

    // Calculate sub-mean
    for (index = 0; index < mean->sLen; index++)
    {
      subMean += (signed long)mean->s[index];
    }
    subMean /= (signed long) mean->sLen;

    printf("mean->m[%d] = %d\n", mean->mPtr, subMean);
    mean->m[mean->mPtr] = subMean; //update subMean-array

    mean->mPtr++;
    if (mean->mPtr >= mean->mLen)
    {
      mean->status |= MEAN_FULL;
      mean->mPtr = 0;
    }
  }
}

signed short meanGet(mean_t mean)
{
  unsigned char index, stop;
  signed short sum = 0;

  if (mean.status & MEAN_FULL)
    stop = mean.mLen;
  else
    stop = mean.mPtr;
  // get mean-value from sub-means

  for (index = 0; index < stop; index++)
    sum += mean.m[index];
  if(stop > 0)
    return sum / stop;
  else
    return 0x8000; // UNDEFINED

}

int main(int argc, char *argv[])
{
  mean_t test;
  signed short means[3], samples[10], index;
  signed long compare = 0;
  meanInit(&test, means, 3, samples, 10);

  for(index = 0; index < 30; index++)
  {
    compare += index * 2;
    addSample(&test, (index * 2));
  }
  compare /= 300;
  printf("Orig: %d Test: %d\n", compare, getMean(test));

  system("PAUSE");
  return 0;
}

syntax highlighted by Code2HTML, v. 0.9.1

main()-funktionen ovan initialiserar ett medelvärdesobjekt och fyller det med data och testar det genom att jämföra medelvärdet med ett ”normalt” beräknat medelvärde.

Man borde kunna generalisera metoden ytterligare genom att lägga in ett läge som fyller ut sample buffern med Älsta-medlet / sample-bufferstorleken och räknar ut ett medel på detta som sedan ersätter det älsta medlet. Detta höjer uppdateringshastigheten om man gör lite avkall på noggranheten eftersom det älsta medlet kommer fungera som ett IIR-baserat medel istället för ett FIR-baserat (som de övriga medelvärdena använder).

Eftersom jag inte är hundra på allt detta är kommentarer, tillrättningar, förslag och buggrapporter hemskt välkomna! Förövrigt är det nog dags att jag hittar nått ställe att lägga dessa kodsnuttar, de börjar bli ett antal nu.

* löpande innebär att de x senaste mätningarna skall användas för att bilda medelvärdet

** ord kan vara 8, 16,32 eller 64 bitar stort beroende på val. I den här implementeringen är orden 16 byte stora

Selection Sort

maj 21, 2010

The Reinvigorated Programmer utfärdade en ny utmaning, implementera selection sort. Selection Sort är en ganska enkel (läs ineffektiv) sorteringsrutin som letar igenom en uppsättning värden och väljer ut det lägsta och placerar det först i en lista (kan vara in-place, dvs samma lista som innehåller de osorterade värdena).

Jag tyckte det här var en bra övning att träna på lite mer formella algoritm-beskrivningar så jag började med att sätta upp invarians, gränsfunktioner och pre/post-conditions (hur översätts dessa?) och skrev sedan min algoritm utifrån dessa beskrivningar. Eftersom det är första gången jag skriver dessa formella beskrivningar är jag lite osäker på om jag uttrycker det jag vill att algoritmen skall göra på rätt sätt. Jag uppskattar därför alla kommentarer på nedanstående c-kod och beskrivningar.

/*
 * Invariant: if val at any position i in an array array of length len
 *  is lower than the current value at j in the array the value is at
 *  an i > j and i < len
 *
 * bound function: 0 <= j < length - 1
 *                 j <  i < length
 *
 * precondition:  a[] is an unsorted array of integers of the size len
 * postcondition: a[] is an array sorted higher to lower
 * */
void selectSort(int a[], int len)
{
  int tempStore, i, j;

  for (j = 0; j < len - 1; j++)
  {
    for (i = j + 1; i < len; i++)
    {
      if (a[i] < a[j])
      {
	tempStore = a[j];
	a[j] = a[i];
	a[i] = tempStore;
      }
    }
  }
  return;
}

syntax highlighted by Code2HTML, v. 0.9.1

Energetisk

augusti 12, 2009

Efter en lugn helg med en massa bokläsning och lite TV kände jag mig oförskämt pigg och bestämde mig för att ta tag i ett par (väldigt) små projekt som jag haft liggande.

Det första var ytterst litet och enkelt: Byta SMS-signal på min telefon. För ett tag sedan kom jag på att sekvensen som spelas mellan nivåerna i The Great Giana Sisters skulle vara rolig att ha. För att komma åt detta ljud laddade jag ner musiken i sid-format (eller psid om man ska vara noga), sedan använde jag SIDPlayer för att spara ljudet som wav och sedan konverterade jag wav-filen till mp3 och förde över till min mobiltelefon. (SMSa gärna så jag får höra signalen!)

När jag använde sidplayer upptäckte jag att programmet kraschade (segmenterings fel) precis när det avslutades och eftersom jag var så pass pigg satte jag mig och letade efter felet och hittade det. Det gör ingen egentlig skillnad eftersom kraschen inte gör någon skada men det kändes ändå bra. Detta var sent en söndag kväll, vissa har liv men inte jag…dock har jag skoj!

Projekt nummer två var att fixa iordning mitt script som laddar ner och visar den senaste bunny-strippen på mitt skrivbord. Tidigare använde jag libxml2 för att själv parsa seriens RSS-flöde nu valde jag att använda det aningen (läs mycket) smidigare biblioteket feedparser och resultatet blev ett litet smidigt script som jag till och med vågar visa andra. Nu finns det upplagt i menyn till höger under namnet bunny-bg.