[Newbie Kernel Developer] Kernel driver to control CPU temperature on a Raspberry Pi

107 views
Skip to first unread message

Atharva Abhyankar

unread,
Mar 17, 2024, 1:30:31 PMMar 17
to Kernel Meetup Bangalore
Hi,
I have gone through the basics of kernel development in linux and also written a working "Hello World" driver. However, I am now trying to up my game a bit and I have assigned myself a project to write a driver to control the CPU temperature of my Raspberry Pi 4B.

I want to turn on the fan when the CPU temperature reaches a certain temperature. 
The fan when turned ON will cool down the CPU and will turn OFF when the temperature falls below a certain temperature.

Now, I can easily write a python script of a C program in user space for that as the CPU temperature is written to a file "sys/class/hwmon/thermal/thermal_zone0/temp", but that won't help me understand writing the driver or making changes in the kernel. Hence, I want to this from the kernel only.


However, I am not able to figure out where the function "bcm2711_get_temp" is called and how the Raspberry Pi updates the temperature in the file mentioned above. Looking at how the file is updated with the temperature will help me know the kernel code flow and thus, will enable me to achieve my objective.

Any help on going forward is appreciated.

Aneesh Kumar

unread,
Mar 18, 2024, 11:40:53 AMMar 18
to Atharva Abhyankar, Kernel Meetup Bangalore
Are you looking for this? 

image.png

That does 
int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
{
const struct thermal_trip *trip;
int crit_temp = INT_MAX;
int ret = -EINVAL;

lockdep_assert_held(&tz->lock);

ret = tz->ops->get_temp(tz, temp);
.....

which is 

static const struct thermal_zone_device_ops bcm2711_thermal_of_ops = {
.get_temp = bcm2711_get_temp,
};

-aneesh

--
You received this message because you are subscribed to the Google Groups "Kernel Meetup Bangalore" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kernel-meetup-ban...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/kernel-meetup-bangalore/f2cbfaf5-9b46-46ee-8ff7-5154335d830an%40googlegroups.com.

Dipankar Sarma

unread,
Mar 22, 2024, 3:15:10 AMMar 22
to Atharva Abhyankar, Kernel Meetup Bangalore
On Sun, 2024-03-17 at 10:30 -0700, Atharva Abhyankar wrote:
>
> I want to turn on the fan when the CPU temperature reaches a certain
> temperature. 
> The fan when turned ON will cool down the CPU and will turn OFF when
> the temperature falls below a certain temperature.
>
> Now, I can easily write a python script of a C program in user space
> for that as the CPU temperature is written to a file
> "sys/class/hwmon/thermal/thermal_zone0/temp", but that won't help me
> understand writing the driver or making changes in the kernel. Hence,
> I want to this from the kernel only.

Before digging deeper into operating system kernel code, it is
important to understand the concepts used in the design of that
operating system. This will help in understanding the code compared to
just following the code.

What you see in /sys/class/hwmon/thermal/thermel_zone0/temp is not an
actual physical file that is written into by anything. /sys is the
mount point of a pseudo-filesystem called sysfs that was implemented in
the kernel a long time ago (similar to /proc filesystem). The goal was
to export information about various subsystems in the kernel and also
provide control to parameters implemented by the kernel. The files in a
pseudo-filesystem are essentially virtual files - read()/write() system
calls on them translates to "methods" implemented by specific
subsystems that implements the virtual files associated with it. There
is no actual backing store associated with these files. Another concept
to keep in mind while looking at the linux kernel code - architecture
dependent code is often para-virtualized via "methods" that are called
from architecture independent (generic) code. It is up to the specific
architecture or board/device to plug in its own specific methods.

In the example above, you should be looking at the generic thermal zone
syfs implementation :

static ssize_t
temp_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
int temperature, ret;

ret = thermal_zone_get_temp(tz, &temperature);

if (ret)
return ret;

return sprintf(buf, "%d\n", temperature);
}

The _show() method is called when the virtual file of this sysfs file
is read. You can read the documentation on sysfs first -
https://docs.kernel.org/filesystems/sysfs.html


>
> I went through the driver code in "bcm2711_thermal.c -
> drivers/thermal/broadcom/bcm2711_thermal.c - Linux source code
> (v6.8.1) - Bootlin"
>
> However, I am not able to figure out where the function
> "bcm2711_get_temp" is called and how the Raspberry Pi updates the
> temperature in the file mentioned above. Looking at how the file is
> updated with the temperature will help me know the kernel code flow
> and thus, will enable me to achieve my objective.

Once you know how the _show() method is implemented, you can work your
way down in the to the paravirtualized method call for that specific
board. thermal_zone ops for that board would have set the get_temp()
method.

Hope this helps from the concept perspective.

Thanks
Dipankar

Reply all
Reply to author
Forward
0 new messages