linux内核 task cmd,linux kernel 常用函数 备忘

一、字符串转换函数

Linux内核中提供的一些字符串转换函数:

lib/vsprintf.c

[cpp]  view plain copy print ?

unsignedlonglongsimple_strtoull(constchar*cp,char**endp, unsignedintbase)

unsigned longsimple_strtoul(constchar*cp,char**endp, unsignedintbase)

longsimple_strtol(constchar*cp,char**endp, unsignedintbase)

longlongsimple_strtoll(constchar*cp,char**endp, unsignedintbase)

intstrict_strtoul(constchar*cp, unsignedintbase, unsignedlong*res)

intstrict_strtol(constchar*cp, unsignedintbase,long*res)

intstrict_strtoull(constchar*cp, unsignedintbase, unsignedlonglong*res)

intstrict_strtoll(constchar*cp, unsignedintbase,longlong*res)

intsprintf(char*buf,constchar*fmt, ...)

intsnprintf(char*buf,size_tsize,constchar*fmt, ...)

intsscanf(constchar*buf,constchar*fmt, ...)

此函数现在linux推荐用kstrtol替换以上的字符串转换函数 (lib/kstrtox.c)

static inline int __must_check kstrtol(const char *s, unsigned int base, long *res)

{

/*

* We want to shortcut function call, but

* __builtin_types_compatible_p(long, long long) = 0.

*/

if (sizeof(long) == sizeof(long long) &&

__alignof__(long) == __alignof__(long long))

return kstrtoll(s, base, (long long *)res);

else

return _kstrtol(s, base, res);

}

调用方法简化了下,并把最后要的整数值以参数的形式得到。

unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)

功能:将一个字符串转换成unsigend long long型数据。

返回:返回转换后数据。

参数:cp指向字符串的开始,endp指向分析的字符串末尾的位置,base为要用的基数(进制数),base为0表示通过cp来自动判断基数,函数自动可识别的基数:‘0x’表示16进制,‘0’表示8进制,其它都认定为10进制。函数可转换成数字的有效字符为:[0,f]。举例:cp = “0x12str”,base = 0,则返回unsigned long long为18,*endp = “str”。 参数下同。

unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)

功能:将一个字符串转换成unsigend long型数据。

返回:返回转换后数据。

long simple_strtol(const char *cp, char **endp, unsigned int base)

功能:将一个字符串转换成sigend long型数据。

返回:返回转换后数据。

说明:该函数调用simple_strtoul,但它先会判断cp指向的字符串的第一个字符是否为负号‘-’。如果为‘-’,它返回负的simple_strtoul的结果。

如:simple_strtol(func->argv, NULL, 0)   // 它会自动识别16进制和8进制,只要你写法匹配,还是很不错的函数实现!

long long simple_strtoll(const char *cp, char **endp, unsigned int base)

功能:将一个字符串转换成sigend long long型。

返回:返回转换后数据。

int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)

功能:将一个字符串转换成unsigend long型。

返回:转换成功返回0,否则返回负。res指向转换后的unsigned long数据。

说明:该函数对cp指向的字符串严格要求,cp指向的字符串必须为真正的unsigned long形式的字符串。字符串必须以“0x”、“0”、[0,f]开始,中间全部为有效的字符[0,f],否则返回为负。它会处理字符串最后的“\n”字符。下同。

int strict_strtol(const char *cp, unsigned int base, long *res)

功能:将一个字符串转换sigend long型。

返回:转换成功返回0,否则返回负。res指向转换后的signed long数据。

int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)

功能:将一个字符串转换unsigend long long型。

返回:转换成功返回0,否则返回负。res指向转换后的unsigned long long数据。

int strict_strtoll(const char *cp, unsigned int base, long long *res)

功能:将一个字符串转换sigend long long型。

返回:转换成功返回0,否则返回负。res指向转换后的signed long long数据。

int sprintf(char *buf, const char *fmt, ...)

功能:格式化输出字符串,类似于printf,只是用字符串buf作为输出对象。

返回:返回写入buf字符串的字符个数。

int snprintf(char *buf, size_t size, const char *fmt, ...)

功能:格式化输出字符串,类似于printf,只是用字符串buf作为输出对象。其中size为buf的大小(包括‘\0’字符)。

返回:返回写入buf字符串的字符个数。

int sscanf(const char *buf, const char *fmt, ...)

功能:格式化输入字符串,类似于scanf,只是用字符串buf作为输入对象。

返回:返回读取buf字符串的字符个数。

lib/kasprintf

[cpp]  view plain copy print ?

char*kasprintf(gfp_t gfp,constchar*fmt, ...)

char *kasprintf(gfp_t gfp, const char *fmt, ...)

功能:格式化输出字符串到一段且gfp分配的内存中。

返回:返回指向该内容的字符串指针。

二、设置定时器函数

setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);

此函数用来注册回调函数及参数

然后使用mod_timer(&hdev->cmd_timer, jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));

这个函数来修改超时时间,超时时间比如1s可使用msecs_to_jiffies(1000)来转换为jiffies。

这是最简单的设置定时器的方法了,当1s超时时间到后,kernel将会调用hci_cmd_timer函数。

/* HCI command timer function */

static void hci_cmd_timer(unsigned long arg)

{

struct hci_dev *hdev = (void *) arg;

BT_ERR("%s command tx timeout", hdev->name);

atomic_set(&hdev->cmd_cnt, 1);

tasklet_schedule(&hdev->cmd_task);

}如果需要删除定时器的话,调用del_timer(&hdev->cmd_timer);这个函数来删除,或者

调用del_timer_sync(&hdev->cmd_timer);它来删除,后者会等待hander完成后再删除,当然也可以用下面的常规方式:

定时器有关的头文件:

view plain

#include

#include

与定时器有关的结构体:

view plain

structtimer_list {

structlist_head entry;

unsigned longexpires;//定时间隔 jiffies+delay

void(*function)(unsignedlong);//定时器执行函数

unsigned longdata;//私有数据

structtvec_base *base;

#ifdef CONFIG_TIMER_STATS

void*start_site;

charstart_comm[16];

intstart_pid;

#endif

#ifdef CONFIG_LOCKDEP

structlockdep_map lockdep_map;

#endif

};

structtimer_list time;

1、初始化定时器:

view plain

init_timer(&(time));

2、设置time的值与返回函数:

view plain

time.data = (unsignedlong)datap;

time.function = func_exec_timer;

(注:以上两步可以用函数setup_timer(time,func_exec_timer, datap)代替,该函数实现赋值并初始化定时器)

3、设置定时时间

view plain

time.expires = jiffies + 100;

4、注册内核定时器,将定时器添加到内核动态定时器的链表中

view plain

add_timer(&(time));

5、在定时器处理函数

func_exec_timer里,当处理完相应工作后,可能需要重新添加定时器,继续实现定时功能,此时需要做的步骤为:

view plain

time.expires = jiffies + 100;

add_timer(&(time));

6、当使用完定时器时,要将定时器删除:

view plain

del_timer(&time);

三、内核中设置一次性超时的另一种机制(摘自i2c-core.c):

/* Retry automatically on arbitration loss */

orig_jiffies = jiffies;

for (ret = 0, try = 0; try <= adap->retries; try++) {

ret = adap->algo->master_xfer(adap, msgs, num);

if (ret != -EAGAIN)

break;

if (time_after(jiffies, orig_jiffies + adap->timeout))

break;

}

四、内核常用函数likely 和 unlikely

#define likely(x) __builtin_expect(!!(x), 1)也就是说明x==1是“经常发生的”或是“很可能发生的”。

使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面, 使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。

if(likely(foo))  //认为foo通常为1

if(unlikely(foo)) //认为foo通常为0

五、驱动代码中获得fastboot或uboot通过cmdline传给kernel的具体内容

static int lcd_id;

static struct msm_panel_info pinfo;

static int __init get_lcd_type(char *options)

{

if (!options) {

lcd_id = LCD_DEFAULT_TYPE;

return 0;

}

lcd_id = simple_strtol(options, NULL, 0);

return 0;

}

__setup("lcd_id=", get_lcd_type);

六、驱动代码中打印log过多,通过用两次时间间隔来控制打印

static unsigned long prev_jiffy = 0;

if (!prev_jiffy)

prev_jiffy = jiffies;

if (time_after(jiffies, prev_jiffy + 1 * HZ)) {

prev_jiffy = jiffies;

printk(KERN_ERR "log\n");

dump_stack();

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值