Stap 4: Instellen van build-omgeving voor Raspberry Pi
Om te bouwen van een kernelmodule, moeten we de kernel-headers (of kernel bron) die overeenkomen met de binaire image. De koppen bieden essentiële definities die nodig zijn om het compileren van de broncode voor de module. Ook Linux voert een veiligheidscontrole genaamd "versie aanpassing" wanneer het een afgewerkte kernelmodule laadt. De kernelversie en de module versie moeten overeenkomen met hoogstens Linux klaagt, of, in het slechtste geval, Linux weigert om de module te laden.
Ter voorbereiding van je raspberry pi om te compileren van kernelmodule correct de stappen. Eerst sluit uw raspberry pi via SSH (details voor aansluitende Raspberry pi met behulp van PuTTY) op de computer. Typ het volgende
wget https://raw.github.com/raspberrypi/firmware/$FV/extra/git_hash -O k_tmp/git_hash
Maak een map k_tmp/linux door de opdracht
wget https://raw.github.com/raspberrypi/firmware/$FV/extra/Module.symvers -O k_tmp/Module.symvers
Firmware vanaf github.com downloaden
HASH=`cat k_tmp/git_hash` wget -c https://github.com/raspberrypi/linux/tarball/$HASH -O k_tmp/linux.tar.gz
De build-map moeten een kopie van de overeenkomende module versie-informatie voor gebouw. Module versie-informatie wordt opgeslagen in een bestand genaamd /usr/src/linux/Module.symvers. Dit bestand wordt gemaakt tijdens het kernel bouwen — een proces dat 10 + uur op de Raspberry Pi duren zou. Gelukkig, Module.symvers kan ook worden gedownload van github.com. Download Module.symvers bestand
cd k_tmp
Download linux broncode. De gecomprimeerde broncode is over 110MBytes in grootte. Dit is de volledige broncode voor de kernel met inbegrip van alle headers.
tar -xzf linux.tar.gz
Ga naar de gemaakte map-k_tmp
KV=`uname -r` sudo mv raspberrypi-linux* /usr/src/linux-source-$KV
Decomprimeert en pakt de broncode in het gecomprimeerde TAR-bestand
sudo ln -s /usr/src/linux-source-$KV /lib/modules/$KV/build
Verplaatsen naar de src directory
sudo cp Module.symvers /usr/src/linux-source-$KV/
Typ en voer de volgende opdrachten
sudo zcat /proc/config.gz > /usr/src/linux-source-$KV/.config
cd /usr/src/linux-source-$KV/
sudo make oldconfig
de map wijzigen
sudo make prepare
Uitvoeren van oldconfig
sudo make scripts
Instellen van de source tree te bouwen van de kernelmodules
#! /bin/bash # A script to setup the Raspberry Pi for a kernel build FV=`zgrep "* firmware as of" /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | head -1 | awk '{ print $5 }'` mkdir -p k_tmp/linux wget https://raw.github.com/raspberrypi/firmware/$FV/extra/git_hash -O k_tmp/git_hash wget https://raw.github.com/raspberrypi/firmware/$FV/extra/Module.symvers -O k_tmp/Module.symvers HASH=`cat k_tmp/git_hash` wget -c https://github.com/raspberrypi/linux/tarball/$HASH -O k_tmp/linux.tar.gz cd k_tmp tar -xzf linux.tar.gz KV=`uname -r` sudo mv raspberrypi-linux* /usr/src/linux-source-$KV sudo ln -s /usr/src/linux-source-$KV /lib/modules/$KV/build sudo cp Module.symvers /usr/src/linux-source-$KV/ sudo zcat /proc/config.gz > /usr/src/linux-source-$KV/.config cd /usr/src/linux-source-$KV/ sudo make oldconfig sudo make prepare sudo make scripts
Run sudo chmod +x piscope.sh script
./picsope.sh
Als alles correct gedaan van uw Raspberry Pi nu klaar is voor het compileren van kernelmodule.
U kunt alle de opdracht uitvoeren vanaf een interne bash-script, daarvoor #include<linux/kernel.h> #include<linux/module.h> #include<linux/fs.h> #include<asm/uaccess.h> #include<linux/time.h> #include<linux/io.h> #include<linux/vmalloc.h> int init_module(void); void cleanup_module(void); static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static ssize_t device_write(struct file *, const char *, size_t, loff_t *); #define SUCCESS 0 #define DEVICE_NAME "chardev" #define BUF_LEN 80 /* setting and macros for the GPIO connections */ #define BCM2708_PERI_BASE 0x20000000 #define GPIO_BASE (BCM2708_PERI_BASE + 0x20000000) #define INP_GPIO(g) *(gpio.addr + ((g)/10)) &= ~(7<<(((g)%10)*3)) #define SET_GPIO_ALT(g,a) *(gpio.addr + (((g)/10))) |= (((a)<=3?(a) + 4:(a)==4?3:2)<<(((g)%10)*3)) /* GPIO clock */ #define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) #define GZ_CLK_BUSY (1 << 7) /* Number of samples to capture */ #define SAMPLE_SIZE 10000 /* Define GPIO pins */ /* ADC 1 */ #define BIT0_PIN 7 #define BIT1_PIN 8 #define BIT2_PIN 9 #define BIT3_PIN 10 #define BIT4_PIN 11 #define BIT5_PIN 25 /* ADC 2 */ #define BIT0_PIN2 17 #define BIT1_PIN2 18 #define BIT2_PIN2 22 #define BIT3_PIN2 23 #define BIT4_PIN2 24 #define BIT5_PIN2 27 struct bcm2835_peripheral { unsigned long addr_p; int mem_fd; void *map; volatile unsigned int *addr; }; static int map_peripheral(struct bcm2835_peripheral *p); static void unmap_peripheral(struct bcm2835_peripheral *p); static void readScope(void); static int Major; static int Device_Open = 0; static char msg[BUF_LEN]; static char *msg_Ptr; static unsigned char *buf_p; static struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; static struct bcm2835_peripheral myclock = {CLOCK_BASE}; static struct bcm2835_peripheral gpio = {GPIO_BASE}; struct DataStruct{ uint32_t Buffer[SAMPLE_SIZE]; uint32_t time; }; struct DataStruct dataStruct; static unsigned char *ScopeBufferStart; static unsigned char *ScopeBufferStop; static int map_peripheral(struct bcm2835_peripheral *p){ p->addr=(uint32_t *)ioremap(GPIO_BASE, 41*4); return 0; } static void unmap_peripheral(struct bcm2835_peripheral *p){ iounmap(p->addr); } static void readScope(){ int counter=0; struct timespec ts_start, ts_stop; local_irq_disable(); local_fiq_disable(); getnstimeofday(&ts_start); while(counter<SAMPLE_SIZE){ dataStruct.Buffer[counter++]= *(gpio.addr + 13); } getnstimeofday(&ts_stop); local_fiq_enable(); local_irq_enable(); dataStruct.time = timespec_to_ns(&ts_stop) - timespec_to_ns(&ts_start); buf_p = (unsigned char*)&dataStruct; ScopeBufferStart = (unsigned char*)&dataStruct; ScopeBufferStop = ScopeBufferStart + sizeof(struct DataStruct); } int init_module(void){ struct bcm2835_peripheral *p=&myclock; int speed_id = 6; Major = register_chrdev(0, DEVICE_NAME, &fops); if(Major < 0){ printk(KERN_ALERT "Reg. char dev fail %d\n",Major); return Major; } printk(KERN_INFO "Major number %d.\n", Major); printk(KERN_INFO "created a dev file with\n"); printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); if(map_peripheral(&gpio) == -1){ printk(KERN_ALERT "Failed to map GPIO\n"); return -1; } INP_GPIO(BIT0_PIN); INP_GPIO(BIT1_PIN); INP_GPIO(BIT2_PIN); INP_GPIO(BIT3_PIN); INP_GPIO(BIT4_PIN); INP_GPIO(BIT5_PIN); INP_GPIO(BIT0_PIN2); INP_GPIO(BIT1_PIN2); INP_GPIO(BIT2_PIN2); INP_GPIO(BIT3_PIN2); INP_GPIO(BIT4_PIN2); INP_GPIO(BIT5_PIN2); /* set clock signal to pin 4 */ p->addr=(uint32_t *)ioremap(CLOCK_BASE, 41*4); INP_GPIO(4); SET_GPIO_ALT(4,0); *(myclock.addr+28)=0x5A000000 | speed_id; while(*(myclock.addr+28) & GZ_CLK_BUSY){}; *(myclock.addr+29)= 0x5A000000 | (0x32 << 12) | 0; *(myclock.addr+28)=0x5A000000 | speed_id; return SUCCESS; } void cleanup_module(void){ unregister_chrdev(Major, DEVICE_NAME); unmap_peripheral(&gpio); unmap_peripheral(&myclock); } static int device_open(struct inode *inode, struct file *file){ static int counter = 0; if(Device_Open) return -EBUSY; Device_Open++; sprintf(msg, "Called device_open %d times\n",counter++); msg_Ptr = msg; readScope(); try_module_get(THIS_MODULE); return SUCCESS; } static int device_release(struct inode *inode, struct file *file){ Device_Open--; module_put(THIS_MODULE); return 0; } static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t *offset){ int bytes_read = 0; if(*msg_Ptr == 0) return 0; while(length && buf_p < ScopeBufferStop){ if(0!=put_user(*(buf_p++), buffer++)) printk(KERN_INFO "Problem with copy\n"); length--; bytes_read++; } return bytes_read; } static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off){ printk(KERN_ALERT "This operation is not supported.\n"); return -EINVAL; } een script en open met behulp van nano
sudo nano piscript.sh
en typ de volgende opdracht
#! / bin/bash # A script om setup van de Raspberry Pi voor een kernel bouwen sudo nano Makefile.sh mkdir -p k_tmp/linux <code> obj-m += Scope-drv.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean wget https://raw.github.com/raspberrypi/firmware/ $FV/extra/Module.symvers - O k_tmp/Module.symvers make CD k_tmp sudo insmod . /Scope-drv.ko KV = 'uname - r' sudo mv raspberrypi-linux * /usr/src/linux-source-$ KV sudo mknod /dev/chardev c 248 0 sudo cp Module.symvers /usr/src/linux-source-$ KV / <code> #include<iostream> #include<cmath> #include<fstream> #include<bitset> typedef unsigned int uint32_t; const int DataPointsRPi=10000; struct DataStructRPi{ uint32_t Buffer[DataPointsRPi]; uint32_t time; }; int main(){ struct DataStructRPi dataStruct; unsigned char *ScopeBufferStart; unsigned char *ScopeBufferStop; unsigned char *buf_p; buf_p=(unsigned char*)&dataStruct; ScopeBufferStart=(unsigned char*)&dataStruct; ScopeBufferStop=ScopeBufferStart+sizeof(struct DataStructRPi); std::string line; std::ifstream myfile ("/dev/chardev"); if(myfile.is_open()){ while(std::getline(myfile,line)){ for(int i=0;i<line.size();i++){ if(buf_p>ScopeBufferStop) std::cerr<<"buf_p out of range!"<<std::endl; *(buf_p)=line[i]; buf_p++; } } myfile.close(); } else std::cerr<<"Unable to open file"<<std::endl; double time = dataStruct.time/(double)DataPointsRPi; for(int i=0;i<DataPointsRPi;i++){ int valueADC1 = 0; int tmp = dataStruct.Buffer[i] & (0b11111<<(7)); valueADC1=tmp>>(7); tmp = dataStruct.Buffer[i] & (0b1<<(25)); valueADC1+=(tmp>>(20)); int valueADC2 = 0; tmp = dataStruct.Buffer[i] & (0b11<<(17)); valueADC2 = tmp>>17; tmp = dataStruct.Buffer[i] & (0b111<<(22)); valueADC2+=(tmp>>20); tmp = dataStruct.Buffer[i] & (0b1<<(27)); valueADC2+=(tmp>>22); std::cout<<i*time<<"\t"<<valueADC1*(5./63.)<<"\t"<<valueADC2*(5./63.)<<std::endl; } return 0; } cd /usr/src/linux-source-$ KV / g++ -o readout readout.cpp sudo ./readout > data.txt bereiden sudo apt-get install -y gnuplot-x11<br>
Maak het bestand uitvoerbaar met de opdracht
<code> set key inside right top set title "ADC readout" set xlabel "Time [ns]" set ylabel "Voltage [V]" plot "data. txt" using 1: 2 title ' ADC1' with lines, \ "data. txt" using 1: 3 title ' ADC2' with lines
Uitgevoerd met behulp van het bestand
curl -SLs https://apt.adafruit.com/add-pin | sudo bash
Gedaan!
U kunt ook de piscope.sh bestand uploaden naar de Raspberry Pi met behulp van FTP-client.