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