找出下列的定義有什麼區別?
const int a;
const int *a;
int *const a;
int const *a;
const int *const a ;
const int const *a ;
再寫driver 的時候, 聲明變量的時候, 還是嚴謹一些比較好。該加const 最好加const ,免得意外出錯。
3> 到google上學習 , 對齊方面的知識 , 寫一個宏, 實現 32 對齊, 分為 32向前對齊和向后對齊: fn_before(33) = 32 , fn_after(33) = 64
學習 __attribute__((__packed__)) 到底是什麼意思? 明白后, 繼續學習 GNU 其他的擴展語法。
//先自己寫, 然后再對照這個程序。
核心的部分, 就是下面幾句。
思想就是 把 一段內存的起始地址轉換為一個結構體的指針 , 這樣 ,就可以通過結構體 來存取 寄存器的值, 寫起程序來, 比較方便 和便捷 。
//一定要用 volatile來定義, 對於寫driver ,定義寄存器一定要用volatile 修飾
typedef volatile u8 S 3C 24X0_REG8;
typedef volatile u16 S 3C 24X0_REG16;
typedef volatile u32 S 3C 24X0_REG32;
#define S 3C 2410_WDTCON_RSTEN (0x01) // 1<<0
#define S 3C 2410_WDTCON_INTEN (1<<2)
#define S 3C 2410_WDTCON_ENABLE (1<<5)
/* WATCH DOG TIMER (see manual chapter 18) */
typedef struct {
S 3C 24X0_REG32 WDTCON;
S 3C 24X0_REG32 WDTDAT;
S 3C 24X0_REG32 WDTCNT;
} /*__attribute__((__packed__))*/ S 3C 24X0_WATCHDOG;
#define S 3C 24X0_WATCHDOG_BASE s 3c _wdt_base
static inline S 3C 24X0_WATCHDOG * const S 3C 24X0_GetBase_WATCHDOG(void)
{
return (S 3C 24X0_WATCHDOG * const)S 3C 24X0_WATCHDOG_BASE;
}
static void wdt_enable(void)
{
//這里用const 修飾符, 表示 , rWATCHDOG 是個指針常量。
S 3C 24X0_WATCHDOG *const rWATCHDOG = S 3C 24X0_GetBase_WATCHDOG(); //255 //128
u16 COUNTER_VALUE = heartbeat * ( 50000000 / (PRESCALER + 1) / DIVISION_FACTOR );
//WATCHDOG DAT REGISTER
rWATCHDOG->WDTDAT = COUNTER_VALUE;
//WATCHDOG COUNTER REGISTER
rWATCHDOG->WDTCNT = COUNTER_VALUE;
//write WDTCON register
rWATCHDOG->WDTCON &= ~0xff00; //bit8~bit15 清零,然后寫入PRESCALER
rWATCHDOG->WDTCON |= (PRESCALER << 8);
rWATCHDOG->WDTCON |= S 3C 2410_WDTCON_ENABLE | S 3C 2410_WDTCON_RSTEN;
}
//可以對比一下, 用 readb/readw/readl() 代碼量就多了不少, 而且 不自然。 !雖然是這樣, kernel的開發者還是推荐用 readb/w/l () 系列的函數, 最新的就是 ioread8/16/32()系列函數。
static void wdt_enable(void)
{
u32 tmp; //255 //128
u16 COUNTER_VALUE = heartbeat * ( 50000000 / (PRESCALER + 1) / DIVISION_FACTOR );
//u16 COUNTER_VALUE = (1 << 16) -10;
printk("COUNTER_VALUE=%hu\n",COUNTER_VALUE);
printk("S 3C 2410_WTCNT address = %p\n",S 3C 2410_WTCNT);
//寫入 S 3C 2410_WTDAT
iowrite32(COUNTER_VALUE, S 3C 2410_WTDAT);
//寫入S 3C 2410_WTCNT
iowrite32(COUNTER_VALUE, S 3C 2410_WTCNT);
tmp = ioread32(S 3C 2410_WTCON);
tmp &= ~0xff00; //bit8~bit15 清零,然后寫入PRESCALER
tmp |= (PRESCALER << 8);
//再寫入division factor
tmp &= ~(0x03 << 3);
tmp |= 0x03 << 3; //11b is 128 division
printk("the value written S 3C 2410_WTCON=0x%04x\n",tmp);
iowrite32(tmp, S 3C 2410_WTCON);
//重新eanble reset
tmp = ioread32(S 3C 2410_WTCON);
iowrite32(tmp |S 3C 2410_WTCON_ENABLE | S 3C 2410_WTCON_RSTEN , S 3C 2410_WTCON);
//test,
tmp = ioread32(S 3C 2410_WTCNT);
printk("S 3C 2410_WTCNT value = %hu\n",tmp);
}