Ich habe versucht, Zugriff auf GPIO2 und GPIO3 auf dem Beaglebone Black über Kernel-Modul ohne Erfolg. Jedes Mal, wenn ich versuche, den GPIOs 2 und 3 einen Ausgabewert zuzuweisen, erhalte ich einen Segmentierungsfehler.Warum bekomme ich bei Beaglebone Black beim Zugriff auf GPIO2 und GPIO3 durch Kernelmodul einen Segmentierungsfehler?
Der exakt gleiche Code (mit der entsprechenden Pinbelegung) funktioniert für GPIO0 und GPIO1.
Ich habe versucht, verschiedene Pins auf P8 und P9 im Zusammenhang mit GPIO2 und GPIO3 ohne Erfolg. Auf der anderen Seite funktioniert derselbe genaue Code für GPIO0 und GPIO1 mit entsprechender Pinbelegung.
Für Pin-Werte verwende ich das offizielle BBB-Handbuch. Für eine entsprechende E/A-GPIO Verfügbarkeit Ich bin Überprüfung dieses Diagramm von beagleboard.com:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <net/tcp.h>
//Macros
#define GPIO1_START_ADDR 0x4804C000
#define GPIO2_START_ADDR 0x481AC000
#define GPIO2_END_ADDR 0x481ACFFF
#define GPIO3_START_ADDR 0x481AE000
#define SIZE (GPIO2_END_ADDR - GPIO2_START_ADDR)
#define GPIO_OE 0x134
#define GPIO_DATAOUT 0x13C
//A couple of standard descriptions
MODULE_LICENSE("GPL");
static int hello_init(void)
{
volatile void *gpio_addr;
volatile unsigned int *oe_addr;
volatile unsigned int *dataout_addr;
printk(KERN_NOTICE "Module: Initializing module\n");
printk(KERN_NOTICE "Module: Map GPIO\n");
gpio_addr = ioremap(GPIO3_START_ADDR,SIZE);
printk(KERN_NOTICE "Module: Set oe_addr\n");
oe_addr = gpio_addr + GPIO_OE;
printk(KERN_NOTICE "Module: Set dataout_addr\n");
dataout_addr = gpio_addr + GPIO_DATAOUT;
//Code will work up to here for any GPIO.
//It crashes on the following for GPIO2 and GPIO3:
printk(KERN_NOTICE "Module: Set pin to OUTPUT\n");
*oe_addr &= (0xFFFFFFFF^(1<<19));
printk(KERN_NOTICE "Module: Set pin output to HIGH\n");
*dataout_addr |= (1<<19);
return 0;
}
static void hello_exit(void)
{
printk(KERN_INFO "Exit module.\n");
}
module_init(hello_init);
module_exit(hello_exit);
Wenn ich die beiden Linien *oe_addr &= (0xFFFFFFFF^(1<<19));
und *dataout_addr |= (1<<19);
blockieren, läuft das Programm für alle GPIOs ohne Panne.
$uname -a: Linux beaglebone 3.8.13-bone79
Warum bin ich Segmentierungsfehler bekommen, wenn GPIO2 und GPIO3 zugreifen?
"_Ist ich die zwei Zeilen aussperren, läuft das Programm für alle GPIOs ohne Glitch._" ... Wenn Sie das tun, dann wird der IO überhaupt nicht zugegriffen !? Außerdem ist dies kein realer Code - 'module_init()' und 'module_exit()' werden außerhalb jeder Funktion "aufgerufen", was nicht möglich ist. Wenn der Code nicht real ist, wie können wir dann darauf vertrauen, dass der Fehler auftritt? – Clifford
@Clifford Was meinst du, es ist kein Code? Es läuft. Ich habe eine LED an einem der Pins und die LED schaltet sich an, wenn ich es betreibe. So werden Kernel-Module formatiert. module_init (arg) wird aufgerufen, wenn das Modul eingefügt wird, und module_exit (arg) wird aufgerufen, wenn das Modul entfernt wird, wobei arg die Funktion ist, auf die diese Makros zeigen. – CallMeTheMan
Ich denke (von einem schnellen Google), dass Sie 'request_mem_region()' vor 'ioremap()' aufrufen müssen. – Clifford