This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM3359:在内核空间中使用 I2C

Guru**** 2935310 points

Other Parts Discussed in Thread: AM3359

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/669811/linux-am3359-using-i2c-from-kernel-space

器件型号:AM3359

工具/软件:Linux

您好!

我希望通过内核空间中 AM3359 ICE V2连接器 J3的引脚4和6与 I2C 器件通信。 我尝试通过直接修改寄存器来实现它。 以下是我的代码:

#include 
#include 
#include 
#include 
#include //对于 iomap

module_license ("GPL");
module_Author ("Vincent Paratte");
module_description ("I2C test");
module_version ("0.1");

#define base_address 0x44E0B000//存储器映射的初始地址
#define base_size 0x100//存储器映射地址的大小
#define prescaler 0x1//预分频器将时钟设置为12MHz 而不是24MHz
#define prescaler_offset 0xB0// I2C_PSC 寄存
器#define 0xLL 从 base_address 的偏移量#SCLL 0x8/define T_low 时钟时间(SCK)至1.25us (400Kbps):1.25u*12M-7
#define SCLL_OFFSET 0xB4// I2C_SCLL 寄存
器#define SCLH 0xA 的 BASE_ADDRESS 偏移//将 t_LOW 时钟时间(SCK)定义为1.25us (400Kbps): 1.25u*12M-5
#define SCLH_OFFSET 0xB8// I2C_SCLH 寄存器的 BASE_ADDRESS 偏移
#define CONF_RECEIVER 0x10000//配置为具有7位地址模式、主模式、启用 I2C 并切换到接收器模式
#define CONF_RECEIVER 0x10100//配置为具有7位地址模式、主模式、主模式、 启用 I2C 并切换到收发器模式
#define CONF_OFF 0x0//配置以禁用 I2C
#define CONF_OFFSET 0xA4// I2C_CON 寄存器
#define SLAVE_ADDRESS 0x55的 BASE_ADDRESS 偏移量//从
I2C_SA 寄存
器#define NB_BYTE 0x2的 BASE_ADDRESS 偏移量//设置字节编号 读取/写入 I2C_CNT
寄存
器#define NBR_BYTE_OFFSET 0x98 //从 BASE_ADDRESS 偏移量0x24//从 BASE_ADDRESS 偏移量以访问 IRQSTATUS_RAW 寄存器(总线忙时位12为高电平)
#define DATA_OFFSET 0x9C//从 BASE_ADDRESS 偏移量以访问数据(位0_STATUS_RAW 寄存器

*静态位0位7)

static int __init i2c_init (void)
{
static u8 counter = 0;
static u8 data = 0xAA;
static u32 BUSY = 0;

// I2C

printk 的配置("I2C 总线的启动配置\n");

base = ioremap (base_address、base_size);//内存映射可访问寄存
器 icalower + prescaler (32)、offset//将时钟设置为12MHz
iowrite32 (SCLL、base + SCLL_offset);//通过应用 t_High = t_Low = 2.5us
iowrite32 (SCLH、base + SClH_offset);
iowrite32 (CONF_receiver、
base + CONF_offset)设置为400Kbps;//将 iowrite32 (it_master_offset)作为 iowritereceiver、i_offset 作为 i_master_offset、i_master_offset//设置从设备
iowrite32 (NBR_byte、base + NBR_byte_offset)的地址;//将原始设备中要读取/写入的字节数量设置为2 (8位)

printk ("配置完成\n");
iowrite32 (CONF_triver、base + CONF_offset);//设置为
收发器("已激活的 printk!"模式!

while (计数器< 10)
{
BUSY = oread16 (base + CONF_OFFSET);//如果总线繁忙
((((BUSY && 0x1000)>> 12)= 0)//如果繁忙位= 0 ->总线不繁忙
{
printk ("总线空\n");
mdelay (1000);
iowbase_offset (32);iowdata.//写入数据
printk ("AA write\n");
mdelay (1000);
}
else printk ("Bus busy\n");
计数器++;
mdelay (2000);
}
return 0;
}

static void __exit iinit_exit (void)
{
iowrite8 (CONF_OFF、base + CONF_offset);// isit
(2000);

}return 0;}static void i2c (it_exit i2c_exit iunc)


;irom_it_exit (i2c)模块(i2c);/ irom_isit (i2c)模块(isc);退出 i_is 

代码使用 make 正确编译、但当我用 insmod 发送代码时、代码会在行<< printk ("收发器模式已激活!\n");>>后停止

我想、我尝试读取(使用 oread16)一个不存在的地址、但我仔细检查寄存器的数量、看起来一切正常。

以下是我的代码的答案:

insmod I2C.ko
[43.447017]启动 I2C 总线[43.451574]配置
完成
[43.4546464]收发器模式已激活!
[43.473560]未处理故障:在0xf9e0b0d1
[43.473567] PgD = ce0f8000
[43.4735788][f9e0b0d1]*PgD=44e11452 (bad)[43.473591]

内部链接模块[#471028]: I2C (O+) pvrsrvkm (O) PRU_rproc pruss_INTC pruss_SHA512_generic SHA256_generic SHA1_generic SHA1_ARM_NEON SHA1_ARM MD5 ti_AM335x_ADC des_gc cc gc multi USB_f_mass storage usb_f_ssp_ip_t_gc w_ip_msp_m_gc ip_ip_m_cr_t_msp4 ip_msp_m_mspu ipt_mspu ipt_m_msp4 ipt_m_mspu ipt_m_mspu ipt_msp4 p_m_mspu ipt_m_m_mspi_mspu ipt_mspu ipt_mspu ipt_mspu ipt_mspu ipt_g3 ipt_mspu ipt_g3 ipt_g3 ipt_mspot_ipt_mspu ipt_mspu ipt_ipt_mspu p INPUT_POLST_FQ_CODEL uio_MODULE_drv (O) uio cryptodev (O)
[43.473738] CPU:0 PID:836 Comm:insmod 已污染:g w o 4.9.59-rt23-g273202a0d3 #10
[43.473742]硬件名称:通用 AM33XX (平展设备树)
[43.473748]任务:ce7e8d00 task.stack:ce6b6000
[43.473771] PC 位于 DO_alignment_ldrhstrh+0x4785][0x43785] PC
位于0x471rr[0x473cr 43785][43.457cr [43.47377cr [43.473773771] PC 位于 dr+0x471cr [0x47
] lr:[<00000001>] psr:000f0113
[43.473785] sp:ce6b7bb8 IP:00000003 fp:ce6b7bcc
[43.473790] r10:00000000 R9:00000004 R8:00000001
[43.473795] r7:f9e0b3r4
:0000r4:0000r4:0000000r4:0000r3 ce6b7d50 R1:e1d330b0 r0:f9e0b0d1
[43.473809] Flags: nzcv 在模式 SVC_32 ISA ARM 段上的 FIQ [
43.473815]控制:10c5387d 表:8e0f8019 DAC:00000001
[ 43.473826 ]
堆栈[ 0x438736](0xc387b 堆栈:0x386b)




1978 6b7d50 c0c492cc [43.473850] 7bc0:ce6b7c9c ce6b7bd0 c0115c34 c0115270 000000000001 ce6b7bf4 ce6b7be8 [43.473863] 7be0:c047a060 501c0001c40 c2000 c40 c2000 c24b7c24c2000 c24c24c2000 c24c24c24c24c24c24c24c24c24c24c24c20c24c24c24c24c24c24c24c24c24c24c24c20c24c24c24c24c24c24c24c24c24c24c24c20c24c24c24c24c24c24c24c24c24c24c24c24c24c20c24c24c24c24c24c24c24c24c24c24c24c24c24c24c24c24c24c24c24c20c24c24c24c24c24c24c
00000000 00000000 ce6b7c64 ce6b7c58 c0477ff8 c047cce8 ce6b7c8c ce6b7c68
[43.473916] 7c60:ce6b7c70 c01a09e0 c01883dc c6b7c8c [43.003916] 7c60:ce6b7c7c70 c70c0001c0001c0001c0001
c0001 c0001 c0001 c0001 c0001 c0001 c0001 c0001 c0001 c0001 c0006

600f0013 00000000 0000001b 00000002 00000004 c0c12140 00000000
[43.473967] 7ce0:c6b7d4c ce6b7cf0 c0164054 c016363c 00000000 00000000 00000000
[43.473980]7d00:c0c6b7ffc c6b7c4006 c0600c1000000
6b4006 b4006 b400d 600c6 b4000000
[6b7dc4 ce6b7d50 c010c138 c01012d4 0000001b c0c121dc 00000000 f9e0b0d1
[43.474019] 7d60:bf25e2c0 f9e0b02d 00001e3180 bf25e100 bf2600000000 1e100bc1007e1007e100bc100b4000
e1007bc1007b4000 e100b4001 e100b4001 e100b4001 b4002 e100b4001 b4001 b4001 b4001 b4001 b4001 b4002 e100c100b4001 b4001 e100b4002 e100b4002 e100b4001 b4001 b4001 b4001 b4001 b4001 b4001

c01016f8 bf26000c ce1e3180 d0e85000 00000001 ce6b7e24 ce6b7de8
[43.474071] 7de0:c01bdf50 c0780f48 c03bb080 00000001 ce1e3964 00000000 [43.474071be100 ce07480 cce4b3b4001 ce2c100e2e2c100e2e2c100e2e2e2c100e2e2e2c100e2c100e2e2e2e2e100e2e2e2e2e2e100e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e100:c100e2e2e2e2e2e2e2e2


c01b483c c01016bc ce1e3940 bf25e100 ce6b7e6c ce6b7f44 00000001 ce1e3940
[43.474124] 7e60:ce6b7fe100b7e70 c01910a4 c01b47e0 bf2510c 7c100b017000000 e100be2b07224100be100be100be0b0b0b07224100b0be100b000000 e100b0b0b0b0b0b0b0b0c100b0c100b000000 e2c100b0c100b0c100b0c100b0c100b0c100b0c100b000000 e100b0c100b0c100b0c100b0c100b0c100be100b0c100be100be100be2c100b0c100b0c100b0c100be100b000010a0c100b0


00000000 00000000
[43.474175] 7e0:00000000 00000000 00000000 00000000 7ffff 00000000
[43.474188] 7f00:00027dc4 c0107b04 ce6b6000 ce6b7f40 00000000 6b7f20 000016dc 1916c 7f400:000240003b4000240003b4000080
e0003b4000240003b4000d400080000

00000000 00000000 00000000 0000065c 00000012 00000013 0000000b 00000009
[43.474240] 7f80:00000007 00000000 0003a008 00000000 00025a74 0000017b 00000000 ce6b7fa8
[43.474253] 7fa0:c0107940 c0191654 0003a008 0000000700000004 00000004 00000004
00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000004 00000002 00000004 00000004 0002 00000004 00000004 0002 00000004 00000004 00000002
bef7cae8 bef7cad8 0001f57c b6f3a9f2 80070030 00000003 00000000 00000000
[43.474283]回溯:
[43.474302][ ](do_alignment_ldrhstrh)、从[ ](DO_alignment+0x110/0x738)
[43.474310] R5:c0c492cc R4:ce6b7d50
[ 43.474323][ ](DO 对齐)从[ ](DO_DataAbort+0x40/bb)
[43.474336] R10:ce1e3948 R9:ce6b6000 R8:ce6b7d50 r7:c086b0 R6:f9e0b0d1 r5:c0115b24
[43.474340] r4:00000001
[43.44751] ](DO 数据中止)从[ ](_dabt_Svc+0x58/0x80)
[43.474356]异常堆栈(0xce6b7d50至0xce6b7d98)
[43.474364] 7d40: 0000002600c121dc 00000000 f9e0b0d1
[43.474377] 7d60:bf25e2c0 f9e0b02d ce1e3180 bf25e100 bf260000 ce1e3948 c66b7dc4
[43.474388] 7d80:ce6b600e100e100b00000000 ce1e3948 ce6bf 3948 ce6bffff 6b7b7b7dc6
b4004:c6rf6 b400rf6 b400r4 rf6 b400rf6 b400r4 b400r4 bf400r4 rf6 b400r4 rf6 bf6 b400r4 bffff 7r4 b400r4 bc6 b7r4 bc6 bc6 b
](i2c_init [I2C])、来自[ ](do_One_initcall+0x48/0x178)
[43.474440] R9:00000000 R8:bf260000 r7:bf25e100 R6:ce1e3180 R5:00000001 R4:bf25e100
[43.474463][ ](多个_initcall)、来自[ ](DO_INIT_MODULE+0x68/0x1cc)
[43.474476] R10:ce1e3948 R9:ce1e3964 R8:00000001 r7:bf25e100 R6:ce1e3180 R5:00000001
[43.474480] R4:bf25e100
[ 43.474497][ ](DO_INIT_MODULE)从[ ](LOAD_MODULE+0x1b60/0x1fc0)
[43.474505] R6:ce1e3940 R5:00000001 R4:ce6b7f44
[43.474517][ ](LOAD_MODULE)从[ ](SYS_FINIT_MODULE+0x94/0xa4)
[43.474530] R10:00000000 R9:ce6b6000 R8:c0107b04 r7:00027dc4 R6:00000000 R5:00000000
[ 43.474533] R4:7ffffff
[ 43.474550][ ](sys_finIT_module)从[ ](ret_FAST_SYSCALL+0x0/0x44)
[43.474559] r7:0000017b R6:00025a74 R5:00000000 R4:0003a008
[43.474572]代码:0a00000c e2113601 0a000032 e3a03000 (e4d0c001)[3.34752]


@

内部消息:AM3352]


从 AM3352[LM312-213广播@

到 AM3352]内部消息源代码:AM3352](UCC13423:13423:13423:13423:13423:13423:13423:13423:13423:13423:30423:13423:13423:13423:13423:13423:13423:13423:13423:13423:13433423:13423:13423:13423 836、stack limit = 0xce6b6208)


来自 systemd-journald@AM335x-EVM 的广播消息(Sat 2017-12-23 13:52:49 UTC):

kernel[318]:[43.473826] stack:(0xce6b7bb8至0xce6b8000)


来自 systemd-journald@AM335x-23EVM 的广播消息(UTC:43836:UTC

:412-4736:UTC:423[UTC] ce6b7d50 c0c492cc

有人知道什么问题吗? 我从未更改过 DTS 文件的 I2C 部分、I2C 正与 I2C-dev 一起在用户空间工作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Vincent、

    BUSY_OFFSET 不正确。 请将 BUSY = oread16 (base + CONF_OFFSET)更改为 BUSY = oread16 (base + BUSY_OFFSET);

    此致、
    Kemal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的回答。 遗憾的是、即使进行了此校正、仍会出现相同的错误消息。 问题似乎来自配置、因为每次我尝试读取寄存器(该寄存器或另一个寄存器)时、我都会遇到相同的问题。

    我的 DTS 配置如下所示。 有什么特别需要改变的地方吗? (在用户空间中工作)

    在 AM335x-icev2.DTS 中:
    
    [...]
    
    i2c0_PINS_DEFAULT:i2c0_PINS_DEFAULT{
    pinctrl-single、PINS =<
    AM33XX_IOPAD (0x988、PIN_INPUT | MUX_MODE0)/*(C17) I2C0_SDA.I2C0_SDA */
    AM33XX_IOPAD (0x98c、PIN_INPUT | MUX_C16
    )
    *[* I2C0_MODE0_];[*[_I2C0_MODE0_]
    
    
    
    &i2c0{
    pinctrl-names ="default";
    pinctrl-0 =<&i2c0_pins_default>;
    
    状态="oke";
    时钟频率=<400000>;
    
    TPS:电源控制器@2D{
    reg =<0x2D>;
    };
    
    tpic2810:GPIO@60{
    compatible ="ti、tpic2810>
    
    
    ;<gpiccontroller=<0x60>;}gpic-cells
    = 0x60>
    
    pca9536:GPIO@41{
    compatible ="ti、pca9536";
    reg =<0x41>;
    GPIO 控制器;
    #gpio-cells =<2>;
    };
    };
    
    在 am33xx.dtsi 中:
    
    i2c0:I2C@44e0b000{
    compatible ="ti、OMAP4-i2c";
    #address-cells =<1>;
    #size-cells =<0>;
    ti、hwmods ="i2c1";
    reg =<0x44e0b000 0x1000>;
    中断=<70>
    ;状态="禁用
    "} 

    此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我再次尝试使用 I2C 在用户空间工作、显然我在该空间也遇到了问题。 我使用以下简单代码:

    包含 
    #include 
    #include 
    #include 
    #include 
    
    int 设备;
    
    int main()
    {
    设备= open ("/dev/i2c-0、O_RDWR);//打开 I2C0文件
    ioctl (设备、I2C_slave、0x42);//将0x40设置为从
    
    器件无符号 char 缓冲区的地址[60];
    
    while (1)
    {
    buffer[0]= 0x01;
    buffer[1]= 0x02;
    if print2 (
    2)、usf);ther\1000 (buler\f1)(buler\1000);if cer\f2 (bultry\f)(bule\f)、problemt (2)(写入)
    
    

    我始终会收到消息"写入问题"、这意味着我无法访问以写入2个元素。 当我查看示波器时、我有一个看起来像地址的内容(如果我更改地址、它会有所不同、但它不对应于正确的从器件地址)、但之后没有其他字节。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    e2e.ti.com/.../t.cIn用户空间您不使用读/写。 而是使用 ioctl 进行读取/写入。 我附加了一个通过 i2c 读取数据的小型程序。

    Steve K.