找出下列的定義有什麼區別?

 

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);

}

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 丘猴子 的頭像
    丘猴子

    轉貼部落格

    丘猴子 發表在 痞客邦 留言(0) 人氣()