mandag den 29. november 2010

Øvelse 11
Hvilken type RAM kreds er benyttet og hvad er karakteristisk for denne type?
Der benyttes en SRAM-kreds, som har følgende karakteristika:
  • Har større footprint end det typiske alternetriv DRAM.
  • Ligesom DRAM, kræver konstant spænding.
  • Er dyre end DRAM, på grund af det større footprint.

Hvor mange addresselinier skal vi bruge for at tilgå al memory i den nævnte kreds? -og kan vi det med GPMC interfacet?
Memory-interfacet er 16-bit.
OMAP har dumt nok kun til et 10-bits interface:
så vi kan ikke bruge de sidste 6-bit, og man kan derfor overveje og bruge en billigere kreds, der bliver bedre udnyttet.


Hvor lang tid kan kredsen holde data efter strømafbrydelse, hvis vi benytter et CR2032 knapcelle batteri?
Q=i*t,
mens i = max 2 µA

det giver 112500 timer,
eller 12,83 år.

Hvad er den maksimale databåndbredde for kredsen?
Vi aflæser tiden til 85 ns, og antallet af bit er 16.
det giver 188235294.118 bit/s som giver 180 megabit

LED
Hvilke adresser skal man skrive til for at sætte værdierne af de 5 LED banke?
Man skriver til adresse A10 A9 og A8.
dette kunne være: 0x4000 0 x 0 0
hvor x angiver bit 11:8 i hex, som vi derfra kan vælge.

Beskriv en skrive cyklus for at sætte værdien af lysdioderne på bank 3.
Man skriver til 0x4000 0 3 0 0, hvor med 3 vælger bank 3.
kredsen 74hc138 omsætter adressen 3 til en "chipselect" til bank 3, og data fra bussen routes der hen.

mandag den 22. november 2010

Opgave 10
Vi laver denne magiske kode der belaster CPU vildt..:
denne har denned tid:

vi mindsker antallet af læsninger manuelt, og derved optimere brugen af cache:
Som giver os denne væsentligt forbedre tid (1/5 hurtigere end normalt):


Yderligere optimering kan fås med compiler flag -O0 til -O3, der optimere diverse.
vi så dog ingen væsentligere forbedringer, kun på få ms, så dette er ikke hver at dokumentere....





mandag den 15. november 2010

Opgave 9
Assambly-koden:
#Testing r-format arithmetic operators

#init registers
.register $s0 -10
.register $s1 5
.register $s2 3


main: add $s3, $s1, $s1 #5+5
add $s4, $s1, $s0 #5+-10
sub $s5, $s1, $s2 #5-3
sub $s6, $s2, $s1 #3-5
and $s7, $s2, $s1 #011 AND 101
exit:

Hvad gør den??

Den første instruktion tager register 1 (5) og lægger sammen med register 1 (5), og putter svaret i reg 3.
Den anden instruktion tager register 1 (5) og lægger sammen med register 0 (-10), og putter svaret i reg 4.
Den tredje instruktion tager register 2 (3) og trækker fra register 1 (5), og putter svaret i reg 5.
Den fjerde instruktion tager register 1 (5) og trækker fra register 2 (3), og putter svaret i reg 6.
Den femte instruktion tager register 2 (3) og adder med register 1 (5), og putter svaret i reg 7.

Opgave 1 : Basic arithmetic
• Hvilke enheder benyttes?
Programcounter
Sender med specifikke mellemrum adressen til næste kommando.
Programinkriminator
Inkrimentere programcounterværdien
'Programinstruktionsstørrelseinkriminator
Udsender en hardcoded værdi af kommandolængden.
Instruktionshukommelsen
Udsender instruktionen tilsvarende til det som kommandoen peger på i dens hukommelse.
Splitter
Opdeler instruktionen i de forskellige registre og funktionaliteter.
Registerbank
Indlæser de to inputregistre, samt klargør outputregistret.
Registerbankkontrol
Vælger funktionalitet af registerbanken
Hovedaritmetik
Udregner arimitikopgaven på 2 input.
Hovedaritmetikkontrol
Angiver funktionalitet til hovediarimtikken ud fra instruktion.

• Hvilke afhængigheder eksisterer?
alle enheder afhænger af hinanden

• I hvilken rækkefølge udføres operationerne?
Programcounteren sætter takten for hele svineriet.
rækkefølgen for svineriet er:
der hentes en instruktion, instruktionen opdeles i registrer og funktionalitet, parallelt sendes registrende til registerbanken, samt funktionaliteten sendes til Hovedaritmetikkontrol, registerbanken modtager kontrolfunktionalitet fra registerkontrollen, parallelt klargøres outputregistret mens værdien fra de to inputregistre hentes og outputtes, hovedarimitik modtager funktionalitet fra hovedaritmitkkontrol, hovedaritmitik modtager to inputværdier, behandler aritmetisk og outputter dem, registerbanken modtager resultatet, og putter det ned i det klargjorte register.

• Svarer det overens med det forventede?

mandag den 8. november 2010

Opgave 8
I denne øvelse skal vi lave en tilføjelse til vores GPIO driver. Vha et ioctl kald skal det være muligt at sætte en output pin til at toggle med et fast interval.

Implementer ioctl kald
ved ioctl kladet udskriver vi til kernen:
IOCTL kladet implimenteres ligesom en read eller write funktion i driveren. IOTCL kan tilgås fra userspace ligesom read og write, og bruges ofte til at sætte driveren op til noget speceilt, det kunne f.eks. være baud-rate på en serial-driver.
IOCTL funktionen skal kaldes med et IOCTL-nummer. Da ioctl-numrene er globale skal man først sikre sig at man vælger et nummer der ikke er optaget. Alt under 1000 er med stor sikkerhed optaget allerede (enten af systemet eller andre drivere) så derfor valgte vi to vilkårlige tal over 1000. Valget faldt på 1101 og 1102.

Det første vi gør er at tilføje IOCTL i file_operations, så muligheden for IOCTL er der:
I vores file_operations struct tilføjer vi muligheden for ioctl-kald.

struct file_operations mygpio_Fops =
{
.owner = THIS_MODULE,
.open = mygpio_open,
.release = mygpio_release,
.write = mygpio_write,
.read = mygpio_read,
.ioctl = mygpio_ioctl,
};

Dernæst skal vi angive vores magiske IOCTL numre:
#define JOE1 1101
#define JOE2 1102

Så implimentere vi IOCTL-funktionen:
size_t mygpio_ioctl(struct inode* Inode, struct file* filep, unsigned int cmd, unsigned long arg)
{
int minor = MINOR(filep->f_dentry->d_inode->i_rdev);
switch(cmd)
{
case JOE1:
printk(KERN_ALERT "Det var en etter\n");
break;
case JOE2:
printk(KERN_ALERT "Det var en toer %i\n", arg);
break;
default:
printk(KERN_ALERT "Defualt default!\n");
break;
}
return 0;
}

Læg mærke til case: JOE2, hvor vi samtidig udskriver arg, denne angiver nemlig hvilke argumenter vi sender med.

Vi laver en applikation der kan kontrollere driveren fra userspace:

#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/timer.h>

int main()
{

int fd = open ( "/dev/joenode1", O_RDWR | 0666);

ioctl(fd, 1101); //burde udskrive Det var en etter til kernen
close(filePtr);
int fd = open ( "/dev/joenode1", O_RDWR | 0666);

ioctl(fd, 1102, 7); //sender 7 med som argument
//burde udskrive Det var en toer 7 til kernen
close(filePtr);
return 0;
}

Test:
Først indsætter vi modulet, og opretter noden, og køre dmesg:

kører vores testprogram, og ser hvad der sker:

Implementer toggler
vi valgte kun at implimentere en timer der ikke belastede CPU'en da denne er den mest anvendelige, og vi var lidt bagefter med CPAC opgaverne..


Til timeren brugte vi siden her som inspiration:
og kom frem til følgende kode som fungerede:
size_t mygpio_ioctl(struct inode* Inode, struct file* filep, unsigned int cmd, unsigned long arg)
{
int minor = MINOR(filep->f_dentry->d_inode->i_rdev);
switch(cmd)
{
case INIT_TIMER:
printk("Init timer!\n");
init_timer(&my_timer);
//jiffies og HZ er system vaiabler der angiver tiden
my_timer.expires = jiffies + arg*HZ;
my_timer.function = timer_func;
my_timer.data = arg;
add_timer(&my_timer);
break;
case SET_INTERVAL:
printk("Setting interval %i\n", arg);
my_timer.expires = jiffies + arg*HZ;
break;
case EXIT_TIMER:
printk("Exit timer!\n");
del_timer_sync(&my_timer);
break;
default:
printk("Defualt case entered!\n");
}
return 0;
}

//og her den timer_func der udføres når den udløber
static void timer_func(long int arg)
{
printk("Entering timer_func");
//init_timer(&my_timer);
add_timer(&my_timer);
my_timer.expires = jiffies + arg*HZ;
my_timer.function = timer_func;
my_timer.data = arg;
if(val == 1)
{
printk("Setting val %i\n", val);
gpio_set_value(139, 1);
val = 0;
}
else
{
printk("Setting val %i\n", val);
gpio_set_value(139, 0);
val = 1;
}
}

VI fik LED'erne til at blinke med et interval vi sendte fra userspace med et kald til IOCTL, med numret for den anden IOCTL kommando, hvor vi kunne sætte intervallet for blinket, og den gjorde og alt var godt : ) : ) : ) : )