cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
leroyworld1
Observer
Observer
4,566 Views
Registered: ‎09-11-2014

Capturing uevent from XADC temperature Sensor (Linux 4.6)

Hi everyone,

We are planning to integrate a Zynq device within a UAV where the temperature could get quite high. I found here which registers I should be reading to know XADC temperature.
I was planning to monitor this registers, like every second or so, and do something if it goes too high. But then I saw I could take advantage of the event register: "in_temp0_thresh_rising_value" and built a better/elegant solution.

The value of in_temp0_raw register is 2490 when I add an external fan, and 2540 when I turn it off, so I configured in_temp0_thresh_rising_value to be 2520 so I can force the event easily, turning on or off the fan.

The thing is I have no idea how I can capture this uevent from user program. I'm attaching the code I tried so far with no results.
Could someone point me out how I can get this done?

Cheers,
Leroy.

void uevent_wait() {

    struct sockaddr_nl nls;
    struct pollfd pfd;
    char buf[512];

    // Open hotplug event netlink socket
    memset(&nls,0,sizeof(struct sockaddr_nl));
    nls.nl_family = AF_NETLINK;
    nls.nl_pid = getpid();
    nls.nl_groups = -1;
    pfd.events = POLLIN;
    pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
    if (pfd.fd == -1) perror("Not root\n");

    // Listen to netlink socket
    if (bind(pfd.fd, (void *)&nls, sizeof(struct sockaddr_nl))) perror("Bind failed\n");

    while(1){
        while (-1 != poll(&pfd, 1, -1)) {
          int i, len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
          if (len == -1) printf("recv\n");

          // Print the data to stdout.
          i = 0;
          while (i < len) {
             printf("%s\n", buf+i);
             i += strlen(buf+i)+1;
         }
     }
 }


 printf("die\n");

    return;
}



0 Kudos
3 Replies
balkris
Xilinx Employee
Xilinx Employee
4,524 Views
Registered: ‎08-01-2008

You have to enable the driver, as you figured out and the xadc needs a DT fragment. But the default dts files should feature it (https://github.com/Xilinx/linux-xlnx/blob/master-next/arch/arm/boot/dts/zynq-zc702.dts#L319 )



Then the corresponding sysfs entries should be created in /sys/devices/amba.1/f8007100.xadc (or similar). Reading the file 'temp' gives you the temperature reading.
Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.
0 Kudos
leroyworld1
Observer
Observer
4,516 Views
Registered: ‎09-11-2014

Hi @balkris, thank you for your quick answer.

I did have the driver enabled, and I'm able to read the temperature from the register. But I wouldn't like to have a process monitoring that register, so a better option would be to capture the event highlighted in pink:

./in_temp0_offset
./in_temp0_scale
./events/in_temp0_thresh_rising_en
./events/in_temp0_thresh_rising_value
./events/in_temp0_thresh_rising_hysteresis
./in_temp0_raw

So the question is: how can I capture this event programmatically? The snippet I added in my previous post is not able to capture it yet...

Cheers,
Leroy

0 Kudos
leroyworld1
Observer
Observer
4,456 Views
Registered: ‎09-11-2014

Hi,

 

I'm still stucked with this. I've tried some code variations but with same result: poll call never leaves it's blocking status despite I'm forcing the temperature to cross in_temp0_thresh_rising_value.

Any tip would be appreciated.

0 Kudos