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.

Need general Linux help --How to send data from pwm kernel driver to userspace application

Other Parts Discussed in Thread: AM3352

HI ,

We are using AM3352 processor -- SDK-08 and linux kernel version is 3.14.

we are using pwm-capture driver to read the fanspeed in rpm and that data we want to send to user space application.

#1: This feature is not available/included in SDK-08 -- but i modified the drivers/pwm/sysfs.c and core.c and added few functions --

     -- here fanspeed value rpm which is 4 bytes data i need to sent to userspace application.

we tried with copy_to_user -- but it is throwing error -- 

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

char array[10];


void main()
{
int fd = 0;
char status=0;

fd= open("/sys/class/pwm/pwmchip0/pwm0/ecap_get_rpm", O_RDWR);

printf("fd:%d \n",fd);

status = read(fd, array, 4);
printf("status :%d \n",status);

}

error log:

root@am335x-evm:/usr# ./test-pwm
fd:3
[ 57.115106] pwm_ecap_get_rpm_show:
[ 57.118900] ecap_pwm_get_value:
[ 57.123449] rpm:3000
[ 57.125766] ret:4
[ 57.127796] get:value:0 0 0 0
[ 57.131675] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 57.140184] pgd = cc480000
[ 57.143103] [00000000] *pgd=8f687831, *pte=00000000, *ppte=00000000
[ 57.149735] Internal error: Oops: 817 [#1] ARM
[ 57.154402] Modules linked in: musb_dsps musb_hdrc pvrsrvkm(O) cryptodev(O) musb_am335x libcomposite configfs
[ 57.164895] CPU: 0 PID: 1628 Comm: test-pwm Tainted: G O 3.14.26-g2489c02-dirty #274
[ 57.173944] task: cf7b3400 ti: cf7f8000 task.ti: cf7f8000
[ 57.179641] PC is at pwm_ecap_get_rpm_show+0x68/0x94
[ 57.184878] LR is at wake_up_klogd+0x3c/0x48
[ 57.189370] pc : [<c02930e8>] lr : [<c00623a0>] psr: 000f0013
[ 57.189370] sp : cf7f9e40 ip : cf7f9d60 fp : cf7f9e5c
[ 57.201419] r10: c05fc53c r9 : cf4e1000 r8 : 00001000
[ 57.206906] r7 : 00000fff r6 : cf074a00 r5 : cf2421c0 r4 : cf4e1000
[ 57.213760] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : c07497a8
[ 57.220619] Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 57.228112] Control: 10c5387d Table: 8c480019 DAC: 00000015
[ 57.234147] Process test-pwm (pid: 1628, stack limit = 0xcf7f8238)
[ 57.240650] Stack: (0xcf7f9e40 to 0xcf7fa000)
[ 57.245242] 9e40: 00000000 cf000400 cf5ae080 c083971c cf7f9e74 cf7f9e60 c035af08 c029308c
[ 57.253840] 9e60: cf5ae080 cf50b008 cf7f9ea4 cf7f9e78 c0126f24 c035aef0 c0126e90 cf074a00
[ 57.262440] 9e80: 00000001 cf5ae080 cf7f9ec8 cc3ccc80 00000000 00000001 cf7f9eb4 cf7f9ea8
[ 57.271042] 9ea0: c0129cdc c0126e9c cf7f9f04 cf7f9eb8 c00e92bc c0129cbc cf5ae0b0 00010650
[ 57.279636] 9ec0: 00000004 cf7f9f78 00000000 00000000 cf7f9f04 cf7f9ee0 c022e4c4 cf074a00
[ 57.288236] 9ee0: 00000004 00010650 cf7f9f78 00000004 00000004 00010650 cf7f9f44 cf7f9f08
[ 57.296834] 9f00: c012a65c c00e9100 00000001 00000002 00000000 00000000 c005dc6c cc3ccc80
[ 57.305432] 9f20: 00000004 00010650 cf7f9f78 00000004 cf7f8000 00010650 cf7f9f74 cf7f9f48
[ 57.314033] 9f40: c00cb748 c012a554 c00e3734 c00e36b4 00000000 00000000 cc3ccc80 cc3ccc80
[ 57.322630] 9f60: 00000004 00010650 cf7f9fa4 cf7f9f78 c00cb920 c00cb6bc 00000000 00000000
[ 57.331226] 9f80: 00000000 beb15c98 00008355 00000003 c000e964 00000000 00000000 cf7f9fa8
[ 57.339822] 9fa0: c000e7e0 c00cb8e8 00000000 beb15c98 00000003 00010650 00000004 00000001
[ 57.348422] 9fc0: 00000000 beb15c98 00008355 00000003 00000000 00000000 46f17000 00000000
[ 57.357024] 9fe0: 00000000 beb15c74 00008469 470665bc 40000010 00000003 00000000 00000000
[ 57.365603] Backtrace:
[ 57.368224] [<c0293080>] (pwm_ecap_get_rpm_show) from [<c035af08>] (dev_attr_show+0x24/0x50)
[ 57.377077] r5:c083971c r4:cf5ae080
[ 57.380875] [<c035aee4>] (dev_attr_show) from [<c0126f24>] (sysfs_kf_seq_show+0x94/0x110)
[ 57.389453] r5:cf50b008 r4:cf5ae080
[ 57.393250] [<c0126e90>] (sysfs_kf_seq_show) from [<c0129cdc>] (kernfs_seq_show+0x2c/0x30)
[ 57.401923] r10:00000001 r9:00000000 r8:cc3ccc80 r7:cf7f9ec8 r6:cf5ae080 r5:00000001
[ 57.410190] r4:cf074a00 r3:c0126e90
[ 57.413988] [<c0129cb0>] (kernfs_seq_show) from [<c00e92bc>] (seq_read+0x1c8/0x4a0)
[ 57.422039] [<c00e90f4>] (seq_read) from [<c012a65c>] (kernfs_fop_read+0x114/0x15c)
[ 57.430080] r10:00010650 r9:00000004 r8:00000004 r7:cf7f9f78 r6:00010650 r5:00000004
[ 57.438346] r4:cf074a00
[ 57.441047] [<c012a548>] (kernfs_fop_read) from [<c00cb748>] (vfs_read+0x98/0x138)
[ 57.448995] r10:00010650 r9:cf7f8000 r8:00000004 r7:cf7f9f78 r6:00010650 r5:00000004
[ 57.457257] r4:cc3ccc80
[ 57.459945] [<c00cb6b0>] (vfs_read) from [<c00cb920>] (SyS_read+0x44/0x90)
[ 57.467167] r10:00010650 r8:00000004 r7:cc3ccc80 r6:cc3ccc80 r5:00000000 r4:00000000
[ 57.475464] [<c00cb8dc>] (SyS_read) from [<c000e7e0>] (ret_fast_syscall+0x0/0x30)
[ 57.483316] r10:00000000 r8:c000e964 r7:00000003 r6:00008355 r5:beb15c98 r4:00000000
[ 57.491594] Code: e5942000 e30907a8 e5953020 e34c0074 (e5832000)
[ 57.498103] ---[ end trace 9e3da6e7e3eecd69 ]---
Segmentation fault
root@am335x-evm:/usr#

here we are getting --why we are getting kernel panic - 

printk(KERN_INFO "get:value:%x %x %x %x\n",buf[0],buf[1],buf[2],buf[3]); //till here we are getting fine 

memcpy((char *)pwm->rpm,buf,4);                     // from here kernel panic we are getting 
printk(KERN_INFO "sys:get:value:rpm:%d \n",pwm->rpm);

please help us here -- if i am doing anything wrong -- ?? how to send the data from kernel space to userspace.

regards,

Viswanath K

  • Hi,
    Are you getting the same kernel oops for the following command too ?
    "cat /sys/class/pwm/pwmchip0/pwm0/ecap_get_rpm"

    In "show" function, use "sprintf" function to print the value to user space.


    The following lines were from "show" function ?

    printk(KERN_INFO "get:value:%x %x %x %x\n",buf[0],buf[1],buf[2],buf[3]); //till here we are getting fine

    memcpy((char *)pwm->rpm,buf,4); // from here kernel panic we are getting
    printk(KERN_INFO "sys:get:value:rpm:%d \n",pwm->rpm);
  • 1.
    Are you getting the same kernel oops for the following command too ?
    "cat /sys/class/pwm/pwmchip0/pwm0/ecap_get_rpm"
    -- YES. Same kernel panic
    cat will not ant have any buffer , then we went to read syscall -- we are giving a buffer.

    2.
    he following lines were from "show" function ?

    printk(KERN_INFO "get:value:%x %x %x %x\n",buf[0],buf[1],buf[2],buf[3]); //till here we are getting fine

    memcpy((char *)pwm->rpm,buf,4); // from here kernel panic we are getting
    printk(KERN_INFO "sys:get:value:rpm:%d \n",pwm->rpm);

    Ans: Yes these are in sysfs.c only. -- i will check with out memcpy.

    3. from driver :pwm-tiecap.c -- i am doing copy_to_user -- but those values i am not getting in sysfs.c
    becoz the buffer pointer comes from user ->sysfs.c -> core.c -> pwm-tiecap.c

    pwm-tiecap.c: in get_value () function.

    if(pc->chip.base == 0 )
    {
    rpm0 = (pulse_count_5/2)* SECS_MINUTE; // this works with timer only
    rpm=rpm0;
    rpm=3000;
    printk(KERN_INFO "rpm:%d\n",rpm);
    }

    if(pc->chip.base == 3 )
    {
    rpm2 = (pulse_count_6/2)* SECS_MINUTE;
    rpm=rpm2;
    rpm=4000;
    printk(KERN_INFO "rpm=%d \n",rpm);
    }

    ret = copy_to_user(uchar,(unsigned char *)rpm,4);
    printk(KERN_INFO "ret:%d\n",ret);


    the same way back to sysfs.c after copy_to_user --i am not getting any value from the buffer -- Here i am not able to get -- could u plz help me ??

    regards,
    Viswanath K

  • Hi Titus,
    As you suggested sprintf in sysfs.c and cpoy_to_user in working fine without any kernel panic.
    But the data only not able to send to user space properly.

    can you please help us.

    regards,
    Viswanath K.
  • Hi Viswanath,
    You mean , not able to see the correct data on user-space ?
    Just getting zeros only ?

    You can also use "snprintf()" with buffer size copying to user space.

    Did you printk the buffer (rpm data) in sysfs.c itself before reading it from user space ?
  • Hi Titus,

    #1:
    not able to see the correct data on user-space ? Just getting zeros only ?
    Ans: YES.

    #2:
    "snprintf()" with buffer size copying to user space ?
    This i need to test.

    #3:
    Did you printk the buffer (rpm data) in sysfs.c itself before reading it from user space ?
    YES. in sysfs.c only i am getting zero's

    for the below printk in sysfs.c:
    printk(KERN_INFO "get:value:%x %x %x %x\n",buf[0],buf[1],buf[2],buf[3]);
    output:
    "0,0,0,0"

    what ever buffer pointer sent from sysfs.c -> core.c -> driver.c same buffer we are used to print.

    regards,
    Viswanath K
  • Hi,

    what ever buffer pointer sent from sysfs.c -> core.c -> driver.c same buffer we are used to print.

    Getting the correct value from buffer but not from sysfs right ?
    Then it seems to be you are not accessed the buffer in sysfs file from PWM driver (between drivers).
    You can try to export that PWM function which used RPM buffer and then try to use that function in sysfs file for buffer access.
  • What i like to say is :
    in Sysfs.c:
    static ssize_t pwm_ecap_get_rpm_show(struct device *child,
    struct device_attribute *attr,
    char *buf)
    {
    struct pwm_device *pwm = child_to_pwm_device(child);
    int ret;

    printk(KERN_INFO "%s:\n",__func__);

    ret = pwm_ecap_get_value(pwm, buf);

    printk(KERN_INFO "get:value:%x %x %x %x\n",buf[0],buf[1],buf[2],buf[3]);

    return sprintf(buf, "%d\n", pwm->rpm);

    }

    in Core.c:
    int pwm_ecap_get_value(struct pwm_device *pwm, char *buffer)
    {
    int err;
    int ret;

    if (!pwm )
    return -EINVAL;

    ret = pwm->chip->ops->getvalue(pwm->chip, pwm, buffer);

    return ret;
    }

    in driver:
    static int ecap_pwm_get_value(struct pwm_chip *chip, struct pwm_device *pwm,
    char *uchar)
    rpm=3000;
    ret = copy_to_user(uchar,(char *)&rpm,4);
    printk(KERN_INFO "ret:%d\n",ret);

    ---------------------------

    this is the code -- now i am not getting "3000" in 1. my application -- which i given in the 1st post and the also not getting from
    2. not with cat command.

    please suggest me -- am i missing or anything wrong..??

    regards,
    Viswanath K.