Buffer I/O error on device sr0

在尝试读取一张旧CD时遇到了Buffer I/O error on device sr0的问题,即使使用root权限也无法通过eject命令弹出光驱。dmesg显示了一系列关于设备sr0的错误信息,包括未处理的错误码。最终通过运行'lsof'找到占用设备的进程并杀死该进程,然后使用'eject'成功弹出光盘。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Buffer I/O error on device sr0, logical block 0

I check today some old CDs, some of them were from ’90 so of course they didn’t work. With one of them was a problem with reading… and ejecting CD-ROM. My PC wasn’t able to eject the CD even calling this command from root:

eject sr0 -rm

didn’t work.

DMESG said:

[ 1067.416522] Buffer I/O error on device sr0, logical block 0
[ 1075.923084] sr 1:0:0:0: [sr0] Unhandled sense code
[ 1075.923088] sr 1:0:0:0: [sr0] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 1075.923097] sr 1:0:0:0: [sr0] Sense Key : Hardware Error [current]
[ 1075.923105] sr 1:0:0:0: [sr0] Add. Sense: Timeout on logical unit
[ 1075.923115] sr 1:0:0:0: [sr0] CDB: Read(10): 28 00 00 00 00 00 00 00 02 00
[ 1075.923130] end_request: I/O error, dev sr0, sector 0
[ 1075.923137] Buffer I/O error on device sr0, logical block

The CD wasn’t mounted, there was only a thread for the device, which wasn’t even mounted (I also wasn’t able to mount it from root):

umount: /dev/sr0: not mounted

 

Solution:

root@Agilob-PC:# lsof /dev/sr0
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
blkid 4079 root 3r BLK 11,0 0t0 7203 /dev/sr0

root@Agilob-PC:# kill -s 9 4079 ; eject

Worked for me!

#include "max30102.h" #include <math.h> static const char *TAG = "max30102"; #define MAX30102_I2C_SCL 2 // GPIO number used for I2C master clock #define MAX30102_I2C_SDA 1 // GPIO number used for I2C master data #define MAX30102_I2C_NUM 0 // I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip #define MAX30102_I2C_FREQ_HZ 50000 // I2C master clock frequency #define MAX30102_I2C_TX_BUF_DISABLE 0 // I2C master doesn't need buffer #define MAX30102_I2C_RX_BUF_DISABLE 0 #define MAX30102_I2C_TIMEOUT_MS 1000 #define MAX30102_GPIO_INT 11 // GPIO number used for MAX30102 int #define MAX30102_ADDR 0x57 // I2C device MAX30102's 7-bit address #define MAX30102_PART_ID_REG_ADDR 0xff static QueueHandle_t gpio_evt_queue = NULL; static esp_err_t max30102_i2c_init() { int i2c_master_port = MAX30102_I2C_NUM; i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = MAX30102_I2C_SDA, .scl_io_num = MAX30102_I2C_SCL, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = MAX30102_I2C_FREQ_HZ, }; i2c_param_config(i2c_master_port, &conf); return i2c_driver_install(i2c_master_port, conf.mode, MAX30102_I2C_RX_BUF_DISABLE, MAX30102_I2C_TX_BUF_DISABLE, 0); } static esp_err_t max30102_register_read(uint8_t reg_addr, uint8_t *data, size_t len) { return i2c_master_write_read_device(MAX30102_I2C_NUM, MAX30102_ADDR, &reg_addr, 1, data, len, MAX30102_I2C_TIMEOUT_MS /portTICK_PERIOD_MS); } /** * @brief Write a byte to a MAX30102 register */ static esp_err_t max30102_register_write_byte(uint8_t reg_addr, uint8_t data) { int ret; uint8_t write_buf[2] = {reg_addr, data}; ret = i2c_master_write_to_device(MAX30102_I2C_NUM, MAX30102_ADDR, write_buf, sizeof(write_buf), MAX30102_I2C_TIMEOUT_MS / portTICK_PERIOD_MS); return ret; } void gpio_intr_task() { uint8_t byte[6]; int data[2]; float red_ac, ir_ac; static float red_buffer[10] = {0}; static float ir_buffer[10] = {0}; static int buffer_index = 0; float red_avg = 0, ir_avg = 0; float ratio; float spo2 = 0; float heart_rate = 0; uint8_t io_num; float calculate_heart_rate() { // Implement your heart rate calculation logic here return 0.0; } for (;;) { if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { ESP_ERROR_CHECK(max30102_register_read(0x07, byte, 6)); data[0] = ((byte[0] << 16 | byte[1] << 8 | byte[2]) & 0x03ffff); // Red LED data data[1] = ((byte[3] << 16 | byte[4] << 8 | byte[5]) & 0x03ffff); // IR LED data // Simple moving average filter red_buffer[buffer_index] = data[0]; ir_buffer[buffer_index] = data[1]; buffer_index = (buffer_index + 1) % 10; for (int i = 0; i < 10; i++) { red_avg += red_buffer[i]; ir_avg += ir_buffer[i]; } red_avg /= 10; ir_avg /= 10; // Calculate AC component red_ac = data[0] - red_avg; ir_ac = data[1] - ir_avg; // Check if there is enough signal if (fabs(red_ac) > 100 && fabs(ir_ac) > 100) { ratio = ir_ac / red_ac; spo2 = -45.060 * pow(ratio, 2) + 30.354 * ratio + 94.845; heart_rate = calculate_heart_rate(); // Implement your own heart rate calculation function printf("血氧: %.2f%%, 心率: %.2f bpm\n", spo2, heart_rate); } else { printf("信号弱或无手指检测\n"); } // Clear PPG_RDY ! Cannot receive the first interrupt without clearing ! uint8_t data; ESP_ERROR_CHECK(max30102_register_read(0x00, &data, 1)); ESP_ERROR_CHECK(max30102_register_read(0x01, &data, 1)); } } } static void IRAM_ATTR gpio_isr_handler(void *arg) { uint32_t gpio_num = (uint32_t)arg; xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); } /** * @brief init the gpio intr for MAX30102 */ static esp_err_t max30102_gpio_intr_init() { gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_NEGEDGE; io_conf.mode = GPIO_MODE_INPUT; io_conf.pin_bit_mask = (1ULL << MAX30102_GPIO_INT); io_conf.pull_down_en = 0; io_conf.pull_up_en = 1; ESP_ERROR_CHECK(gpio_config(&io_conf)); // create a queue to handle gpio event from isr gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); // start gpio task xTaskCreate(gpio_intr_task, "gpio_intr_task", 2048, NULL, 10, NULL); // install gpio isr service gpio_install_isr_service(0); // hook isr handler for specific gpio pin gpio_isr_handler_add(MAX30102_GPIO_INT, gpio_isr_handler, (void *)MAX30102_GPIO_INT); return ESP_OK; } void get_temp() { uint8_t byte[2]; float temp; ESP_ERROR_CHECK(max30102_register_write_byte(0x21, 0x01)); vTaskDelay(100 / portTICK_PERIOD_MS); ESP_ERROR_CHECK(max30102_register_read(0x1f, &byte[0], 1)); ESP_ERROR_CHECK(max30102_register_read(0x20, &byte[1], 1)); temp = (int8_t)(byte[0]) + byte[1] * 0.0625; printf("Temp: %f\n", temp); // FIFO ESP_ERROR_CHECK(max30102_register_write_byte(0x04, 0x00)); // clear FIFO Write Pointer ESP_ERROR_CHECK(max30102_register_write_byte(0x05, 0x00)); // clear FIFO Overflow Counter ESP_ERROR_CHECK(max30102_register_write_byte(0x06, 0x00)); // clear FIFO Read Pointer // clear PPG_RDY ! Cannot receive the first interrupt without clearing ! uint8_t data; ESP_ERROR_CHECK(max30102_register_read(0x00, &data, 1)); ESP_ERROR_CHECK(max30102_register_read(0x01, &data, 1)); } void max30102_init() { ESP_ERROR_CHECK(max30102_i2c_init()); ESP_LOGI(TAG, "MAX30102 I2C initialized successfully"); max30102_gpio_intr_init(); ESP_LOGI(TAG, "MAX30102 GPIO INTR initialized successfully"); // reset ESP_ERROR_CHECK(max30102_register_write_byte(0x09, 0x40)); vTaskDelay(100 / portTICK_PERIOD_MS); // Interrupt Enable ESP_ERROR_CHECK(max30102_register_write_byte(0x02, 0xc0)); // enable interrupts: A_FULL: FIFO Almost Full Flag and PPG_RDY: New FIFO Data Ready ESP_ERROR_CHECK(max30102_register_write_byte(0x03, 0x02)); // enable interrupt: DIE_TEMP_RDY: Internal Temperature Ready Flag // FIFO ESP_ERROR_CHECK(max30102_register_write_byte(0x04, 0x00)); // clear FIFO Write Pointer ESP_ERROR_CHECK(max30102_register_write_byte(0x05, 0x00)); // clear FIFO Overflow Counter ESP_ERROR_CHECK(max30102_register_write_byte(0x06, 0x00)); // clear FIFO Read Pointer // FIFO Configuration ESP_ERROR_CHECK(max30102_register_write_byte(0x08, 0x0f)); // SMP_AVE = 0b000: 1 averaging, FIFO_ROLLOVER_EN = 0, FIFO_A_FULL = 0xf // Mode Configuration ESP_ERROR_CHECK(max30102_register_write_byte(0x09, 0x03)); // MODE = 0b011: SpO2 mode // SpO2 Configuration ESP_ERROR_CHECK(max30102_register_write_byte(0x0a, 0x47)); // SPO2_ADC_RGE = 0b10: 8192, SPO2_SR = 0b001: 100 SAMPLES PER SECOND, // LED_PW = 0b11: PULSE WIDTH 411, ADC RESOLUTION 18 // LED Pulse Amplitude ESP_ERROR_CHECK(max30102_register_write_byte(0x0c, 0x50)); // LED1_PA(red) = 0x24, LED CURRENT 16mA ESP_ERROR_CHECK(max30102_register_write_byte(0x0d, 0x50)); // LED2_PA(IR) = 0x24, LED CURRENT 16mA ESP_ERROR_CHECK(max30102_register_write_byte(0x10, 0x50)); // PILOT_PA = 0x24, LED CURRENT 16mA // clear PPG_RDY ! Cannot receive the first interrupt without clearing ! uint8_t data; ESP_ERROR_CHECK(max30102_register_read(0x00, &data, 1)); ESP_LOGI(TAG, "Interrupt Status 1: 0x%x", data); ESP_ERROR_CHECK(max30102_register_read(0x01, &data, 1)); ESP_LOGI(TAG, "Interrupt Status 2: 0x%x", data); } 这是我目前的代码,请帮我分析代码后,将心率和血氧的计算算法优化补齐
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值