linux通电总时间检查,Linux模块每秒检查电池状态,更好的检查方式,目前的方式rmmod将无法正常工作...

我正在制作一个每秒都会进行一次acpi调用的linux模块(目前只有20秒)。我希望它每秒都会继续进行acpi呼叫,直到它被移除。就我所知,我将模块放入循环中,如果确实将此循环设置为永久重复,则不能使用rmmod删除模块。有没有一种方法可以为循环设置一个全局变量?

代码:acpi_call.ko

/* Copyright (c) 2010: Michal Kottman */

#include

#include

#include

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

#define BUFFER_SIZE 256

extern struct proc_dir_entry *acpi_root_dir;

char result_buffer[BUFFER_SIZE];

void do_acpi_call(void);

size_t get_avail_bytes(void)

{

return BUFFER_SIZE - strlen(result_buffer);

}

char *get_buffer_end(void)

{

return result_buffer + strlen(result_buffer);

}

int __init init_battcheck(void)

{

int i;

if( true )

{

for (i=0 ; i < 1 ; i++)

{

do_acpi_call();

if(result_buffer[3] == '1')

printk(KERN_INFO "Battery is discharging. %c\n", result_buffer[3]);

else if(result_buffer[3] == '2')

printk(KERN_INFO "Battery is charging. %c\n", result_buffer[3]);

else

printk(KERN_INFO "Battery is CRITICAL. %c\n", result_buffer[3]);

}

}

return 1;

}

/** Appends the contents of an acpi_object to the result buffer

@param result: An acpi object holding result data

@returns: 0 if the result could fully be saved, a higher value otherwise **/

int acpi_result_to_string(union acpi_object *result)

{

if (result->type == ACPI_TYPE_INTEGER)

{

snprintf(get_buffer_end(), get_avail_bytes(),"0x%x", (int)result->integer.value);

}

else if (result->type == ACPI_TYPE_STRING)

{

snprintf(get_buffer_end(), get_avail_bytes(), "\"%*s\"", result->string.length, result->string.pointer);

}

else if (result->type == ACPI_TYPE_BUFFER)

{

int i;

// do not store more than data if it does not fit. The first element is

// just 4 chars, but there is also two bytes from the curly brackets

int show_values = min(result->buffer.length, get_avail_bytes() / 6);

sprintf(get_buffer_end(), "{");

for (i = 0; i < show_values; i++)

sprintf(get_buffer_end(), i == 0 ? "0x%02x" : ", 0x%02x", result->buffer.pointer[i]);

if (result->buffer.length > show_values)

{

// if data was truncated, show a trailing comma if there is space

snprintf(get_buffer_end(), get_avail_bytes(), ",");

return 1;

}

else

{

// in case show_values == 0, but the buffer is too small to hold

// more values (i.e. the buffer cannot have anything more than "{")

snprintf(get_buffer_end(), get_avail_bytes(), "}");

}

}

else if (result->type == ACPI_TYPE_PACKAGE)

{

int i;

sprintf(get_buffer_end(), "[");

for (i=0; i < result->package.count; i++)

{

if (i > 0)

snprintf(get_buffer_end(), get_avail_bytes(), ", ");

// abort if there is no more space available

if (!get_avail_bytes() || acpi_result_to_string(&result->package.elements[i]))

return 1;

}

snprintf(get_buffer_end(), get_avail_bytes(), "]");

}

else

{

snprintf(get_buffer_end(), get_avail_bytes(), "Object type 0x%x\n", result->type);

}

// return 0 if there are still bytes available, 1 otherwise

return !get_avail_bytes();

}

void do_acpi_call(void)

{

acpi_status status;

acpi_handle handle;

struct acpi_object_list arg;

struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

printk(KERN_INFO "acpi_call: Calling \\_SB.PCI0.LPCB.EC0.BAT0._BST\n");

// get the handle of the method, must be a fully qualified path

status = acpi_get_handle(NULL, (acpi_string) "\\_SB.PCI0.LPCB.EC0.BAT0._BST", &handle);

if (ACPI_FAILURE(status))

{

snprintf(result_buffer, BUFFER_SIZE, "Error: %s", acpi_format_exception(status));

printk(KERN_ERR "acpi_call: Cannot get handle: %s\n", result_buffer);

return;

}

// prepare parameters

arg.count = 0;

arg.pointer = NULL;

// call the method

status = acpi_evaluate_object(handle, NULL, &arg, &buffer);

if (ACPI_FAILURE(status))

{

snprintf(result_buffer, BUFFER_SIZE,"Error: %s", acpi_format_exception(status));

printk(KERN_ERR "acpi_call: Method call failed: %s\n", result_buffer);

return;

}

// reset the result buffer

*result_buffer = '\0';

acpi_result_to_string(buffer.pointer);

kfree(buffer.pointer);

printk(KERN_INFO "acpi_call: Call successful: %s\n", result_buffer);

}

/** module initialization function */

int __init init_acpi_call(void)

{

struct proc_dir_entry *acpi_entry = create_proc_entry("call", 0660, acpi_root_dir);

strcpy(result_buffer, "not called");

if (acpi_entry == NULL)

{

printk(KERN_ERR "acpi_call: Couldn't create proc entry\n");

return -ENOMEM;

}

printk(KERN_INFO "acpi_call: Module loaded successfully\n");

init_battcheck();

return 0;

}

void __exit unload_acpi_call(void)

{

remove_proc_entry("call", acpi_root_dir);

printk(KERN_INFO "acpi_call: Module unloaded successfully\n");

}

module_init(init_acpi_call);

module_exit(unload_acpi_call);编辑:我只是意识到我没有这个等待一秒钟,每次打电话给do_acpi_call,我这样做只是为了检查错误。这只是我正在制作的一个例子。我在问是否有一种方法可以让我可以像我描述的那样删除一个处于循环中的模块?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值