国嵌6410的代码注释

#include<linux/module.h>
#include<linux/init.h>  //#include<linux/kernel.h> 
//编写内核常用头文件


MODULE_LICENSE("GPL");    //    许可权限申明。若不申明,这在加载时会收到内核warning
MODULE_AUTHOR("goat"); //  module writer 
MODULE_DESCRIPTION("Hello world module");  // 描述
/*  MODULE_VERSION(""); 版本
MODULE_DEVICE_TABLE(""); 设备表
MODULE_ALIAS("");  别名

*/
static int_init hello_init(void) //  __init  加载的模块函数必须实现
{ //  通过 module_init  加载模块函数
printk(KERN_ERR "hello world!\n");
return 0;
}

static void_exit hello_exit(void)   //  __exit 卸载模块函数,通过module_init 注册
{
printk(KERN_EMERG"hello exit!\n");
}

module_init(hello_init);            // 注册,模块函数。module_init 
module_exit(hello_exit);



######################### 5-1-2#################


#include<linux/module.h>
#include<linux/moduleparam.h>
#include<linux/kernel.h>


MODULE_LICENSE("GPL")
MODULE_AUTHOR("GOAT")
MODULE_DESCRIPTION("THIS MODULE IS A PARAM EXAMPLE");


#define MAX_ARRAY 6
static int int_var=0;
static char *str_var="defaule";
static ini int_array[6];
int narr;


module_param(int_var,int,0644);   //模块参数传入API ,函数原型 module_param(name,type,perm);
//name: 用户看到参数名,有是模块内接受参数变量
//type:参数数据类型
//访问权限,0644表示访问权限与linux文件访问权限相同


MODULE_PARM_DESC(int_var,"A integer variable"); //通过宏对参数进行说明
module_param(str_var,charp,0644);
MUDULE_PARM_DESC(str_var,"a string variable");


module


#############5-1-4######################
//calculate.c
#include<linux/init.h>
#include<linux/module.h>


MODULE_LICENSE("GPL");    //声明权限


int add_integar(int a,int b)
{
return a+b;
}


int sub_integar(int a,int b)
{
return a-b;
}

static int __init sym_init()  // 模块载入时
{
return 0;
}


static void __exit sym_exit()  // module exit
{
}


module_init(sym_init);     // module 通过这两个注册
module_exit(sym_exit);      //
EXPORT_SYMBOL(add_integar);   //导出symbol
EXPORT_SYMBOL(sub_integar);


/// hello.c ,调用calculate 中的symbol
#include<linux/moudle.h>
#incluce<linux/init.h>


MODULE_LICENSE("GPL");


extern int add_integar(int a,int b);
extern int sub_integar(int a,int b);


static int __int hello_init(void)
{
int res=add_integar(1,2);
printk(KERN_EMERG"hello init,res=%d\n",res);
return 0;
}


static void __exit hello_exit()
{
int res=sub_integar(2,1);
printk(KERN_EMERG" HELLO EXIT,res=%d\n",res);

}
module_init(hello_init);
module_exit(hello_exit);


#############################end###########################

##########// asmble file search the register########
AREA  start ,CODE ,READONLY
ENTRY
CODE32


START
ADR R9,DAT1                     ;address read ,dat1  to r9
ADR R10, DAT2


MOV R0, #0X1
MOV R1, #0X2
ADD R0,R0,#0X4


MOV R2,R1
SUB R1,R2,R0
ADD R2,R2,R0,LSL #1


LDR R1,[R9] ; PUT [R9]DATA TO R1
STR R2,[R9] ; PUT R2 DATA TO [R9]
SWP R1,R1,[R9] ; EXCHANGE [R9]DATA WITH R1


LDR R0,[R9,#4]                  ; SEND [R9+4] to R0
STR R0,[R10,#4] ; SEND    R0 TO []


LDMIA R9!,{R1-R5,R8} ; LODE,多寄存器寻址,把R1-R5,R8的值给R9所指的地址,r9++
STMIA R10!,{R1-R5,R8} ;STORE,R10 ++,所指的address 给到R1-R5,R8,


B HALT
NOP
NOP
NOP
HALT
B HALT
DLEGTH EQU 6
DAT1 
DCD 0X1000
DCD 0X2000
DCD 0X3000
DCD 0X4000
DCD 0X5000
DCD 0X6000
NOP
NOP
DAT2
SPACE DLEGTH*4

END


#########################################################


############################# ASEMB 伪指令运用########
CONST1 EQU  0X50003100
CONST2 EQU  0X20


GBLL VaIL
GBLA VaIA

AREA START ,CODE ,READONLY
ENTRY
CODE32
start
LDR R0,=CONST1   ; sent constl1 to r0
LDR R1,=CONST2 ;send   const2 address to r1

ADR R2,start
LDR R3,start  
LDR R4,=start
LDR R5,=0X50200000
LDR R6,=0X10

MACRO
RETURN 
MOV PC,LR
MEND


VaIL  SETL   {TRUE}

IF  VaIL = {TRUE}
VaIA   SETA 0X9
BL SUM
LDR R1,=VaIA
ELSE 
B HALT
ENDIF

NOP
NOP

HALT B HALT


SUM ;function sum
MOV R0,#0
MOV R1,#1
WHILE  VaIA > 0
ADD R0,R0,R1
ADD R1,R1,#1
VaIA SETA VaIA-1
WEND
RETURN

END

###################混合编程c and asm ###################################
// init cpu
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|

IMPORT Main
IMPORT InitStack

AREA Start,CODE 
ENTRY
CODE32

LDR R0,=|Image$$RO$$Limit|
LDR R1,=|Image$$RW$$Base|
LDR R3,=|Image$$ZI$$Base|

CMP R0,R1
BEQ LOOP1

LOOP0 
CMP R1,R3
LDRCC R2,[R0],#4
STRCC R2,[R1],#4
BCC  LOOP0
LOOP1
LDR R1,=|Image$$ZI$$Limit|
MOV R2,#0
LOOP2
CMP R3,R1
STRCC R2,[R3],#4
BCC LOOP2

BL InitStack

BL InitStack

BL Main

END
// init stack
AREA  START ,CODE 
CODE32


USR_STACK_LEGTH EQU 128
SVC_STACK_LEGTH EQU 0
FIQ_STACK_LEGTH EQU 16
IRQ_STACK_LEGTH EQU 64
ABT_STACK_LEGTH EQU 0
UND_STACK_LEGTH EQU 0


EXPORT InitStack
InitStack
MOV  R0,LR
MSR CPSR_c,#0XD3
LDR SP,StackSvc
MSR CPSR_c,#0XD2

MSR CPSR_c,#0XD1
LDR SP, StackFiq

MSR CPSR_c,#0XD7
LDR SP,StackAbt

MSR CPSR_c,#0Xdb
LDR SP ,StackUnd

MSR CPSR_c,#0Xdf
LDR SP,StackUsr

MOV PC,R0

StackUsr DCD UsrStackSpace+(USR_STACK_LEGTH-1)*4
StackSvc DCD SvcStackSpace+(SVC_STACK_LEGTH-1)*4
StackIrq DCD IrqStackSpace+(IRQ_STACK_LEGTH-1)*4
StackFiq DCD FiqStackSpace+(FIQ_STACK_LEGTH-1)*4
StackAbt DCD AbtStackSpace+(ABT_STACK_LEGTH-1)*4
StackUnd DCD  UndtStackSpace+(UND_STACK_LEGTH-1)*4


AREA  MyStack,DATA,NOINIT,ALIGN=2
UsrStackSpace  SPACE USR_STACK_LEGTH*4
SvcStackSpace  SPACE SVC_STACK_LEGTH*4
IrqStackSpace  SPACE IRQ_STACK_LEGTH*4
FiqStackSpace  SPACE FIQ_STACK_LEGTH*4
AbtStackSpace  SPACE ABT_STACK_LEGTH*4
UndtStackSpace  SPACE UND_STACK_LEGTH*4


    END
//
extern int asmSum(int,int);
int cSum(int ,int);
int cSumargs(int a1,int a2,int a3,int a4,int a5);


void Main(void)
{
int a,b,sum;
a=1;
b=2;
sum=0;
sum=cSumargs(1,3,5,8,9);
sum=0;

while(a<10)
{
sum=asmSum(a,sum);
a=cSum(a,b);
}

}


int cSum(int x,int y)
{
return(x+y);
}

int cSumargs(int a1,int a2,int a3,int a4,int a5)
{
return(a1+a2+a3+a4+a5);
}


####################### 中断function###############################
#include"gpio.h"
#include"def.h"


#include"system.h"
#include"intc.h"


#define Outp32(addr,data)


#define Inp32(addr)
#define CPIO_BASE
#define CPIO ((vioatile oGPIO_REGS*)GPIO_BASE)


void_irq Isr_Eint(void);


void delay(int times);
void BuzzerPortInit(void);
void BuzzerPlay(u32 count);
void KeyIntPortInit(u32 uKey, u32 uType);
void EintClrPend(u32 uEINT_No );
void EintDisMask(u32 uEINT_No );
void KeyEIntInit(void);


int main(void)
{
SYSTEM_EnableVIC();
SYSTEM_EnableIRQ();
INTC_Init();

BuzzPortInit();
KeyEIntInit();

while(1);
}


void delay(int times)
{
int i;
for(;times>0;times--)
 for(i=0;i<3000;i++);
}

void BuzzPortInit(void)
{
u32 uConValue;
//set cpio,set input and output
uConValue=GPIO->rGPIOFCON;
uConValue &= ~(0x3<<30);
uConValue |= 0x1<<30;
GPIO->rGPIOFCON = uConValue ;
}


void BuzzerPlay(u32 count)
{
while(count--)
{
GPIO->rCPIOFDAT |=0X1<<15;
delay(500);
GPIO->rCPIOFDAT &=~(OX1<<15);
delay(500);
}

void _irq lsr_Eint(void)
{
//  pending waiting for the intrreput
EintCIrPend(0);
EintCIrPend(2);
EintCIrPend(4);

BuzzerPlay(3);
Outp32(rVIC0ADDR,0);
}


void KeyIntPortInit(u32 Ukey,u32 uType)
{
u32 uConValue;
if(uKey==0||uKey>6)
return ;
//first set the extened function,cpnx set the interrupt
uConValue=GPIO->rGPIONCON;
uConValue &=~(0X3<<((uKey-1)<<1);
uConValue |=0x2<<((uKey-1)<<1);
GPIO->rGPIONCON = uConVaule;

//then set the up down resistor,disable
uConValue = GPIO->rGPIONPUD;
uConValue &=~(0X3<<((uKey-1)<<1));
uConValue |=0x0<<((uKey-1)<<1);
GPIO->rGPI0NPUD=uConValue;

//可见,eint0,1是同时设置的 set the intrupt type
uConValue =GPIO->rEINT0CON0;
uConValue &=~(0x7<<(((uKey-1)/2)<<2));
uConValue |=uType<<(((uKey-1)/2)<<2);
GPIO->rEINT0CON0=uConValue;


}

void EintClrPend(u32 uEINT_No)
{  // ds10-62; pending mean waiting ,wait for the intrupt
GPIO->rEINT0PEND |=1<<uENIT_NO;
}

void EintDisMask(u32 uEINT_No)
{   //mask the interrupt 0 enable,1 mask
u32 uConValue;
uConValue=GPIO->rEINT0MASK;
uConValue &=~(0x1<<uEINT_No);
GPIO->rENIT0MASK=uConValue;
}
void keyEIntInit(void)
{
u32 uConValue;
KeyIntPortInit(1,Low_Level);
KeyIntPortInit(3,Failing_Edge);
KeyIntPortInit(5,Both_Edge);

EintClrPend(0);
EintClrPend(2);
EintClrPend(4);

//write the number of interrupt to the vic0 ,next is the functionname
Outp32(rVIC0VECTADDR,(unsigned)lsr_Eint);
outp32(rVIC0VECTADDR+4,(unsigned)lsr_Eint);

//  set the interrupt enable 
// read the rVIC0INTERNTENABLE DATA
//the setdata 
uConValue = Inp32(rVIC0INTENABLE);
uConValue |= (1<<NUM_EINT0)|(1<<NUM_EINT1);
Outp32(rVIC0NTENABLE,uConVable);

EintDisMask(0);
EintDisMask(2);
EintDisMask(4);

}

#######################timer and interrupt#########################################
#include "sfr6410.h"
#include "gpio.h"
#include "def.h"


#include "library.h"
#include "system.h"
#include "intc.h"
#include "timer.h"


extern SYSC_GetClkInform(viod);


#define GPIO ((volatile oGPIO_REGS*)GPIO_BASE)


void _irq lsr_Timer(void);


void delay(int times);
void LedPortInit(void);
void LedDisplay(u8 data);
void TimerClrPend(u32 utime);
void TimerDisMask(u32 utime);
void TimerClrInit(u32 utime,u32 ms);
void TimerStart(u32 uTimer_No);
void TimerInit(void);


int main(void)

SYSTEM_EnableVIC();
SYSTEM_EnableIRQ();
// read the timer g_pclk,time 计时数
SYSC_GetClkInform();
INTC_Init();

LedPortInit();
TimerInit();
LedDisplay(0x3);

while(1);
}

vvoid delay(int times)
{
int i;
for(;times>0;times--)
for(i=3000;i>0;i--);
}

void LedPortInit(void)
{
//10-33  set gpK0~~gpK3 is output;
u32 uConValue ;
uConValue = GPIO->rGPIOKCON;
uConValue &=~(0xf|

GPIO->rGPIOKCON =uConValue;
}

void LedDisPlay(u8 data)
{
// 
u32 tmpDat;
tmpDat = GPIO->rGPIOKDAT;
tmpDat =(tmpDat&0xfff0)| (~data) ;

GPIO->rGPIOKCON = tmpDat;
}

static u32 uCounter = 1;
void _irq lsr_Timer(void)
{
u32 uTmp;
uTmp = Inp32(rTINT_CSTAT);
if(uTmp&(1<<5))
{
TimerClrPend(0);
LedDisplay(1<<0);
delay(2000);
LedDisplay(0);
}
else if(uTmp&(1<<6))
{
TimerClrPend(1);
if(uCounter==5)
{
LedDisplay(1<<1);
delay(2000);
LedDisplay(0);

}
}
uCounter++;
}

void TimerClrPend(u32 uTimer_No)
{
//32-18  i kown  status intrrupt ,when the intr occur status is 0,
// mean the intrrupt is happening ,like pending bit 
// so at the intrrupt function should set 1
u32 uTmp;
uTmp = Inp32(rTINT_CSTAT);
uTmp = (uTmp & 0x1f)|(1<<(5+uTimer_No));
Outp32(rTINT_CSTAT,uTmp);
}

void TimerDisMask( u32 uTimer_No)
{
// like up,enable the intrrupt 
u32 uTmp;
uTmp = Inp32(rTINT_CSTAT);
uTmp = (uTmp & 0x1f)|(1<<uTimer_No);
Outp32(rTINT_CSTAT,uTmp);
}


// SET THE TIMER ,how long the interrupt occur
void TimerClkInit(u32 uTimer_No,u32 ms)
{
u32 uTmp;
uTmp = Inp32(rTCFG0);
// 23-13 SET THE Prescaler,
if(uTimer_No<2)
uTmp = (uTmp & ~0xff)|0x7f;
else 
uTmp = (uTmp & ~(0xff<<8))|(0x7f<<8);
Outp32(rTCFG0,uTmp);
// SET MUX=16
uTmp = Inp32(rTCF1);
uTmp = (uTmp & ~(0xf<<(uTimer_No*4)))|(0x4<<(uTimer_No*4));
Outp32(rTCFG1,uTmp);
// 填充数据,当到达时,发生中断,buffer
Outp32(rTCNTB0+0XC*uTimer_No,((g_PCLK>>11)/1000)*ms);
}

void TimerStart(u32 uTimer_No)
{
u32 uTmp;
uTmp = Inp32(rTCON);
if(uTimer_No==0)
{  // 0xa ; 自动装载(auto-reload),手动更新(manual)
uTmp = (uTmp & ~0x1f)|0xa;
Outp32(rTCON,uTmp);

// timer start; manual shutoff;auto-reload
uTmp =(uTmp &~ox1f)|0x9;
Outp32(rTCON,uTmp);
}
else 
{ // write it by yourself
uTmp = (uTmp & ~(0x1f<<(4*uTimer_No)))|0xa;
Outp32(rTCON,uTmp);

uTmp = (uTmp & ~(0x1f<<(4*uTimer_No)))|0x9;
Outp32(rTCON,uTmp);
}
}

void TimerInit(void)
{
u32 uConValue;
outp32(rTCON,0);

TimerClkInit(0,500);
TimerClkInit(1,1000);

TimerClrPend(0);
TimerClrPend(1);

Outp32(rVIC0VECTADDR+NUM_TIEMR0*4,(unsigned)lsr_Timer);
outp32(rVIC0VECTADDR+NUM_TIEMR1*4,(unsigned)lsr_Timer);

uConValue = Inp32(rVIC0INTERNABLE);
uConValue |= (1<<NUM_TIEMR0)|(1<<NUM_TIMER1);
Outp32(rVIC0INTENABLE,uConValue);

TimerDisMask(0);
TimerDisMask(1);

TimerStart(0);
TimerStart(1);
}

###############内核链表  ############################
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/list.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("List Module");
MODULE_ALIAS("List module");


struct student
{
    char name[100];
    int num;
    struct list_head list;      
// list_head已经定义,next and ptr
// struct list_head { struct list_head *next,*prev;}
};


struct student *pstudent;
struct student *tmp_student;
struct list_head student_list;
struct list_head *pos;


int mylist_init(void)
{
int i = 0;

INIT_LIST_HEAD(&student_list);  // next and ptrv pointer 指向student_list headaddress

pstudent = kmalloc(sizeof(struct student)*5,GFP_KERNEL);  // like malloc ,address
// kmalloc(size,int flags(类型));   小块连续内存
memset(pstudent,0,sizeof(struct student)*5);     //
//*memset(void *s,int ch,size n)
//将s中前n个字节替换为ch 返回s,对结构体和数组清0


for(i=0;i<5;i++)
{
       sprintf(pstudent[i].name,"Student%d",i+1);
// sprintf,把格式化的数据写到某个字符串,
// the second parameter like printf(),only changed is that put to the first parameter
// int sprintf(char *buff,const char *format,[argument]..)
pstudent[i].num = i+1; 
// pstudent point the header address ,use like array
list_add( &(pstudent[i].list), &student_list);

/*static inline void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);

// two know consecutive entries(node),next and prev node ,tow node address
static inline void __list_add( struct list_head *new,
                               struct list_head *prev,
                               struct list_head *next)
{
    next->prev = new;     //(1)
    new->next = next;     //(2)
    new->prev = prev;     //(3)
    prev->next = new;     //(4)
}
*/  //可见这是一个循环链表,good code!!! 用的很巧





list_for_each(pos,&student_list)
{
tmp_student = list_entry(pos,struct student,list);
printk("<0>student %d name: %s\n",tmp_student->num,tmp_student->name);
// 我们使用list_entry()宏在linux链表中访问链表数据。
  //原理为指针ptr指向结构体type中的成员member;通过指针ptr,返回结构体type的起始地址。
 // 定义中((unsigned long) &(type *)0)->member)意为:把0地址转化为type结构的指针,然后获取该结构中member成员的指针,并将其强制转换为unsigned long类型
// get the head address
}

return 0;
}




void mylist_exit(void)
{
int i ;
/* 实验:将for换成list_for_each来遍历删除结点,观察要发生的现象,并考虑解决办法 */
for(i=0;i<5;i++)
{
list_del(&(pstudent[i].list));     // 多此一举???
}

kfree(pstudent);
}


module_init(mylist_init);
module_exit(mylist_exit);
##########################################












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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值