解决i8253 count too high !resetting!的其他方法

本文介绍了解决Linux系统启动时出现的提示和消除特定错误的方法。包括如何进入单用户模式禁用pcmcia服务以及通过修改内核源代码来消除i8253计数过高的警告。
部署运行你感兴趣的模型镜像
1.关闭提示 2.消除误差
1.关闭提示
开机到grub处,按下e键,选择kernel /vmlinuz-2.4.20-8 ro root=LABEL=/ ,在末尾处“空格+single”,然后回车退出,再按b键引导进入单用户模式,在单用户模式下输入chkconfig pcmcia off,然后reboot重启就可以了
2.消除误差
Linux系统本身就已经具备了消除这种误差的功能,因为i8253 count too hight,reseting,本身就是一个Debug的回显信息,系统是如何消除这种误差的呢?

I 'solved' the problem by removing the message from the linux kernel source
and compiling it again then installing the new kernel. No more messages!

You *NEED* to have the kernel source on your virtual machine to do this.

On 2.4.x kernel sources (assuming your linux sources is at /usr/src/linux)
the file that needs editing is time.c found like this...
root@dana2:/root$ cd /usr/src/
root@myserver:/usr/src$ grep "i8253 count too high! resetting.." *

which outputs:

grep: Documentation: Is a directory
grep: arch: Is a directory
grep: crypto: Is a directory
grep: drivers: Is a directory
grep: fs: Is a directory
grep: include: Is a directory
grep: init: Is a directory
grep: ipc: Is a directory
grep: kernel: Is a directory
grep: lib: Is a directory
grep: mm: Is a directory
grep: net: Is a directory
grep: scripts: Is a directory
arch/i386/kernel/time.c: "i8253 count too
high! resetting..\n");

Go edit this time.c file and it is the two lines 690/691 (for 2.4.27 anyway). At comment
markers around the two lines then save and build a new kernel and install.

time.c lines 690 & 691
-------------------------------
/* printk(KERN_WARNING"i8253 count too high! resetting..\n"); */

The line numbers may or may not be the same for other 2.4.xx kernels but it will be the same file.

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

// 系统校准流程 void AD7190_SystemCalibrate(void) { if (!ad7190_state.is_initialized) AD7190_Init(); uint8_t rx_char; uint32_t start_time = HAL_GetTick(); // 获取开始时间 printf("===== System Calibration =====\r\n"); // 1. 零点校准 printf("Ensure platform is empty, then press 'z' for zero calibration...\r\n"); while(1) { if (HAL_UART_Receive(&huart1, &rx_char, 1, 100) == HAL_OK) { if(rx_char == 'z' || rx_char == 'Z') break; } // 添加超时检测 if (HAL_GetTick() - start_time > CALIBRATION_TIMEOUT) { printf("Calibration timed out\n"); return; } } // 读取32个样本,丢弃异常值 uint32_t samples[32]; int valid_count = 0; for(int i = 0; i < 32; i++) { uint32_t data = AD7190_ReadData(); // 检查数据有效性(排除异常值) if (data > 0 && data < 0xFFFFFF) { samples[valid_count++] = data; } HAL_Delay(10); } if (valid_count < 16) { printf("ERROR: Not enough valid samples for zero calibration (%d/32)\n", valid_count); return; } // 计算中值代替平均值(更抗干扰) qsort(samples, valid_count, sizeof(uint32_t), compare_uint32); ad7190_state.calib.calibration_offset = samples[valid_count / 2]; // 2. 量程校准 printf("Place 1000.0g weight, then press 'f' for full scale calibration...\r\n"); while(1) { if (HAL_UART_Receive(&huart1, &rx_char, 1, 100) == HAL_OK) { if(rx_char == 'f' || rx_char == 'F') break; } // 添加超时检测 if (HAL_GetTick() - start_time > CALIBRATION_TIMEOUT) { printf("Calibration timed out\n"); return; } } // 读取32个样本,丢弃异常值 // 读取32个样本,丢弃异常值 uint32_t F_samples[32]; int F_valid_count = 0; for(int i = 0; i < 32; i++) { uint32_t data = AD7190_ReadData(); // 检查数据有效性(排除异常值) if (data > 0 && data < 0xFFFFFF) { F_samples[F_valid_count++] = data; } HAL_Delay(10); } if (valid_count < 16) { printf("ERROR: Not enough valid samples for full scale calibration (%d/32)\n", valid_count); return; } // 计算中值代替平均值 qsort(F_samples, F_valid_count, sizeof(uint32_t), compare_uint32); uint32_t full_scale = F_samples[valid_count / 2]; // 计算校准因子(增加安全范围检查) int32_t diff = (int32_t)full_scale - (int32_t)ad7190_state.calib.calibration_offset; if (diff <= 1000) { // 1000是经验值,根据实际传感器调整 printf("ERROR: Invalid calibration difference (%ld). Too small!\n", diff); return; } if (diff > 10000000) { // 防止异常大值 printf("ERROR: Invalid calibration difference (%ld). Too large!\n", diff); return; } ad7190_state.calib.calibration_factor = 1000.0f / (float)diff; // 重置去皮值和滤波器 ad7190_state.calib.tare_value = 0.0f; KalmanFilter_Init(&ad7190_state.kf, 0.001f, 0.01f, 1.0f, 0.0f); // 保存到EEPROM // AD7190_SaveCalibrationToEEPROM(); printf("System calibration completed! Factor: %f\n", ad7190_state.calib.calibration_factor); } REFIN2 configured successfully (GPOCON: 0x00) Internal zero calibration completed AD7190 initialized successfully ===== System Calibration ===== Ensure platform is empty, then press 'z' for zero calibration... Place 1000.0g weight, then press 'f' for full scale calibration... System calibration completed! Factor: 0.004975 WARNING: Only 0/32 valid samples Weight: 0.0g WARNING: Only 0/32 valid samples Weight: 0.0g WARNING: Only 0/32 valid samples Weight: -69.0g WARNING: Only 0/32 valid samples什么原因?
08-21
drivers/staging/led/led.c: In function 'rf_detect_sync_header': drivers/staging/led/led.c:244:12: error: invalid storage class for function 'rf_decode_data_bits' static int rf_decode_data_bits(struct rf_decoder_state *state, uint32_t pulse_width, int level) ^~~~~~~~~~~~~~~~~~~ drivers/staging/led/led.c: In function 'rf_decode_data_bits': drivers/staging/led/led.c:285:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] uint32_t low_duration = pulse_width; // 低电平持续时间 ^~~~~~~~ drivers/staging/led/led.c: In function 'rf_detect_sync_header': drivers/staging/led/led.c:244:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] static int rf_decode_data_bits(struct rf_decoder_state *state, uint32_t pulse_width, int level) ^~~~~~ drivers/staging/led/led.c:323:12: error: invalid storage class for function 'rf_data_decode' static int rf_data_decode(struct rf_decoder_state *state) ^~~~~~~~~~~~~~ drivers/staging/led/led.c:364:20: error: invalid storage class for function 'rf_data_irq_handler' static irqreturn_t rf_data_irq_handler(int irq, void *dev_id) ^~~~~~~~~~~~~~~~~~~ drivers/staging/led/led.c:375:12: error: invalid storage class for function 'rf_open' static int rf_open(struct inode *inode, struct file *file) ^~~~~~~ drivers/staging/led/led.c:415:16: error: invalid storage class for function 'rf_read' static ssize_t rf_read(struct file *file, char __user *buf, size_t len, loff_t *offset) ^~~~~~~ drivers/staging/led/led.c:446:16: error: invalid storage class for function 'rf_write' static ssize_t rf_write(struct file *file, const char __user *buf, size_t len, loff_t *offset) ^~~~~~~~ drivers/staging/led/led.c:452:12: error: invalid storage class for function 'rf_close' static int rf_close(struct inode *inode, struct file *file) ^~~~~~~~ drivers/staging/led/led.c:466:21: error: invalid storage class for function 'rf_poll' static unsigned int rf_poll(struct file *file, poll_table *wait) ^~~~~~~ drivers/staging/led/led.c:481:13: error: initializer element is not constant .open = rf_open, ^~~~~~~ drivers/staging/led/led.c:481:13: note: (near initialization for 'rf_file_operations.open') drivers/staging/led/led.c:482:13: error: initializer element is not constant .read = rf_read, ^~~~~~~ drivers/staging/led/led.c:482:13: note: (near initialization for 'rf_file_operations.read') drivers/staging/led/led.c:483:14: error: initializer element is not constant .write = rf_write, ^~~~~~~~ drivers/staging/led/led.c:483:14: note: (near initialization for 'rf_file_operations.write') drivers/staging/led/led.c:484:16: error: initializer element is not constant .release = rf_close, ^~~~~~~~ drivers/staging/led/led.c:484:16: note: (near initialization for 'rf_file_operations.release') drivers/staging/led/led.c:485:13: error: initializer element is not constant .poll = rf_poll, ^~~~~~~ drivers/staging/led/led.c:485:13: note: (near initialization for 'rf_file_operations.poll') drivers/staging/led/led.c:488:19: error: invalid storage class for function 'rf_init' static int __init rf_init(void) ^~~~~~~ drivers/staging/led/led.c:570:20: error: invalid storage class for function 'rf_exit' static void __exit rf_exit(void) ^~~~~~~ In file included from drivers/staging/led/led.c:1:0: drivers/staging/led/led.c:591:13: error: initializer element is not constant module_init(rf_init); ^ ./include/linux/init.h:218:50: note: in definition of macro '___define_initcall' __attribute__((__section__(#__sec ".init"))) = fn; ^~ ./include/linux/init.h:251:30: note: in expansion of macro '__define_initcall' #define device_initcall(fn) __define_initcall(fn, 6) ^~~~~~~~~~~~~~~~~ ./include/linux/init.h:256:24: note: in expansion of macro 'device_initcall' #define __initcall(fn) device_initcall(fn) ^~~~~~~~~~~~~~~ ./include/linux/module.h:87:24: note: in expansion of macro '__initcall' #define module_init(x) __initcall(x); ^~~~~~~~~~ drivers/staging/led/led.c:591:1: note: in expansion of macro 'module_init' module_init(rf_init); ^~~~~~~~~~~ drivers/staging/led/led.c:592:13: error: initializer element is not constant module_exit(rf_exit); ^ ./include/linux/init.h:259:50: note: in definition of macro '__exitcall' static exitcall_t __exitcall_##fn __exit_call = fn ^~ drivers/staging/led/led.c:592:1: note: in expansion of macro 'module_exit' module_exit(rf_exit); ^~~~~~~~~~~ ./include/linux/init.h:259:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] static exitcall_t __exitcall_##fn __exit_call = fn ^ ./include/linux/module.h:99:24: note: in expansion of macro '__exitcall' #define module_exit(x) __exitcall(x); ^~~~~~~~~~ drivers/staging/led/led.c:592:1: note: in expansion of macro 'module_exit' module_exit(rf_exit); ^~~~~~~~~~~ In file included from ./include/linux/module.h:18:0, from drivers/staging/led/led.c:2: ./include/linux/moduleparam.h:24:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] static const char __UNIQUE_ID(name)[] \ ^ ./include/linux/module.h:161:32: note: in expansion of macro '__MODULE_INFO' #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) ^~~~~~~~~~~~~ ./include/linux/module.h:215:34: note: in expansion of macro 'MODULE_INFO' #define MODULE_LICENSE(_license) MODULE_INFO(license, _license) ^~~~~~~~~~~ drivers/staging/led/led.c:594:1: note: in expansion of macro 'MODULE_LICENSE' MODULE_LICENSE("GPL"); ^~~~~~~~~~~~~~ In file included from drivers/staging/led/led.c:2:0: ./include/linux/module.h:268:22: error: expected declaration or statement at end of input static const struct module_version_attribute \ ^ drivers/staging/led/led.c:597:1: note: in expansion of macro 'MODULE_VERSION' MODULE_VERSION("1.3"); ^~~~~~~~~~~~~~ #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/sched.h> #include <linux/wait.h> #include <asm/uaccess.h> #include <asm/io.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/device.h> #include <linux/timer.h> #include <linux/jiffies.h> #include <linux/kfifo.h> #include <linux/ktime.h> #define COUNT 1 #define RF_DATA_GPIO 137 // RF数据输入引脚 #define dev_name "rf_decoder" // 433MHz RF解码参数 #define RF_SYNC_CODE_MAX_SCALE 60 #define RF_SYNC_CODE_MIN_SCALE 20 #define RF_SYNC_CODE_TYPICAL_SCALE 32 #define RF_DATA_CODE_MAX_SCALE 6 #define RF_DATA_CODE_MIN_SCALE 2 #define RF_DATA_CODE_TYPICAL_SCALE 3 // 时间参数(单位:微秒) #define RF_REPEAT_DATA_TIME 2000000 // 2秒去重时间 #define RF_SYNC_HIGH_MIN 200 // 同步头高电平最小宽度200us #define RF_SYNC_HIGH_MAX 8000 // 同步头高电平最大宽度800us #define RF_BIT_MIN_WIDTH 200 // 数据位最小宽度200us #define RF_BIT_MAX_WIDTH 2000 // 数据位最大宽度2ms #define UINT32_MAX ((uint32_t)0xFFFFFFFF) // 数据位解码比例参数(使用整数运算避免浮点) #define RATIO_1_MIN_NUMERATOR 15 // 1.5 = 15/10 #define RATIO_1_MIN_DENOMINATOR 10 #define RATIO_1_MAX_NUMERATOR 50 // 5.0 = 50/10 #define RATIO_1_MAX_DENOMINATOR 10 #define RATIO_0_MIN_NUMERATOR 2 // 0.2 = 2/10 #define RATIO_0_MIN_DENOMINATOR 10 #define RATIO_0_MAX_NUMERATOR 67 // 0.67 = 67/100 #define RATIO_0_MAX_DENOMINATOR 100 // 环形缓冲区大小 #define RF_RX_FIFO_SIZE 256 static dev_t rf_device_id; static struct cdev rf_cdev; static struct class *rf_class; // RF解码状态结构体 struct rf_decoder_state { // 解码状态标志 uint8_t bit_rx_sync; // 是否接收到同步头 uint8_t bit_rx_status; // 当前电平状态 uint8_t bit_rx_decode; // 正在解码数据 uint8_t uc_rec_count; // 接收数据位计数 // 同步头检测状态 uint8_t sync_phase; // 同步头检测阶段: 0=等待高电平, 1=等待低电平 uint32_t sync_high_time; // 同步头高电平时间 uint32_t sync_low_time; // 同步头di电平时间 // 时间记录 uint32_t rx_time_us; // 上次接收时间 uint32_t rx_old_data; // 上次接收的数据(用于去重) // 数据缓冲区 uint32_t rx_shift; // 移位寄存器 uint32_t rx_long; // 长按数据 // 电平时间记录 uint32_t last_pulse_width; // 上次脉冲宽度 uint32_t last_edge_time; // 上次边沿时间 uint32_t last_level; // 上次电平状态 // FIFO缓冲区 struct kfifo rx_data_fifo; // 接收数据FIFO unsigned char *fifo_buffer; // FIFO缓冲区指针 // 同步保护 spinlock_t lock; wait_queue_head_t read_queue; }; static struct rf_decoder_state rf_decoder; // 获取32位微秒时间 u32 get_32bit_usec_ktime(void) { ktime_t kt = ktime_get(); return (u32)ktime_to_us(kt); } // 专门处理32位时间差计算的函数 static uint32_t time_diff_32(uint32_t newer, uint32_t older) { if (newer >= older) { return newer - older; } else { // 处理溢出情况 return (UINT32_MAX - older) + newer + 1; } } // 重置解码状态 static void rf_reset_state(struct rf_decoder_state *state) { state->bit_rx_sync = 1; // 等待同步头 state->sync_phase = 0; // 同步头检测阶段0: 等待高电平 state->sync_high_time = 0; // 清空同步头高电平时间 state->sync_low_time = 0; // 清空同步头di电平时间 state->bit_rx_decode = 0; state->uc_rec_count = 0; state->rx_shift = 0; state->last_pulse_width = 0; state->last_level = gpio_get_value(RF_DATA_GPIO); } // 数据接收完成处理 static int rf_complete_data_reception(struct rf_decoder_state *state) { uint32_t current_time = get_32bit_usec_ktime(); unsigned long flags; printk(KERN_INFO "RF: Received 24 bits: 0x%08X\n", state->rx_shift); // 去重处理 if ((state->rx_old_data != state->rx_shift) || ((current_time - state->rx_time_us) > RF_REPEAT_DATA_TIME)) { state->rx_time_us = current_time; state->rx_old_data = state->rx_shift; // 将解码数据写入FIFO spin_lock_irqsave(&state->lock, flags); if (kfifo_avail(&state->rx_data_fifo) >= sizeof(uint32_t)) { kfifo_in(&state->rx_data_fifo, (unsigned char *)&state->rx_shift, sizeof(uint32_t)); wake_up_interruptible(&state->read_queue); printk(KERN_INFO "RF: 🎯 Decoded data: 0x%08X\n", state->rx_shift); } else { printk(KERN_WARNING "RF: ⚠️ RX FIFO full, data dropped: 0x%08X\n", state->rx_shift); } spin_unlock_irqrestore(&state->lock, flags); } else { printk(KERN_DEBUG "RF: 🔄 Duplicate data ignored: 0x%08X\n", state->rx_shift); } // 重置状态,等待下一个同步头 rf_reset_state(state); return 0; } // 使用整数运算检查比例(避免浮点运算) static int check_ratio(uint32_t high_time, uint32_t low_time, uint32_t min_num, uint32_t min_denom, uint32_t max_num, uint32_t max_denom) { // 检查 high_time/low_time 是否在 [min_num/min_denom, max_num/max_denom] 范围内 // 使用乘法避免除法,避免浮点运算 // 检查 high_time * min_denom >= low_time * min_num if (high_time * min_denom < low_time * min_num) { return 0; } // 检查 high_time * max_denom <= low_time * max_num if (high_time * max_denom > low_time * max_num) { return 0; } // 检查 low_time < max_num if (low_time < 8000) { return 0; } return 1; } // 同步头检测 static int rf_detect_sync_header(struct rf_decoder_state *state, uint32_t pulse_width, int level) { if (level == 1) { state->sync_low_time = pulse_width; // 记录di电平shijian if (check_ratio(state->sync_low_time, state->sync_high_time, RF_SYNC_CODE_MIN_SCALE, 1, RF_SYNC_CODE_MAX_SCALE, 1)) { // 同步头检测成功 printk(KERN_DEBUG "RF: Sync header detected:succeed"); state->bit_rx_sync = 0; return 1; }else { if (state->sync_high_time >= RF_SYNC_HIGH_MIN && state->sync_high_time <= RF_SYNC_HIGH_MAX) { state->sync_high_time = pulse_width; // 保存高电平持续时间 } printk(KERN_DEBUG "RF: state->sync_low_time:%u ,state->sync_high_time:%u\n\n",state->sync_low_time,state->sync_high_time); return 0; } /* if (state->sync_phase == 0) { // 阶段0: 等待高电平开始(上升沿) } else if (state->sync_phase == 1) { // 阶段1: 等待高电平结束(下降沿) if (level == 0) { uint32_t high_duration = time_diff_32(get_32bit_usec_ktime(), state->sync_high_time); // 检查高电平持续时间 if (high_duration >= RF_SYNC_HIGH_MIN && high_duration <= RF_SYNC_HIGH_MAX) { state->sync_high_time = high_duration; state->sync_phase = 2; } } } else if (state->sync_phase == 2) { // 阶段2: 等待低电平结束(上升沿) if (level == 1) { uint32_t low_duration = pulse_width; // 这个pulse_width是低电平持续时间 // 检查低电平时间是否为高电平时间的20-60倍 if (check_ratio(low_duration, state->sync_high_time, RF_SYNC_CODE_MIN_SCALE, 1, RF_SYNC_CODE_MAX_SCALE, 1)) { // 同步头检测成功 printk(KERN_DEBUG "RF: Sync header detected:succeed"); state->bit_rx_sync = 0; return 1; } } }*/ return 0; } // 数据位解码 static int rf_decode_data_bits(struct rf_decoder_state *state, uint32_t pulse_width, int level) { static uint32_t bit_start_time = 0; uint32_t current_time; uint32_t duration; current_time = get_32bit_usec_ktime(); if (state->last_level == level) { // 电平没有变化,不应该发生 printk(KERN_DEBUG "RF: Unexpected level change\n"); return -1; } if (level == 1) { // 上升沿:低电平结束,记录低电平持续时间 duration = pulse_width; // pulse_width是低电平持续时间 // 检查数据位宽度是否合理 if (duration < RF_BIT_MIN_WIDTH || duration > RF_BIT_MAX_WIDTH) { printk(KERN_DEBUG "RF: Invalid bit width - low: %u\n", duration); rf_reset_state(state); return -1; } // 记录位开始时间(高电平开始) bit_start_time = current_time; state->last_level = 1; } else { // 下降沿:高电平结束,记录高电平持续时间 duration = time_diff_32(current_time, bit_start_time); // 检查数据位宽度是否合理 if (duration < RF_BIT_MIN_WIDTH || duration > RF_BIT_MAX_WIDTH) { printk(KERN_DEBUG "RF: Invalid bit width - high: %u\n", duration); rf_reset_state(state); return -1; } // 使用整数运算检查高低电平比例来判断是0还是1 // 注意:这里我们检查的是高电平持续时间与低电平持续时间的比例 uint32_t low_duration = pulse_width; // 低电平持续时间 if (check_ratio(duration, low_duration, RATIO_1_MIN_NUMERATOR, RATIO_1_MIN_DENOMINATOR, RATIO_1_MAX_NUMERATOR, RATIO_1_MAX_DENOMINATOR)) { // 逻辑1:高电平时间较长 state->rx_shift = (state->rx_shift << 1) | 1; state->uc_rec_count++; printk(KERN_DEBUG "RF: Bit %d: 1 (H:%uus L:%uus)\n", state->uc_rec_count, duration, low_duration); } else if (check_ratio(low_duration, duration, RATIO_0_MIN_NUMERATOR, RATIO_0_MIN_DENOMINATOR, RATIO_0_MAX_NUMERATOR, RATIO_0_MAX_DENOMINATOR)) { // 逻辑0:低电平时间较长 state->rx_shift = (state->rx_shift << 1); state->uc_rec_count++; printk(KERN_DEBUG "RF: Bit %d: 0 (H:%uus L:%uus)\n", state->uc_rec_count, duration, low_duration); } else { // 无效数据位,重新同步 printk(KERN_DEBUG "RF: Invalid bit ratio, resync (H:%u L:%u)\n", duration, low_duration); rf_reset_state(state); return -1; } // 检查是否接收完24位数据 if (state->uc_rec_count >= 24) { return rf_complete_data_reception(state); } state->last_level = 0; } return 0; } // 解码函数 static int rf_data_decode(struct rf_decoder_state *state) { uint32_t current_time; int level; uint32_t pulse_width; // 在函数开头声明所有变量,符合C90标准 current_time = get_32bit_usec_ktime(); level = gpio_get_value(RF_DATA_GPIO); // 如果是第一次调用,初始化时间 if (state->last_edge_time == 0) { state->last_edge_time = current_time; state->last_level = level; return -1; } // 计算脉冲宽度 pulse_width = time_diff_32(current_time, state->last_edge_time); state->last_edge_time = current_time; // 添加合理性检查 - 过滤异常脉冲 if (pulse_width > 100000) { // 100ms最大限制 printk(KERN_DEBUG "RF: Pulse width too large: %u us, resetting\n", pulse_width); rf_reset_state(state); return -1; } // 状态机处理 if (state->bit_rx_sync) { // 同步头检测模式 return rf_detect_sync_header(state, pulse_width, level); } else { // 数据接收模式 return rf_decode_data_bits(state, pulse_width, level); } return 0; } // 中断处理函数 static irqreturn_t rf_data_irq_handler(int irq, void *dev_id) { struct rf_decoder_state *state = (struct rf_decoder_state *)dev_id; // 在中断上下文中进行基础解码 rf_data_decode(state); return IRQ_HANDLED; } // 文件操作函数 static int rf_open(struct inode *inode, struct file *file) { int ret; int irq; // 请求GPIO ret = gpio_request(RF_DATA_GPIO, "rf_data"); if (ret < 0) { printk(KERN_ERR "RF: Failed to request GPIO %d\n", RF_DATA_GPIO); return ret; } // 配置为输入模式 ret = gpio_direction_input(RF_DATA_GPIO); if (ret < 0) { printk(KERN_ERR "RF: Failed to set GPIO direction\n"); gpio_free(RF_DATA_GPIO); return ret; } // 申请中断 - 双边沿触发 irq = gpio_to_irq(RF_DATA_GPIO); ret = request_irq(irq, rf_data_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "rf_data", &rf_decoder); if (ret < 0) { printk(KERN_ERR "RF: Failed to request IRQ for GPIO %d, irq %d\n", RF_DATA_GPIO, irq); gpio_free(RF_DATA_GPIO); return ret; } // 重置解码状态 rf_reset_state(&rf_decoder); rf_decoder.last_edge_time = get_32bit_usec_ktime(); printk(KERN_INFO "RF decoder device opened successfully, IRQ: %d\n", irq); return 0; } static ssize_t rf_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { unsigned long flags; int ret; uint32_t data; if (len < sizeof(uint32_t)) { return -EINVAL; } // 等待数据可用 if (wait_event_interruptible(rf_decoder.read_queue, !kfifo_is_empty(&rf_decoder.rx_data_fifo))) { return -ERESTARTSYS; } spin_lock_irqsave(&rf_decoder.lock, flags); ret = kfifo_out(&rf_decoder.rx_data_fifo, (unsigned char *)&data, sizeof(uint32_t)); spin_unlock_irqrestore(&rf_decoder.lock, flags); if (ret != sizeof(uint32_t)) { return -EIO; } if (copy_to_user(buf, &data, sizeof(uint32_t))) { return -EFAULT; } return sizeof(uint32_t); } static ssize_t rf_write(struct file *file, const char __user *buf, size_t len, loff_t *offset) { // 只读设备,不支持写入 return -EPERM; } static int rf_close(struct inode *inode, struct file *file) { int irq = gpio_to_irq(RF_DATA_GPIO); // 释放中断 free_irq(irq, &rf_decoder); // 释放GPIO gpio_free(RF_DATA_GPIO); printk(KERN_INFO "RF decoder device closed\n"); return 0; } static unsigned int rf_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; poll_wait(file, &rf_decoder.read_queue, wait); if (!kfifo_is_empty(&rf_decoder.rx_data_fifo)) { mask |= POLLIN | POLLRDNORM; } return mask; } static const struct file_operations rf_file_operations = { .owner = THIS_MODULE, .open = rf_open, .read = rf_read, .write = rf_write, .release = rf_close, .poll = rf_poll, }; static int __init rf_init(void) { int ret; // 初始化RF解码器状态 memset(&rf_decoder, 0, sizeof(rf_decoder)); spin_lock_init(&rf_decoder.lock); init_waitqueue_head(&rf_decoder.read_queue); // 初始状态:等待同步头 rf_decoder.bit_rx_sync = 1; rf_decoder.sync_phase = 0; rf_decoder.last_edge_time = 0; // 初始化FIFO缓冲区 rf_decoder.fifo_buffer = kmalloc(RF_RX_FIFO_SIZE, GFP_KERNEL); if (!rf_decoder.fifo_buffer) { printk(KERN_ERR "RF: Failed to allocate FIFO buffer\n"); return -ENOMEM; } // 初始化FIFO ret = kfifo_init(&rf_decoder.rx_data_fifo, rf_decoder.fifo_buffer, RF_RX_FIFO_SIZE); if (ret) { printk(KERN_ERR "RF: Failed to initialize FIFO\n"); kfree(rf_decoder.fifo_buffer); return ret; } // 创建设备号 ret = alloc_chrdev_region(&rf_device_id, 0, COUNT, dev_name); if (ret < 0) { printk(KERN_ERR "RF: Failed to allocate chrdev region\n"); kfifo_free(&rf_decoder.rx_data_fifo); kfree(rf_decoder.fifo_buffer); return ret; } // 初始化字符设备 cdev_init(&rf_cdev, &rf_file_operations); rf_cdev.owner = THIS_MODULE; ret = cdev_add(&rf_cdev, rf_device_id, COUNT); if (ret < 0) { printk(KERN_ERR "RF: Failed to add cdev\n"); goto err_cdev; } // 创建设备类 rf_class = class_create(THIS_MODULE, "rf_class"); if (IS_ERR(rf_class)) { ret = PTR_ERR(rf_class); printk(KERN_ERR "RF: Failed to create class\n"); goto err_class; } // 创建设备节点 if (IS_ERR(device_create(rf_class, NULL, rf_device_id, NULL, dev_name))) { printk(KERN_ERR "RF: Failed to create device\n"); goto err_device; } printk(KERN_INFO "RF decoder driver initialized successfully\n"); printk(KERN_INFO "RF parameters:\n"); printk(KERN_INFO " Sync header: High %d-%d us, Low/High ratio: %d-%d\n", RF_SYNC_HIGH_MIN, RF_SYNC_HIGH_MAX, RF_SYNC_CODE_MIN_SCALE, RF_SYNC_CODE_MAX_SCALE); printk(KERN_INFO " Bit width: %d-%d us\n", RF_BIT_MIN_WIDTH, RF_BIT_MAX_WIDTH); printk(KERN_INFO " Data bits: 24\n"); printk(KERN_INFO "Usage: cat /dev/rf_decoder - Read decoded RF data\n"); return 0; err_device: class_destroy(rf_class); err_class: cdev_del(&rf_cdev); err_cdev: unregister_chrdev_region(rf_device_id, COUNT); kfifo_free(&rf_decoder.rx_data_fifo); kfree(rf_decoder.fifo_buffer); return ret; } static void __exit rf_exit(void) { // 清理设备节点 device_destroy(rf_class, rf_device_id); class_destroy(rf_class); // 清理字符设备 cdev_del(&rf_cdev); unregister_chrdev_region(rf_device_id, COUNT); // 释放FIFO kfifo_free(&rf_decoder.rx_data_fifo); // 释放FIFO缓冲区 if (rf_decoder.fifo_buffer) { kfree(rf_decoder.fifo_buffer); } printk(KERN_INFO "RF decoder driver unloaded\n"); } module_init(rf_init); module_exit(rf_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("AWOL"); MODULE_DESCRIPTION("433MHz RF Signal Decoder Driver with interrupt-based reception"); MODULE_VERSION("1.3");
最新发布
11-15
<think>我们正在处理一个关于shell警告"shell level too high resetting to 1"的问题。根据用户提供的信息,这个警告通常发生在shell嵌套层级(通过环境变量SHLVL表示)过高时,系统为了防止无限递归或资源耗尽而将SHLVL重置为1。 根据引用[1]中的内容,我们可以了解到在bash中,即使前面的命令出错,bash也会继续执行后面的命令。这可能导致一些问题,特别是在脚本中嵌套调用shell(比如在一个shell脚本中调用另一个shell脚本)时,可能会使得SHLVL不断增加,直到达到某个阈值(通常是100)而触发此警告。 解决方案: 1. 检查脚本中是否存在不必要的shell嵌套调用。例如,在脚本中使用`sh`或`bash`命令调用另一个脚本,而实际上可以使用函数或者使用`source`命令(.命令)来避免创建新的shell进程。 2. 如果确实需要调用子shell,注意控制嵌套深度,或者考虑重构代码以减少嵌套。 3. 检查环境变量SHLVL的值,如果发现异常增长,可以尝试在适当的位置重置它(但需谨慎,因为SHLVL是用于记录shell嵌套层级的,通常由shell自动管理)。 然而,需要注意的是,SHLVL变量是由shell自动维护的,每当启动一个新的子shell时,SHLVL就会增加1,退出子shell时减少1。当SHLVL达到一个很高的值(比如100)时,shell会发出警告并重置为1,以防止无限递归。 因此,常见的原因可能是: - 在某个脚本中循环调用自身(直接或间接递归),导致SHLVL不断增加。 - 在配置文件(如.bashrc, .profile等)中意外地启动了新的shell,导致每次打开终端时SHLVL都增加。 具体解决步骤: 步骤1:检查脚本中的递归调用 如果是在运行某个脚本时出现此警告,检查该脚本以及它调用的其他脚本是否存在递归调用。特别注意循环中是否调用了相同的脚本。 步骤2:检查shell配置文件 在用户的shell配置文件(如~/.bashrc, ~/.bash_profile, ~/.profile等)中,检查是否有启动新shell的命令。例如,在配置文件中直接调用一个脚本,而该脚本又启动了新的shell,这样每次打开终端都会增加SHLVL。 步骤3:使用调试信息 在出现问题的脚本中添加调试信息,打印SHLVL的值,以便追踪嵌套层级增加的位置。 例如,在脚本开头添加: ```sh echo "Current shell level: $SHLVL" ``` 步骤4:避免不必要的子shell - 使用函数替代脚本:如果多个脚本需要执行相同的任务,可以将这些任务封装成函数,然后在主脚本中调用这些函数,这样就不会启动新的shell进程。 - 使用`source`或`.`命令:如果需要在当前shell环境中执行另一个脚本(比如设置环境变量),应该使用`source script.sh`或`. script.sh`,而不是`sh script.sh`。 步骤5:检查终端启动配置 如果每次打开终端都会出现警告,那么问题可能出在终端启动时加载的配置文件。检查配置文件中是否有启动新shell的命令,比如在配置文件的末尾有`bash`或`sh`命令。 步骤6:重置SHLVL(临时解决方案) 如果问题难以定位,可以在需要的时候手动重置SHLVL(但这不是根本解决办法): ```sh export SHLVL=0 ``` 注意:这可能会干扰shell的正常嵌套计数,所以只建议作为临时调试手段。 根据引用[2]的内容,我们注意到一个与QEMU虚拟机和内核相关的问题,但这个问题似乎与当前的shell警告无关。因此,我们主要关注shell脚本的嵌套问题。 总结:解决"shell level too high resetting to 1"警告的关键是减少shell的嵌套深度,避免不必要的子shell启动,并检查递归调用。 相关问题: 1. 如何检查shell脚本中的递归调用? 2. 在bash中,`source`命令和直接执行脚本有什么区别? 3. 如何调试shell脚本的嵌套层级问题? 4. 环境变量SHLVL的作用是什么? 5. 在.bashrc文件中应该注意哪些问题以避免shell嵌套?</think>### 解决 "shell level too high resetting to 1" 警告 此警告表示 Shell 嵌套层级(通过 `$SHLVL` 环境变量跟踪)超过系统阈值(通常为 100 层),系统自动将其重置为 1。这通常由以下原因引起: #### 常见原因及解决方案 1. **递归调用 Shell 脚本** - **问题**:脚本直接或间接调用自身(如 `A.sh` 调用 `B.sh`,`B.sh` 又调用 `A.sh`) - **解决**: - 检查脚本调用链,避免循环依赖 - 使用函数替代重复调用的脚本 ```bash # 错误示例:递归调用 # script.sh 内容: ./script.sh # 调用自身 # 正确做法:改用函数 main_task() { # 核心逻辑 } main_task ``` 2. **Shell 配置文件问题** - **问题**:`~/.bashrc`、`~/.profile` 等文件意外启动新 Shell - **解决**: - 检查配置文件中是否包含 `bash`、`sh` 等命令 - 避免在配置文件中直接执行可能启动子 Shell 的操作 ```bash # 错误示例:在 .bashrc 中启动新 Shell if [ -f /some/file ]; then bash # 导致嵌套 fi ``` 3. **终端模拟器配置问题** - **问题**:终端设置(如 GNOME Terminal)在启动时额外调用 Shell - **解决**:检查终端配置的 "自定义命令" 选项,确保未设置强制启动 Shell 的命令。 4. **环境变量污染** - **问题**:`$SHLVL` 被手动修改或异常继承 - **解决**: - 临时重置:`export SHLVL=0` - 检查脚本中是否有修改 `SHLVL` 的代码 #### 调试步骤 1. **追踪 Shell 层级** 在脚本中添加调试信息: ```bash echo "[DEBUG] Current SHLVL: $SHLVL" # 显示当前层级 ``` 2. **检查配置文件** 使用 `grep` 扫描配置文件中可疑命令: ```bash grep -r "sh\\|bash" ~/.bashrc ~/.profile /etc/profile.d/ ``` 3. **简化复现** 通过最小化脚本逐步排除问题: ```bash # test.sh echo "SHLVL start: $SHLVL" # 注释掉可疑代码块 # ./other_script.sh echo "SHLVL end: $SHLVL" ``` #### 预防措施 - 用 `source` 替代直接执行(避免新建 Shell): ```bash # 替代 ./utils.sh source utils.sh # 在当前 Shell 执行 ``` - 控制脚本调用深度,必要时用 `wait` 管理并行任务 - 定期检查环境变量: ```bash env | grep SHLVL # 监控层级变化 ``` > 引用说明:调试时使用 `echo` 输出关键状态是定位 Shell 问题的有效方法,通过检查输出可快速定位嵌套层级异常点[^1]。 --- ### 相关问题 1. 如何查看当前 Shell 的嵌套层级? 2. `source script.sh` 和 `./script.sh` 有何区别? 3. 在 Shell 脚本中如何避免环境变量污染? 4. 哪些操作会隐式创建新的 Shell 子进程? 5. 如何调试 Shell 脚本中的无限递归问题? [^1]: 引用自用户提供的调试方法说明,通过插入唯一标识消息定位代码问题段落。 [^2]: 引用自用户提供的系统兼容性说明,涉及内核版本与虚拟化问题(与当前问题关联度较低)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值