CPU frequency control framework

DJF

/(bb|[^b]{2})/
Ich bastle zur Zeit an einem Enlightenment module, das die Taktrate der CPU steuern soll. Das standart module im enlightenment-devel Port funktionert leider nicht. Da ich von solchen Dingen eigentlich keine Ahnung habe, hab ich mir mal den Sourcecode des cpu-scaling Applets von Gnome angeschaut (das Applet funktioniert bei mir).
Ich kann aber nicht wirklich nachvollziehen wieso das Applet funktioniert: Es greift entweder auf /proc/cpufreq (procfs), oder /sys/devices/system/cpu/cpu0/cpufreq/ (sysfs)zu. Das hat wohl mit Veränderungen in den Linux Kernelversionen 2.4 und 2.6 zu tun. Wie dem auch sei, sysfs gibts in freeBSD nicht und procfs kennt kein cpufreq!? Deswegen war ich ziemlich verwundert, dass das ganze überhaupt funktioniert, zumal das Enlightenment-module eigentlicht das gleiche macht.

Weitere Nachfoschungen haben ergeben, dass FreeBSD über ein CPU frequency control framework verfügt (man cpufreq). Das klang sehr interessant, aber als ich versucht hab den Kernel (FreeBSD 5.4) mit device cpufreq zu kompilieren hies es nur "device cpufreq is unknown". Dumm gelaufen.
Andererseits kann man den CPU speed wunderbar mit "sysctl dev.cpu.0.freq=...." (als root) setzen. Im Moment überlege ich vielleicht einfach genau das zu tun, aber dann müsste das Programm wohl mit suid laufen.

Weiss vielleicht jemand wie/wieso das Gnome-Applet unter BSD funktionieren? Wie man CPU scaling vielleicht FreeBSD.-spezifischer lösen könnte? Wo man was dazu nachlesen kann? Wo es mehr infos zum CPU frequency control framework gibt?
 
Besten Dank!

Soweit ich das auf den ersten Blick sagen kann greift powered direkt auf die sysctl Variablen zu. Also genau wie ichs mir vorgestellt hab. Aber wie dieses gnome-applet funktioniert wird dadurch nur noch mysteriöser. Linuxkompatibilität kanns auch nicht sein, das hab ich zum Test abgeschaltet... äusserst mysteriös.

The truth is out there *g*
 
Guten Morgen,
habe mir die Sache auch schon mal angeschaut, da ich auch gerne ein cpu-, battery- und wlan-modul für e17 hätte...
Also ich habe speedstepping mit est laufen http://wiki.bsdforen.de/index.php/FreeBSD_-_Pentium_M
Damit hat man dann sowas wie hw.est.*, kann dort die verfügbaren Frequenzen auslesen und auch setzen. Meine Idee war dann die Linux-Aufrufe proc und sysfs einfach durch sysctl hw.est.* zu ersetzten. Current habe ich mir noch nicht angeschaut, da ich noch etwas bsd-noob bin.
Würde sagen fürs Gnome sind es wohl bsd-patches oder ein paar #ifdefs, denn sowie ich das sehe ist die Steuerung des Taktes Kernelsache und damit auch unter bsd und linux nicht gleich.
Grüße
 
Ich baue auch gerade an etwas änlichem, ich verwende zum Zugriff die sysctl Bibliothek (man 3 sysctl). Leider weiß ich nicht wie man zur laufzeit den Typ einer sysctl variablen feststellt.

Im Moment behelfe ich mir damit sie immer in einen char[] zu lesen. Falls die Länge des Strings durch 4 teilbar ist prüfe ich ob es bytes gibt die normalerweise nicht in einem ASCI String vorkommen und lese es dann noch mal als int oder int[] aus. Das ist recht zuverlässig, aber eben nicht 100 prozentig. Kennt da jemand eine Lösung?

[edit]
Soweit ich weiß funktioniert cpufreq nur mit idle calls. Ich bastel an einer Alternative für den estctrl deamon.
 
Zuletzt bearbeitet:
Ehrlich gesagt hab ich seit der letzten Woche nich mehr viel dran gearbeitet. Auf Grund des generellen Semesterends-Chaos hatte ich einfach keine Zeit. Und dann ist der FreeBSD Laptop ausgestiegen *freu*!


Zu den Variablen Typen. Aus powered.c:
Code:
static int	freq_mib[4];
static int	levels_mib[4];
.
.
.
len = 4;
if (sysctlnametomib("dev.cpu.0.freq", freq_mib, &len))
		err(1, "lookup freq");
.
len = 4;
if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len))
		err(1, "lookup freq_levels");
.
.
.

static int
read_freqs(int *numfreqs, int **freqs, int **power)
{
	char *freqstr, *p, *q;
	int i;
	size_t len = 0;

	if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
		return (-1);
	if ((freqstr = malloc(len)) == NULL)
		return (-1);
	if (sysctl(levels_mib, 4, freqstr, &len, NULL, 0))
		return (-1);
	*numfreqs = 1;
	for (p = freqstr; *p != '\0'; p++)
		if (*p == ' ')
			(*numfreqs)++;

	if ((*freqs = malloc(*numfreqs * sizeof(int))) == NULL) {
		free(freqstr);
		return (-1);
	}
	if ((*power = malloc(*numfreqs * sizeof(int))) == NULL) {
		free(freqstr);
		free(*freqs);
		return (-1);
	}

/* der interessante Teil */
	for (i = 0, p = freqstr; i < *numfreqs; i++) {
		q = strchr(p, ' ');
		if (q != NULL)
			*q = '\0';
		if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) {
			free(freqstr);
			free(*freqs);
			free(*power);
			return (-1);
		}
		p = q + 1;
	}

	free(freqstr);
	return (0);
}
.
.
.

@Kamikaze: Er schmeist alles in ein char Array und dann sscanf(). Vielleicht gibts nix besseres. Aber das setzt widerum voraus, dass man bereits weiss von welchem Typ die Variablen sind... :/
 
Ich verwende sysctlbyname() aus sysctl.h. Da bekommt man die Daten eben wie sie im sysctl liegen, als char[], int oder int[].

Da ich einen Deamon schreiben will der beliebige sysctl variablen überwacht und verändert muss ich den Typ irgendwie raten, da ich ihn nicht fest programmieren kann, weil ich ja nicht weiß auf welche variablen später zugegriffen werden soll.
 
Vorgestern kam mein laptop endlich wieder aus der Reparatur zurück. Nach einem portsnap/portupgrade hab mich wieder an die Arbeit gemacht. Nachdem start der neuesten Enlightenment Version hatte ich immerhin eine funktionierende Temperaturanzeige! CPU control hab ich zwar noch nicht, aber zumindest einen patch für die Batterieanzeige. Bei mir läuft's ganz vernünftig :D Wer will kann ihn ja mal ausprobieren, wäre noch interessant zu wissen, ob das Ding auch auf anderen Rechnern funzt.

einfach ins enlightenment/src/module/battery Verzeichnis wechseln und patch anwenden.
 

Anhänge

  • bsd_batt.patch.zip
    3,2 KB · Aufrufe: 437
Nur der Vollständigkeit halber der patch für cpufreq module für E17. Ich hab beide patches an die Entwickler geschickt und hoffentlich werden sie in einem der nächsten Releases dabei sein.
 

Anhänge

  • bsd_cpufreq.patch.zip
    2,6 KB · Aufrufe: 378
Zuletzt bearbeitet:
Zurück
Oben