Øvelse 4: Linux Kernemoduler

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

#include <string.h>
#include <errno.h>


void SetLed(int hfile, char * value);

int main()
{
    char ch;
    int hBrightness=0;
    int hTrigger=0;
    
    

    char *ON = "1";
    char *OFF = "0";
    char *NONE = "none";
    char *HEARTBEAT = "heartbeat";

    enum BOOL {false=0,true} bLoop = true;

    

    if ((hBrightness = open("/sys/class/leds/led3/brightness", O_WRONLY ) ) == -1){
        printf("Error opening Brightness file: %s\n",strerror(errno));
    }
    else {
        printf("Brightness file successfully opened.\n");
    }

    if ((hTrigger = open("/sys/class/leds/led3/trigger", O_WRONLY ) ) == -1){
        printf("Error opening Trigger file: %s\n",strerror(errno));
    }
    else {
        printf("Trigger file successfully opened.\n");
    }

    //As long as 'q' is not pressed
    while ( bLoop ) {
    
        printf("Actions on LED3:\n");
        printf("\t 0 - Turn off. \n");
        printf("\t 1 - Turn on. \n");
        printf("\t h - Heartbeat. \n");
        printf("\t n - No heartbeat. \n");
        printf("\t q - Quit. \n");
        printf("Your choice: ");
        ch=getchar();
        
        switch (ch) {
            case '0' : SetLed(hBrightness,ON); break;
            case '1' : SetLed(hBrightness,OFF); break;
            case 'h' : SetLed(hTrigger,HEARTBEAT); break;
            case 'n' : SetLed(hTrigger,NONE); break;
            case 'q' : bLoop = false; break;
            default  : break;
        }    
        //empty input buffer        
        while((ch=getchar()) != '\n'){}

    

    }



    if ( close(hBrightness) != 0  ) {
        printf("Error closing Brightness file. Error: %s\n",strerror(errno));
    }
    else {
        printf("Brightness file successfully closed.\n");
    }

    if ( close(hTrigger) != 0  ) {
        printf("Error closing Trigger file. Error: %s\n",strerror(errno));
    }
    else {
        printf("Trigger file successfully closed.\n");
    }
        
    exit(0);
}


void SetLed(int hFile, char * value){
            
        int length = strlen(value);
        int nwrite;
        if ( (nwrite = write(hFile,value,length) ) != length )    
        {
            printf("Error writing to file. Error: %s.\n",nwrite,strerror(errno));
        }

}

Øvelse 1: Endianness

Her er et adresseområde i hukommelsen:

       00  01  02  03  04   05  06  07  08  09  0A  0B  0C  0D  0E   0F 
00:  4E  55  20  4B  4A  48  20  41  20  54  41   49  56   20   55   4E
10:  4D  45  44  54  20   47  53  47  4F  44  20   41  42   45   45   46

Hukommelsen har en 8-bit atomisk størrelse, dvs. den mindste
datastørrelse, man kan tilgå, er en byte.

1) Fra adresseområdet laves en række læsninger:

A: Read32Big(0x00);    0x4E55204B
B: Read8Big(0x0A);     0x41
C: Read32Little(0x0B); 0x55205649
D: Read16Little(0x08); 0x5420
E: Read32Big(0x12);    0x44542047
F: Read32Little(0x04);  0x4120484A
G: Read8Little(0x16);   0x53
H: Read16Little(0x10); 0x454D
I: Read8Big(0x0F);       0x4E
J: Read16Big(0x17);     0x474F
K: Read8Big(0x1B);     0x41
L: Read16Little(0x19);  0x2044


2) Vi sammensætter resultaterne i rækkefølgen
A & B & I & L & C & G & D & J & E & K & F & H,
og får følgende hexadecimal udtryk
0x4E 0x55 0x20 0x4B 0x41 0x4E 0x20 0x44 0x55 0x20 0x56 0x49 0x53 0x54
0x20 0x47 0x4F 0x44 0x54 0x20 0x47 0x41 0x41 0x20 0x48 0x4A 0x45 0x4D

3) Oversættelsen af ovenstående hexadecimal udtryk til ASCII
giver: "NU KAN DU VIST GODT GAA HJEM"

4) At tilgå data med den forkerte atomiske størrelse (f.eks. 16-bit eller 32-bit) ville
resultere i en ombytning af bogstaverne i den endelige ASCII-oversættelse.