Mikro saniye gecikmeleri gerektiren bir sürücüm var. Bu gecikmeyi oluşturmak için, sürücüm kernel'in udelay işlevini kullanıyor. Özel olarak, udelay (90) için bir çağrı var. Aygıtla ilgili güvenilirlik sorunlarımız vardı. Çok fazla hata ayıklamasından sonra, 90us'un geçmesinden önce sürücünün devam etmesini sağladık. (Aşağıdaki "prova" bölümüne bakın.)Linux Çekirdek: udelay() çok erken geri döndü mü?
Intel Pentium Dual Core (E5700) üzerinde çekirdek sürümü 2.6.38-11-jenerik SMP (Kubuntu 11.04, x86_64) çalıştırıyorum.
Bildiğim kadarıyla, dokümanlar udelay'in belirtilen gecikmeyi en az yürütmeyi geciktireceğini ve kesintisiz olduğunu belirtir. Çekirdeğin bu sürümünde bir hata var mı, yoksa udelay kullanımıyla ilgili bir şeyi yanlış anlamış mıyım? aşağıdaki gibi sorun udelay çok erken dönen neden olduğunu kendimizi ikna etmek
, biz I/O bağlantı noktalarından birine bir 100kHz saati beslenen ve kendi gecikme uygulanan:
// Wait until n number of falling edges
// are observed
void clk100_delay(void *addr, u32 n) {
int i;
for (i = 0; i < n; i++) {
u32 prev_clk = ioread32(addr);
while (1) {
u32 clk = ioread32(addr);
if (prev_clk && !clk) {
break;
} else {
prev_clk = clk;
}
}
}
}
... ve sürücü şimdi kusursuz çalışıyor. Son bir not
, o frekans ölçekleme yaramazlık fonksiyonların * gecikme() ailesini neden olabilecek belirten a discussion bulundu, ancak bu bir ARM posta listesinde - ben gibi sorunları varsayarak olmayan olacağını Linux x86 tabanlı bir bilgisayarda var.
Denerim ve size geri döneceğim. Sadece sizi doğru anlıyorum, her çekirdeğin kendi TSC'si var, bu yüzden eğer şoförün bakım yaptığı işlem başka bir CPU'ya yeniden ayarlanmışsa, TSC aynı olmayabilir mi? Ayrıca, X86_FEATURE_CONSTANT_TSC'nin, CPU'nun TSC'sinin frekans ölçeklemesinden bağımsız olarak kararlı olduğunu ve X86_FEATURE_NONSTOP_TSC'nin TSC'nin asla saymayı durduracağı anlamına geldiğini doğru bir şekilde anlıyor musunuz? Eğer öyleyse, bir CPU ne zaman TSC'yi durdurur? –
TSC, belirli [C-States] (http://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface#Processor_states) sırasında durdurabilir. –
[TSC tabanlı gecikme kodu] (http://lxr.linux.no/#linux+v2.6.38/arch/x86/lib/delay.c#L51), gecikmeler sırasında CPU'lar arasında kaydırılmayı uygun şekilde hesaplar. Gecikme sırasında TSC'nin durması sadece gecikmeyi * daha uzun *, daha * kısa * yapar, bu da sorun değildir. – caf