williamklein
Posts: 5
Joined: Sat Jun 13, 2015 7:58 am

Need help / Kernel module using GPIO

Sat Jun 13, 2015 8:23 am

Hello everyone,

I'm working on a project which is using this kernel module.

As I switched to RPI2 due to performance/power issues, it won't works anymore because of the gpio.h containing RPI1 kernel virtual addresses.

You can find more details about this on the github issue I created.

For now, I've tried 3 ways to get a fix for this :

- Update the addresses from 0xF2000000 to 0x3F000000 according to this documentation
Same behavior as in the github issue.
root@raspberrypi:~/linux-rpi-audi-dis# make
make -C /lib/modules/3.18.14-v7+/build M=/root/linux-rpi-audi-dis modules
make[1]: Entering directory '/root/Downloads/linux'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/root/Downloads/linux'
root@raspberrypi:~/linux-rpi-audi-dis# insmod dis.ko

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.850490] Internal error: Oops: 5 [#1] PREEMPT SMP ARM

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.946595] Process insmod (pid: 2715, stack limit = 0xbb14e238)

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.953620] Stack: (0xbb14fdc0 to 0xbb150000)

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.958968] fdc0: bb14fdec bb14fdd0 7f19903c 7f1973c4 00000000 7f199000 00000000 807e4590

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.969140] fde0: bb14fe84 bb14fdf0 80008834 7f19900c bb14e000 ba674e80 80121724 bb801080
Erreur de segmentation

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.979456] fe00: 3b872000 bc79fe80 bb14fe4c bb14fe18 8012e98c 80524f44 00000002 ba674e80
root@raspberrypi:~/linux-rpi-audi-dis#
Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 101.989813] fe20: bf1c2000 00000002 ba674e80 bf1c2000 00000001 00000001 7f197730 8008e988

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.000194] fe40: bb14fe6c bb14fe50 80121724 8012e784 bb14ff48 7f19773c 00000001 bb14ff48

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.010638] fe60: 7f19773c 00000001 b94dac80 00000001 7f197730 8008e988 bb14ff44 bb14fe88

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.021194] fe80: 800915e0 800087b0 7f19773c 00007fff 8008edb8 ffffffff bb14fee4 bf1c2000

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.031847] fea0: 00000000 7f19773c 00000000 bb14fedc 807e0d70 7f197778 bb14e000 7f1978a0

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.042609] fec0: 00001e3c 806c44f8 bc77ce3c bb14e000 b94f1000 808a46e4 76fe4000 00000000

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.053428] fee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.064317] ff00: 00000000 00000000 00000000 00000000 00000000 00000000 00000080 00001e3c

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.075242] ff20: 76fe4000 76f86948 00000080 8000f028 bb14e000 00000000 bb14ffa4 bb14ff48

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.086168] ff40: 80091da4 8008fdac bf1c2000 00001e3c bf1c2f54 bf1c2dfb bf1c3c1c 00000938

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.097093] ff60: 00000a58 00000000 00000000 00000000 0000001f 00000020 00000017 00000014

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.108019] ff80: 00000010 00000000 00000000 7efb56cc 00000000 77587028 00000000 bb14ffa8

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.118946] ffa0: 8000ed80 80091cc8 7efb56cc 00000000 76fe4000 00001e3c 76f86948 76fe4000

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.129873] ffc0: 7efb56cc 00000000 77587028 00000080 77586f80 00001e3c 76f86948 00000000

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.140800] ffe0: 00000000 7efb5674 76f7dfb4 76ee8e94 60000010 76fe4000 00000000 00000000

Message from syslogd@raspberrypi at Jun 13 10:18:19 ...
kernel:[ 102.206144] Code: e3a01001 e0020011 e1a03103 e383343f (e5931000)
dmesg:
[ 101.833282] Unable to handle kernel paging request at virtual address 3f200004
[ 101.842083] pgd = b94b4000
[ 101.846141] [3f200004] *pgd=00000000
[ 101.850490] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[ 101.856552] Modules linked in: dis(O+) cfg80211 rfkill snd_bcm2835 snd_pcm snd_seq snd_seq_device snd_timer snd 8192cu uio_pdrv_genirq uio
[ 101.870747] CPU: 1 PID: 2715 Comm: insmod Tainted: G O 3.18.14-v7+ #1
[ 101.879925] task: bb1bd080 ti: bb14e000 task.ti: bb14e000
[ 101.886226] PC is at set_output+0x54/0x6c [dis]
[ 101.891671] LR is at init_module+0x3c/0xa8 [dis]
[ 101.897201] pc : [<7f19740c>] lr : [<7f19903c>] psr: 60000013
[ 101.897201] sp : bb14fdc0 ip : bb14fdd0 fp : bb14fdcc
[ 101.910556] r10: bb14e000 r9 : 00000000 r8 : 7f199000
[ 101.916730] r7 : b94dac80 r6 : b94dab80 r5 : 807e4590 r4 : 00000000
[ 101.924226] r3 : 3f200004 r2 : 00007000 r1 : 00000001 r0 : 00001000
[ 101.931718] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 101.939845] Control: 10c5387d Table: 394b406a DAC: 00000015
[ 101.946595] Process insmod (pid: 2715, stack limit = 0xbb14e238)
[ 101.953620] Stack: (0xbb14fdc0 to 0xbb150000)
[ 101.958968] fdc0: bb14fdec bb14fdd0 7f19903c 7f1973c4 00000000 7f199000 00000000 807e4590
[ 101.969140] fde0: bb14fe84 bb14fdf0 80008834 7f19900c bb14e000 ba674e80 80121724 bb801080
[ 101.979456] fe00: 3b872000 bc79fe80 bb14fe4c bb14fe18 8012e98c 80524f44 00000002 ba674e80
[ 101.989813] fe20: bf1c2000 00000002 ba674e80 bf1c2000 00000001 00000001 7f197730 8008e988
[ 102.000194] fe40: bb14fe6c bb14fe50 80121724 8012e784 bb14ff48 7f19773c 00000001 bb14ff48
[ 102.010638] fe60: 7f19773c 00000001 b94dac80 00000001 7f197730 8008e988 bb14ff44 bb14fe88
[ 102.021194] fe80: 800915e0 800087b0 7f19773c 00007fff 8008edb8 ffffffff bb14fee4 bf1c2000
[ 102.031847] fea0: 00000000 7f19773c 00000000 bb14fedc 807e0d70 7f197778 bb14e000 7f1978a0
[ 102.042609] fec0: 00001e3c 806c44f8 bc77ce3c bb14e000 b94f1000 808a46e4 76fe4000 00000000
[ 102.053428] fee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 102.064317] ff00: 00000000 00000000 00000000 00000000 00000000 00000000 00000080 00001e3c
[ 102.075242] ff20: 76fe4000 76f86948 00000080 8000f028 bb14e000 00000000 bb14ffa4 bb14ff48
[ 102.086168] ff40: 80091da4 8008fdac bf1c2000 00001e3c bf1c2f54 bf1c2dfb bf1c3c1c 00000938
[ 102.097093] ff60: 00000a58 00000000 00000000 00000000 0000001f 00000020 00000017 00000014
[ 102.108019] ff80: 00000010 00000000 00000000 7efb56cc 00000000 77587028 00000000 bb14ffa8
[ 102.118946] ffa0: 8000ed80 80091cc8 7efb56cc 00000000 76fe4000 00001e3c 76f86948 76fe4000
[ 102.129873] ffc0: 7efb56cc 00000000 77587028 00000080 77586f80 00001e3c 76f86948 00000000
[ 102.140800] ffe0: 00000000 7efb5674 76f7dfb4 76ee8e94 60000010 76fe4000 00000000 00000000
[ 102.151751] [<7f19740c>] (set_output [dis]) from [<7f19903c>] (init_module+0x3c/0xa8 [dis])
[ 102.162872] [<7f19903c>] (init_module [dis]) from [<80008834>] (do_one_initcall+0x90/0x1d8)
[ 102.173983] [<80008834>] (do_one_initcall) from [<800915e0>] (load_module+0x1840/0x1f1c)
[ 102.184826] [<800915e0>] (load_module) from [<80091da4>] (SyS_init_module+0xe8/0xfc)
[ 102.195313] [<80091da4>] (SyS_init_module) from [<8000ed80>] (ret_fast_syscall+0x0/0x48)
[ 102.206144] Code: e3a01001 e0020011 e1a03103 e383343f (e5931000)
[ 102.213740] ---[ end trace 14cc4bf8d8605f3d ]---
- Switching from this gpio.h file to the wiringPi library and changing related content in dis.c + modifying Makefile
Cannot compile it.
root@raspberrypi:~/test-wiringPi# make
make -C /lib/modules/3.18.14-v7+/build M=/root/test-wiringPi modules -lwiringPi
make[1]: Entering directory '/root/Downloads/linux'
Building modules, stage 2.
MODPOST 1 modules
WARNING: "pinMode" [/root/test-wiringPi/dis.ko] undefined!
WARNING: "wiringPiSetup" [/root/test-wiringPi/dis.ko] undefined!
WARNING: "digitalWrite" [/root/test-wiringPi/dis.ko] undefined!
make[1]: Leaving directory '/root/Downloads/linux'
wiringPi is well working though, here is the output of "gpio readall":
root@raspberrypi:~/test-wiringPi# gpio readall
+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5V | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT0 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT0 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
- Switching from this gpio.h file to this bcm2835.h file and changing related content in dis.c
Cannot compile it.
root@raspberrypi:~/test-bcm# make
make -C /lib/modules/3.18.14-v7+/build M=/root/test-bcm modules
make[1]: Entering directory '/root/Downloads/linux'
Building modules, stage 2.
MODPOST 1 modules
WARNING: "bcm2835_gpio_fsel" [/root/test-bcm/dis.ko] undefined!
WARNING: "bcm2835_gpio_write" [/root/test-bcm/dis.ko] undefined!
make[1]: Leaving directory '/root/Downloads/linux'
This is really overpassing my limited knowledge of linux / kernel modules / RPI.

Sorry for the long post, and I hope someone will help me sort this :)

Cheers,
William

User avatar
joan
Posts: 13294
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 11:51 am

Change the constant to GPIO_BASE. GPIO_BASE should be defined for kernel modules.

williamklein
Posts: 5
Joined: Sat Jun 13, 2015 7:58 am

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 12:50 pm

Seems not:
root@raspberrypi:~/linux-rpi-audi-dis# make
make -C /lib/modules/3.18.14-v7+/build M=/root/linux-rpi-audi-dis modules
make[1]: Entering directory '/root/Downloads/linux'
CC [M] /root/linux-rpi-audi-dis/dis.o
In file included from /root/linux-rpi-audi-dis/dis.c:8:0:
/root/linux-rpi-audi-dis/gpio.h: In function ‘set_output’:
/root/linux-rpi-audi-dis/gpio.h:108:24: error: ‘GPIO_BASE’ undeclared (first use in this function)
/root/linux-rpi-audi-dis/gpio.h:108:24: note: each undeclared identifier is reported only once for each function it appears in
/root/linux-rpi-audi-dis/gpio.h: In function ‘set’:
/root/linux-rpi-audi-dis/gpio.h:125:24: error: ‘GPIO_BASE’ undeclared (first use in this function)
/root/linux-rpi-audi-dis/gpio.h: In function ‘clear’:
/root/linux-rpi-audi-dis/gpio.h:138:24: error: ‘GPIO_BASE’ undeclared (first use in this function)
scripts/Makefile.build:263: recipe for target '/root/linux-rpi-audi-dis/dis.o' failed
make[2]: *** [/root/linux-rpi-audi-dis/dis.o] Error 1
Makefile:1381: recipe for target '_module_/root/linux-rpi-audi-dis' failed
make[1]: *** [_module_/root/linux-rpi-audi-dis] Error 2
make[1]: Leaving directory '/root/Downloads/linux'
Makefile:8: recipe for target 'dis' failed
make: *** [dis] Error 2
According to this post, here is my output :
Hardware : BCM2709
Revision : a01041
Serial : 00000000d7d84d7f
So it really is a Raspberry Pi 2 !

Here is one more source indicating that the base address is 0x3F200000.

How could I have this output ?!
[ 101.833282] Unable to handle kernel paging request at virtual address 3f200004
This is my complete file, any idea ?
// ARM TRM section 3-83, 3-84
// Need a read barrier after the last read from peripheral, and a write barrier before first write to peripheral.
// Not so sure which of these to use but its leaning towards the sync.
#define ARM_DATA_SYNC_BARRIER __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4" : : : "memory")
#define ARM_DATA_MEM_BARRIER __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 5" : : : "memory")

#define GPFSEL0 0x00200000 // GPIO Function Select 0, R/W
#define GPFSEL1 0x00200004 // GPIO Function Select 1, R/W
#define GPFSEL2 0x00200008 // GPIO Function Select 2, R/W

#define GPFSEL_REG(P) (GPFSEL0 + ((GPFSEL1 - GPFSEL0) * ((P) / 10)))
#define GPFSEL_MASK(P) (0x7 << (((P) % 10) * 3))
#define GPFSEL_VALSHIFT(P,V) ((V) << (((P) % 10) * 3))

#define GPFSEL_INPUT 0
#define GPFSEL_OUTPUT 1
#define GPFSEL_ALT0 4
#define GPFSEL_ALT1 5
#define GPFSEL_ALT2 6
#define GPFSEL_ALT3 7
#define GPFSEL_ALT4 3
#define GPFSEL_ALT5 2


// setting

#define GPSET_REG(P) (GPSET0 + ((GPSET1 - GPSET0) * ((P) / 32)))

#define GPSET0 0x0020001C // GPIO Pin Output Set 0, W
#define GPSET1 0x00200020 // GPIO Pin Output Set 1, W
#define GPCLR0 0x00200028 // GPIO Pin Output Clear 0, W
#define GPCLR1 0x0020002C // GPIO Pin Output Clear 1, W

#define GPSET_VALSHIFT(P,V) ((V) ? (1 << ((P) % 32)) : 0)

// clear

#define GPCLR_REG(P) (GPCLR0 + ((GPCLR1 - GPCLR0) * ((P) / 32)))
#define GPCLR_VALSHIFT(P,V) ((V) ? (1 << ((P) % 32)) : 0)

#define KERN_VIRT_ADDR 0x3F000000

void set_output(int);
void set_pin(int);
void clear_pin(int);

// Configures a pin to be an output.
void set_output(int pin)
{
volatile unsigned *p_mem = NULL;
unsigned tmp;

unsigned address = KERN_VIRT_ADDR | GPFSEL_REG(pin);
unsigned mask = GPFSEL_MASK(pin);
unsigned value = GPFSEL_VALSHIFT(pin, GPFSEL_OUTPUT);

ARM_DATA_SYNC_BARRIER;
p_mem = (unsigned *) address;
tmp = *p_mem;
tmp &= ~mask;
tmp |= (value & mask);
*p_mem = tmp;
ARM_DATA_SYNC_BARRIER;
}

// Sets a pin high.
void set(int pin)
{
volatile unsigned *p_mem = NULL;
unsigned address = KERN_VIRT_ADDR | GPSET_REG(pin);
unsigned value = GPSET_VALSHIFT(pin, 1);

ARM_DATA_SYNC_BARRIER;
p_mem = (unsigned *) address;
*p_mem = value;
ARM_DATA_SYNC_BARRIER;
}

// Sets a pin low.
void clear(int pin)
{
volatile unsigned *p_mem = NULL;
unsigned address = KERN_VIRT_ADDR | GPCLR_REG(pin);
unsigned value = GPCLR_VALSHIFT(pin, 1);

ARM_DATA_SYNC_BARRIER;
p_mem = (unsigned *) address;
*p_mem = value;
ARM_DATA_SYNC_BARRIER;
}
I'm missing something and it's driving me crazy :D

User avatar
joan
Posts: 13294
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 1:21 pm

Perhaps you are missing some kernel files or the structure changed between the earlier models and the Pi2.

linux/arch/arm/mach-bcm2708/include/mach/platform.h

Code: Select all

#define BCM2708_PERI_BASE 0x20000000
#define IC0_BASE          (BCM2708_PERI_BASE + 0x2000)
#define ST_BASE           (BCM2708_PERI_BASE + 0x3000)   /* System Timer */
#define MPHI_BASE         (BCM2708_PERI_BASE + 0x6000)   /*  Parallel Host IF */
#define DMA_BASE          (BCM2708_PERI_BASE + 0x7000)   /* DMA controller */
#define ARM_BASE          (BCM2708_PERI_BASE + 0xB000)   /* ARM control blk */
#define PM_BASE           (BCM2708_PERI_BASE + 0x100000) /* Power Mgmnt...*/
#define PCM_CLOCK_BASE    (BCM2708_PERI_BASE + 0x101098) /* PCM Clock */
#define RNG_BASE          (BCM2708_PERI_BASE + 0x104000) /* Hardware RNG */
#define GPIO_BASE         (BCM2708_PERI_BASE + 0x200000) /* GPIO */
#define UART0_BASE        (BCM2708_PERI_BASE + 0x201000) /* Uart 0 */
#define MMCI0_BASE        (BCM2708_PERI_BASE + 0x202000) /* MMC interface */
#define I2S_BASE          (BCM2708_PERI_BASE + 0x203000) /* I2S */
#define SPI0_BASE         (BCM2708_PERI_BASE + 0x204000) /* SPI0 */
#define BSC0_BASE         (BCM2708_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */
#define UART1_BASE        (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */
#define EMMC_BASE         (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */
#define SMI_BASE          (BCM2708_PERI_BASE + 0x600000) /* SMI */
#define BSC1_BASE         (BCM2708_PERI_BASE + 0x804000) /* BSC1 I2C/TWI */
#define USB_BASE          (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB cont */
#define MCORE_BASE        (BCM2708_PERI_BASE + 0x0000)   /* Fake frame buf...*/

williamklein
Posts: 5
Joined: Sat Jun 13, 2015 7:58 am

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 1:28 pm

joan,

Thank you for you help.

FYI, I built my kernel following this tutorial.

As I'm running:
root@raspberrypi:~/linux-rpi-audi-dis# uname -a
Linux raspberrypi 3.18.14-v7+ #1 SMP PREEMPT Wed Jun 10 01:59:14 CEST 2015 armv7l GNU/Linux
I looked into this file: /lib/modules/3.18.14-v7+/build/arch/arm/mach-bcm2709/include/mach/platform.h
#define BCM2708_PERI_BASE 0x3F000000
#define IC0_BASE (BCM2708_PERI_BASE + 0x2000)
#define ST_BASE (BCM2708_PERI_BASE + 0x3000) /* System Timer */
#define MPHI_BASE (BCM2708_PERI_BASE + 0x6000) /* Message -based Parallel Host Interface */
#define DMA_BASE (BCM2708_PERI_BASE + 0x7000) /* DMA controller */
#define ARM_BASE (BCM2708_PERI_BASE + 0xB000) /* BCM2708 ARM control block */
#define PM_BASE (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
#define PCM_CLOCK_BASE (BCM2708_PERI_BASE + 0x101098) /* PCM Clock */
#define RNG_BASE (BCM2708_PERI_BASE + 0x104000) /* Hardware RNG */
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO */
Seems good...

Even if I don't use this constant, addresses seems to be exactly the same!

User avatar
joan
Posts: 13294
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 1:54 pm

I've looked at the last kernel module I wrote. I used ioremap to map the physical address (in your case 0x3f000000) to the kernel virtual address space. Should you be doing that? That's an honest question, this whole area gives me a headache.

williamklein
Posts: 5
Joined: Sat Jun 13, 2015 7:58 am

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 2:47 pm

If I understood well, 0x3F000000 is the kernel virtual address.
Peripherals (at physical address 0x20000000 on) are mapped into the kernel virtual address
space starting at address 0xF2000000. Thus a peripheral advertised here at bus address
0x7Ennnnnn is available in the ARM kenel at virtual address 0xF2nnnnnn.
Do you have any example of your ioremap implementation to help me out?

PS: I can provide a remote access for anyone willing to try...

User avatar
joan
Posts: 13294
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Need help / Kernel module using GPIO

Sat Jun 13, 2015 3:07 pm

I believe 0x3f000000 is a physical address. Perhaps the kernel maps virtual Linux addresses directly to physical addresses.

My code contains

Code: Select all

   uint32_t *gpioRegs;
   ...
   gpioRegs = (uint32_t *)ioremap(GPIO_BASE, GPIO_LEN);
where GPIO_BASE would be 0x3f000000 and GPIO_LEN is 0xB4.

Thereafter I use gpioRegs as the base address of the gpio registers.

williamklein
Posts: 5
Joined: Sat Jun 13, 2015 7:58 am

Re: Need help / Kernel module using GPIO

Sun Jun 21, 2015 3:19 pm

No news here... Can't do it :(

Killertechno
Posts: 130
Joined: Wed Jan 02, 2013 8:28 am

Re: Need help / Kernel module using GPIO

Mon Feb 12, 2018 2:56 pm

Hi guys, I apologize if I'm resuming old discussion, but it's just 3:45pm and I WANNA DIE!!!!!!!!!!!!

I'm newbie about kernel, so to write my custom kernel module I need to take code pieces from several kernel examples and merge it toghether to make kernel module working.
After much work (and much more coffee) I finally get kernel module working..... until next Raspbian.
I need to use Rapberry Compute Module, so I'm testing my hardware on a standard Raspberry. Today I try to compile my kernel module.... and it doesn't compile at all.
Please, help me!!!

Code: Select all



/*
// questo dovrebbe impostarmi i permessi nel character device, ma non mi riconosce il campo .dev_uevent
static int my_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
    add_uevent_var(env, "DEVMODE=%#o", 0440);
    return 0;
}
*/




/*
 * The only file operation we care about is read.
 */

static const struct file_operations adxlsync_fops = {
	.owner		= THIS_MODULE,
	//.dev_uevent        = my_dev_uevent,
	.read		= adxlsync_read,
};

static struct miscdevice adxlsync_dev = {
	/*
	 * We don't care what minor number we end up with, so tell the
	 * kernel to just pick one.
	 */
	MISC_DYNAMIC_MINOR,
	/*
	 * Name ourselves /dev/qcn_sync.
	 */
	"adxl_sync",
	/*
	 * What functions to call when a program performs file
	 * operations on the device.
	 */
	&adxlsync_fops
};


static int __init adxlsync_init(void)
{
	int ret;
	//int rtc;

	/*
	 * Create the "hello" device in the /sys/class/misc directory.
	 * Udev will automatically create the /dev/hello device using
	 * the default rules.
	 */
	ret = misc_register(&adxlsync_dev);
	if (ret)
		printk(KERN_ERR "Unable to register \"ADXL\" device\n");
	else
	{
		printk("Loading QCN-Pi syncing module...\n");
		s_pGpioRegisters = (struct GpioRegisters *)__io_address(GPIO_BASE);
	}

	return ret;
}

module_init(adxlsync_init);
I write my kernel code from here:
https://sysprogs.com/VisualKernel/tutor ... leddriver/
but when compiling I got.

/home/pi/mykernel/qcn_1/qcn_sync.c:250:30: error: implicit declaration of function ‘__io_address’ [-Werror=implicit-function-declaration]
/home/pi/mykernel/qcn_1/qcn_sync.c:250:59: error: ‘GPIO_BASE’ undeclared (first use in this function)
due not available mach/platform.h.
I have no idea about this error (probably something different in kernel/device tree); is there an updated example about driving GPIO pins from kernel?

Second issue:
crw------- 1 root root 10, 58 Feb 12 14:54 /dev/adxl_sync
I can read adxl_sync, I must use sudo.
I've seen following code to change permissions:

Code: Select all

static int my_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
    add_uevent_var(env, "DEVMODE=%#o", 0440);
    return 0;
}

static const struct file_operations adxlsync_fops = {
	.owner		= THIS_MODULE,
	.dev_uevent        = my_dev_uevent,
	.read		= adxlsync_read,
};
But it says .dev_uevent is not a member, is there a way to solve this?
Thanks.

Return to “C/C++”

Who is online

Users browsing this forum: No registered users and 3 guests