ビーグルボーンブラックのGPIO2とGPIO3へのアクセスをカーネルモジュールで成功させようとしています。 GPIO 2とGPIO 3に出力値を割り当てようとするたびに、セグメンテーションフォルトが発生します。カーネルモジュール経由でGPIO2とGPIO3にアクセスするとBeaglebone Blackでセグメンテーションフォルトが発生するのはなぜですか?
GPIO0とGPIO1では全く同じコード(適切なピン割り当て)が機能します。
私は、GPIO2とGPIO3に関連するP8とP9の両方にさまざまなピンを試してみましたが、成功しませんでした。フリップ側では、GPIO0とGPIO1では、ピン割り当てが適切な場合と同じコードが機能します。
ピン値については、公式のBBBマニュアルを使用しています。適切なI/O GPIOの可用性のために私は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);
を私は2つのライン *oe_addr &= (0xFFFFFFFF^(1<<19));
と *dataout_addr |= (1<<19);
を遮断した場合、プログラムはグリッチなしで、すべてのGPIOのために実行されます。
$uname -a: Linux beaglebone 3.8.13-bone79
GPIO2とGPIO3にアクセスしたときに、なぜ私がセグメンテーションフォールトを取得していますか?
"_私が2本のラインをブロックすると... [...]プログラムはグリッチなしですべてのGPIOで実行されます。" ...そうすると、IOは全くアクセスされません!さらに、これは実際のコードではありません。 'module_init()'と 'module_exit()'は関数の外部で呼び出されますが、これは不可能です。コードが実際ではない場合、どのようにして障害が発生すると信じることができますか? – Clifford
@Cliffordコードではないということはどういう意味ですか?それは動く。ピンの1つにLEDが付いていて、走ったときにLEDが点灯します。これがカーネルモジュールのフォーマット方法です。 module_init(arg)は、モジュールが挿入されたときに呼び出され、moduleが削除されたときにmodule_exit(arg)が呼び出されます。argは、これらのマクロが指し示す関数です。 – CallMeTheMan
私は(早いグーグルから) 'ioremap()'の前に 'request_mem_region()'を呼び出す必要があると思います。 – Clifford