Linux中的宏DIV_ROUND_UP和BITS_TO_LONGS,搜索网络,发现很多人在理解上有问题。说DIV_ROUND_UP这个宏是向上取整数,按照定义,不能自圆其说。答案是对的,凑答案,导致结果正确。
现分析如下:
1、下面是是从Linux摘取的宏定义:
打开“/home/zgq/linux/atk-mp1/linux/my_linux/linux-5.4.31/include/linux/bitops.h”
#define DIV_ROUND_UP(n,d) ( ((n) + (d) - 1) / (d) )
#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
//BITS_PER_BYTE表示每个字节8位
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
//BITS_PER_TYPE(long)的值为8*8=64,即long型数据为64位,注意:这里的nr>0
//当1<nr<=64,返回值为1,表示占用1个long型数据
//当64<nr<=128,返回值为2,表示占用2个long型数据
//当128<nr<=192,返回值为3,表示占用3个long型数据
2、应用举例
打开
“/home/zgq/linux/atk-mp1/linux/my_linux/linux-5.4.31/include/uapi/linux/input-event-codes.h”
#define INPUT_PROP_MAX 0x1f
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) //INPUT_PROP_CNT=32
#define EV_MAX 0x1f
#define EV_CNT (EV_MAX+1) //定义EV_CNT为32
#define KEY_MAX 0x2ff
#define KEY_CNT (KEY_MAX+1) //KEY_CNT=768
#define REL_MAX 0x0f
#define REL_CNT (REL_MAX+1) //REL_CNT=16
打开
“/home/zgq/linux/atk-mp1/linux/my_linux/linux-5.4.31/include/uapi/linux/input-event-codes.h”
#define ABS_MAX 0x3f
#define ABS_CNT (ABS_MAX+1) //ABS_CNT=64
#define MSC_MAX 0x07
#define MSC_CNT (MSC_MAX+1) //MSC_CNT=8
#define LED_MAX 0x0f
#define LED_CNT (LED_MAX+1) //LED_MAX=16
#define SND_MAX 0x07
#define SND_CNT (SND_MAX+1) //SND_CNT=8
/home/zgq/linux/atk-mp1/linux/my_linux/linux-5.4.31/include/uapi/linux/input.h
#define FF_MAX 0x7f
#define FF_CNT (FF_MAX+1) //FF_CNT=128
#define SW_MAX 0x0f
#define SW_CNT (SW_MAX+1) //SW_CNT=16
struct input_dev {
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
/*INPUT_PROP_CNT=32,(32+63)/64取整数为1占用1个long型空间*/
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
/*表示输入事件类型*/
/*EV_CNT=32,(32+63)/64取整数为1占用1个long型空间*/
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
/*KEY_CNT=768,(768+63)/64取整数为12占用12个long型空间*/
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
/*REL_CNT=16,(16+63)/64取整数为1占用1个long型空间*/
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
/*ABS_CNT=64,(64+63)/64取整数为1占用1个long型空间*/
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
/*MSC_CNT=8,(8+63)/64取整数为1占用1个long型空间*/
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
/*LED_CNT=16,(16+63)/64取整数为1占用1个long型空间*/
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
/*SND_CNT=8,(8+63)/64取整数为1占用1个long型空间*/
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
/*FF_CNT=128,(128+63)/64取整数为2占用2个long型空间*/
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
/*SW_CNT=16,(16+63)/64取整数为1占用1个long型空间*/
unsigned int hint_events_per_packet;
unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
int (*setkeycode)(struct input_dev *dev,
const struct input_keymap_entry *ke,
unsigned int *old_keycode);
int (*getkeycode)(struct input_dev *dev,
struct input_keymap_entry *ke);
struct ff_device *ff;
struct input_dev_poller *poller;
unsigned int repeat_key;
struct timer_list timer;
int rep[REP_CNT];
struct input_mt *mt;
struct input_absinfo *absinfo;
unsigned long key[BITS_TO_LONGS(KEY_CNT)];
unsigned long led[BITS_TO_LONGS(LED_CNT)];
unsigned long snd[BITS_TO_LONGS(SND_CNT)];
unsigned long sw[BITS_TO_LONGS(SW_CNT)];
int (*open)(struct input_dev *dev);
void (*close)(struct input_dev *dev);
int (*flush)(struct input_dev *dev, struct file *file);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
struct input_handle __rcu *grab;
spinlock_t event_lock;
struct mutex mutex;
unsigned int users;
bool going_away;
struct device dev;
struct list_head h_list;
struct list_head node;
unsigned int num_vals;
unsigned int max_vals;
struct input_value *vals;
bool devres_managed;
ktime_t timestamp[INPUT_CLK_MAX];
};