有助于了解宏 [英] help to understand macro

查看:234
本文介绍了有助于了解宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题要了解MTD驱动程序的一些片code的

I'm having problem to understand some piece of code in MTD driver

#define ROUNDUP(x, y)       ((((x)+((y)-1))/(y))*(y))
...
static struct mtd_partition my_parts[] =
{
   {
      .name = "boot",
      .size = 0,
      .offset = 0,
      .mask_flags = MTD_WRITEABLE
   },
   {
      .name = "linux",
      .size = 0,
      .offset = 0
   },
   {
       .name = "rootfs",
       .size = 0,
       .offset = 0,
       .mask_flags = MTD_WRITEABLE
   },
   {
       .name = "nvram",
       .size = 0,
       .offset = 0
   },
   {
       .name = 0,
       .size = 0,
       .offset = 0
   }
}
...

i = (sizeof(bcm947xx_parts)/sizeof(struct mtd_partition)) - 2;

bcm947xx_parts[i].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
bcm947xx_parts[i].offset = size - bcm947xx_parts[i].size;

因此​​,这里是我的questoins:
1)为什么是必要的围捕分区的大小?
2)你能帮助理解四舍五入是如何工作的?
3)在同一个平台上的引导装载程序闪存驱动程序不执行此特定分区的四舍五入,使闪光灯布局在内核侧和在自举程序具有不同的偏移。是什么原因?

So here are my questoins: 1) why is it necessary to round up the size of the partition? 2) could you help to understand how the rounding works? 3) flash driver in boot loader on the same platform doesn't do the rounding for this specific partition, so the flash layout has different offsets in the kernel side and in the bootloader. What is the reason for this?

在此先感谢任何宝贵的意见!

Thanks in advance for any valuable comments !

推荐答案

(1)快闪记忆体出现在其擦除大小的倍数。 (显然,至少,这是引用的code告诉我。)这意味着在NVRAM的结束和任何随之而来的差距。该间隙小于一个擦除尺寸的大小。在Flash中,它的方便,不要把不同的重写时间表两个对象在一个单一的擦除块 - 不断变化的任一对象需要闪存存储控制器块复制到临时存储,应用部分更新商店,擦除块(慢ISH),并写入更新块总店。 (可重复使用不同的previously擦除块并拧回原块的地方。但是,这被认为是一种高科技的优化。)

(1) Flash memory comes in multiples of its erase size. (Apparently. At least, this is what the quoted code tells me.) This means there is a gap between the end of the NVRAM and whatever comes next. This gap is less than the size of one erase size. In flash, it's convenient to not put two objects with different rewrite schedules in a single erase block -- changing either object requires the flash storage controller to copy the block to a temporary store, apply a partial update to the store, erase the block (slow-ish), and write the updated block to the main store. (It can reuse a different previously erased block and thread it back in the place of the original block. But this is considered a high tech optimization.)

(2)如何解析宏:

((((x)+((y)-1))/(y))*(y))

步骤1,删除围绕确保作为参数传递复杂的前pressions不以意想不到的方式突然重新绑定参数的括号由于操作precedence。

Step 1, remove the parens around the arguments that make sure that complicated expressions passed as arguments don't suddenly rebind in unexpected ways due to operator precedence.

(((x+(y-1))/y)*y)

步骤2,删除括号偏执对于有明确指示的precedence操作。

Step 2, remove paranoid parens for operations that clearly have the indicated precedence.

(x+y-1)/y*y

步骤3,使用你的C解析规则,不是你的代数规则。如果x和y都是整数类型(在code没有足够的信息可以肯定的这一点),那么划分是整数除法,所以从C到数学转换。

Step 3, use your C parsing rules, not your algebra rules. If x and y are integral types (not enough information in your code to be certain of this), then the division is integer division, so translate from C to math.

 floor((x+y-1)/y)*y

步骤4,阅​​读。如果x是y的倍数,则由于Y-1太小为y的倍数时,操作只是还给X]。如果x大于y的多个1以上,则沿+ y-1按压分子上y的倍数,其结果是y的最小倍数恰好是大于x。事实上,如果x大于y的多个1更大,y-1多之间,则+ Y-1凸点的分子上超过y的倍数和四舍五入是的Y时的最小倍数的结果大于x

Step 4, read. If x is a multiple of y, then since y-1 is too small to be a multiple of y, the operation just gives back x. If x is 1 more than a multiple of y, then the +y-1 pushes the numerator over the next multiple of y and the result is the smallest multiple of y that happens to be larger than x. In fact, if x is between 1 more and y-1 more than a multiple of y, the "+y-1" bumps the numerator up over the next multiple of y and the result of rounding up is the smallest multiple of y larger than x.

我们发现什么,因此是ROUNDUP(X,Y)x舍入到这恰好是大于或等于x y的最小倍数。此外,该宏计算它的第二个参数不止一次:不要把副作用前pressions在第二个插槽,除非你希望这些副作用发生的每次呼叫三次。 (考虑INT I = 3; ROUNDUP(6,我++),不知这SUBEX pressions进行评估之前和之后每次我的三个增量)。

What we find, therefore is that ROUNDUP(x,y) rounds x up to the smallest multiple of y that happens to be greater than or equal to x. Additionally, this macro evaluates its second argument more than once: don't put expressions with side effects in the second slot unless you want those side effects to happen three times per call. (Consider int i = 3; ROUNDUP(6,i++) and wonder which subexpressions are evaluated before and which after each of the three increments of i.)

(3)不知道。没有人告诉引导程序笔者,仅NVRAMs进来erasesize的倍数?

(3) No idea. No one told the bootloader writer that NVRAMs only come in multiples of erasesize?

这篇关于有助于了解宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆