ZynqRTOS上实现系统调用

在原始的RTOS中,赛灵思只用系统调用用于线程的切换,只有系统调用号0在用,今天仿照Linux系统调用实现在Zynq上的FreeRtos的系统调用实现。
1、首先实现系统调用表,用汇编编写如下:

sys_call_tlb:
	.long _sys_write
	.long _sys_open

很简单里面装了两个系统调用wirte和open,当然这个要我们自己实现,这里就简单实现一下__sys_open,如下所示:

int _sys_open(char* a, int b, int c){

	xil_printf("file name: %s, flag %d, mode %d\n", a, b, c);
	//return do_sys_open();
	return 111;
}

很简单,打印传入的参数,返回一个111,那么如何传入由用户空间传输这些参数到内核空间呢?
寄存器R0-R5传输最多六个参数,R7记录系统调用号,下面看一下提供给用户的接口open函数:

int __open(char *f, int a, int b){
	int flag = 0 ;
	
	__asm volatile ( "SWI 1" ::: "memory" );
	__asm__ ("mov %[ret], r0"
			: [ret]"=r"(flag)
	);

	return flag;
}

也比较简单,传入了字符串,int a,b,然后调用了软中断号1,即open系统调用,上面文章我们讲过Arm用R0-R3传入不大于4个的系统参数,大于四个用堆栈,而在系统调用中我们一般小于四个,保存在R0-R3中,R0作为返回值,这里也是为什么我们用汇编把R0保存在Flag中返回。
下面看软中断处理函数:

FreeRTOS_SWI_Handler:
	stmdb	sp!,{r1-r3,r6-r7,r12,lr}		/* state save from compiled code */
//由于R0-R3保存着系统参数,所以不能更改
	tst	r7, #0x20			/* check the T bit */
	ldrneh	r7, [lr,#-2]			/* Thumb mode */
	bicne	r7, r7, #0xff00			/* Thumb mode */
	ldreq	r7, [lr,#-4]			/* ARM mode */
	biceq	r7, r7, #0xff000000		/* ARM mode */

	cmp		r7, #0
	beq		_rtos_context_switch			/* SWInterrupt: call C function here */

	ldr		r6, =sys_call_tlb //导入系统调用表

	add		r7, r6, r7, lsl #2	//获取系统地址
	mov 	lr, pc//保存返回地址
	ldr 	pc, [r7]//系统调用!
	//bl		do_sys_call//恢复现场
	ldmia	sp!,{r1-r3,r6-r7,r12,lr}		/* state restore from compiled code */
	
	movs	pc, lr		/*return to the next instruction after the SWI instruction */

_rtos_context_switch:
	ldmia	sp!,{r1-r3,r6-r7,r12,lr}		/* state restore from compiled code */
	/* Save the context of the current task and select a new task to run. */
	portSAVE_CONTEXT
	LDR R0, vTaskSwitchContextConst
	BLX	R0
	portRESTORE_CONTEXT

测试:
在任务中添加Open函数,如下所示,然后打印返回值:

	xil_printf("open ret: %d\n", __open("hello txt", 1, 2));

串口输出如下:

sys call init start!
Hello from Freertos example main

file name: hello txt, flag 1, mode 2
open ret: 111
Rx task received string from Tx task: Hello World

file name: hello txt, flag 1, mode 2
open ret: 111
Rx task received string from Tx task: Hello World

file name: hello txt, flag 1, mode 2

系统调用实现成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值