Impl APC to run syscalls

pull/37/head
sunnycase 2019-01-24 16:54:33 +08:00
parent 4665773a4e
commit 56c394343d
12 changed files with 351 additions and 239 deletions

View File

@ -14,7 +14,7 @@ add_compile_flags(LD
# C Flags Settings
add_compile_flags(BOTH
-mcmodel=medany
-march=rv64imafdc
-march=rv64imafc
-fno-common
-ffunction-sections
-fdata-sections

View File

@ -160,6 +160,27 @@
#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
#define SYS_switch_ctx 2012
#define SYS_apc_return 2013
#define REG_EPC 0
#define REG_RA 1
#define REG_SP 2
#define REG_T0 5
#define REG_T1 6
#define REG_A0 10
#define REG_A1 11
#define REG_A2 12
#define REG_A3 13
#define REG_A4 14
#define REG_A5 15
#define REG_A6 16
#define REG_A7 17
#define REG_APC_PROC 64
#define REG_APC_RET 65
#define NUM_XCEPT_REGS (66)
#ifdef __riscv
#ifdef __riscv64

View File

@ -18,7 +18,9 @@
# define IRQ_STACK_SIZE 20480
.global g_wake_address
.global g_irq_count
.global xPortStartScheduler
.global sys_queue_apc
.section .text.start, "ax", @progbits
.globl _start
@ -73,38 +75,38 @@ _start:
csrs mstatus, t0
fssr x0
fmv.d.x f0, x0
fmv.d.x f1, x0
fmv.d.x f2, x0
fmv.d.x f3, x0
fmv.d.x f4, x0
fmv.d.x f5, x0
fmv.d.x f6, x0
fmv.d.x f7, x0
fmv.d.x f8, x0
fmv.d.x f9, x0
fmv.d.x f10,x0
fmv.d.x f11,x0
fmv.d.x f12,x0
fmv.d.x f13,x0
fmv.d.x f14,x0
fmv.d.x f15,x0
fmv.d.x f16,x0
fmv.d.x f17,x0
fmv.d.x f18,x0
fmv.d.x f19,x0
fmv.d.x f20,x0
fmv.d.x f21,x0
fmv.d.x f22,x0
fmv.d.x f23,x0
fmv.d.x f24,x0
fmv.d.x f25,x0
fmv.d.x f26,x0
fmv.d.x f27,x0
fmv.d.x f28,x0
fmv.d.x f29,x0
fmv.d.x f30,x0
fmv.d.x f31,x0
fmv.w.x f0, x0
fmv.w.x f1, x0
fmv.w.x f2, x0
fmv.w.x f3, x0
fmv.w.x f4, x0
fmv.w.x f5, x0
fmv.w.x f6, x0
fmv.w.x f7, x0
fmv.w.x f8, x0
fmv.w.x f9, x0
fmv.w.x f10,x0
fmv.w.x f11,x0
fmv.w.x f12,x0
fmv.w.x f13,x0
fmv.w.x f14,x0
fmv.w.x f15,x0
fmv.w.x f16,x0
fmv.w.x f17,x0
fmv.w.x f18,x0
fmv.w.x f19,x0
fmv.w.x f20,x0
fmv.w.x f21,x0
fmv.w.x f22,x0
fmv.w.x f23,x0
fmv.w.x f24,x0
fmv.w.x f25,x0
fmv.w.x f26,x0
fmv.w.x f27,x0
fmv.w.x f28,x0
fmv.w.x f29,x0
fmv.w.x f30,x0
fmv.w.x f31,x0
.option push
.option norelax
@ -131,27 +133,13 @@ _start:
.macro get_irq_count
csrr t0, mhartid
slli t1, t0, 3
la t2, _irq_count
la t2, g_irq_count
add t2, t2, t1
ld t3, 0(t2)
.endm
.globl trap_entry
.type trap_entry, @function
.align 2
trap_entry:
csrw mscratch, t0
ld t0, _irq_enabled
bnez t0, 1f
# Disable interrupt
li t0, MSTATUS_MPIE
csrc mstatus, t0
csrr t0, mscratch
mret
1:
csrr t0, mscratch
# Store context
addi sp, sp, -64 * REGBYTES
.macro save_context
addi sp, sp, -NUM_XCEPT_REGS * REGBYTES
sd x1, 1 * REGBYTES(sp)
sd x2, 2 * REGBYTES(sp)
@ -184,38 +172,124 @@ trap_entry:
sd x30, 30 * REGBYTES(sp)
sd x31, 31 * REGBYTES(sp)
fsd f0, ( 0 + 32) * REGBYTES(sp)
fsd f1, ( 1 + 32) * REGBYTES(sp)
fsd f2, ( 2 + 32) * REGBYTES(sp)
fsd f3, ( 3 + 32) * REGBYTES(sp)
fsd f4, ( 4 + 32) * REGBYTES(sp)
fsd f5, ( 5 + 32) * REGBYTES(sp)
fsd f6, ( 6 + 32) * REGBYTES(sp)
fsd f7, ( 7 + 32) * REGBYTES(sp)
fsd f8, ( 8 + 32) * REGBYTES(sp)
fsd f9, ( 9 + 32) * REGBYTES(sp)
fsd f10, (10 + 32) * REGBYTES(sp)
fsd f11, (11 + 32) * REGBYTES(sp)
fsd f12, (12 + 32) * REGBYTES(sp)
fsd f13, (13 + 32) * REGBYTES(sp)
fsd f14, (14 + 32) * REGBYTES(sp)
fsd f15, (15 + 32) * REGBYTES(sp)
fsd f16, (16 + 32) * REGBYTES(sp)
fsd f17, (17 + 32) * REGBYTES(sp)
fsd f18, (18 + 32) * REGBYTES(sp)
fsd f19, (19 + 32) * REGBYTES(sp)
fsd f20, (20 + 32) * REGBYTES(sp)
fsd f21, (21 + 32) * REGBYTES(sp)
fsd f22, (22 + 32) * REGBYTES(sp)
fsd f23, (23 + 32) * REGBYTES(sp)
fsd f24, (24 + 32) * REGBYTES(sp)
fsd f25, (25 + 32) * REGBYTES(sp)
fsd f26, (26 + 32) * REGBYTES(sp)
fsd f27, (27 + 32) * REGBYTES(sp)
fsd f28, (28 + 32) * REGBYTES(sp)
fsd f29, (29 + 32) * REGBYTES(sp)
fsd f30, (30 + 32) * REGBYTES(sp)
fsd f31, (31 + 32) * REGBYTES(sp)
fsw f0, ( 0 + 32) * REGBYTES(sp)
fsw f1, ( 1 + 32) * REGBYTES(sp)
fsw f2, ( 2 + 32) * REGBYTES(sp)
fsw f3, ( 3 + 32) * REGBYTES(sp)
fsw f4, ( 4 + 32) * REGBYTES(sp)
fsw f5, ( 5 + 32) * REGBYTES(sp)
fsw f6, ( 6 + 32) * REGBYTES(sp)
fsw f7, ( 7 + 32) * REGBYTES(sp)
fsw f8, ( 8 + 32) * REGBYTES(sp)
fsw f9, ( 9 + 32) * REGBYTES(sp)
fsw f10, (10 + 32) * REGBYTES(sp)
fsw f11, (11 + 32) * REGBYTES(sp)
fsw f12, (12 + 32) * REGBYTES(sp)
fsw f13, (13 + 32) * REGBYTES(sp)
fsw f14, (14 + 32) * REGBYTES(sp)
fsw f15, (15 + 32) * REGBYTES(sp)
fsw f16, (16 + 32) * REGBYTES(sp)
fsw f17, (17 + 32) * REGBYTES(sp)
fsw f18, (18 + 32) * REGBYTES(sp)
fsw f19, (19 + 32) * REGBYTES(sp)
fsw f20, (20 + 32) * REGBYTES(sp)
fsw f21, (21 + 32) * REGBYTES(sp)
fsw f22, (22 + 32) * REGBYTES(sp)
fsw f23, (23 + 32) * REGBYTES(sp)
fsw f24, (24 + 32) * REGBYTES(sp)
fsw f25, (25 + 32) * REGBYTES(sp)
fsw f26, (26 + 32) * REGBYTES(sp)
fsw f27, (27 + 32) * REGBYTES(sp)
fsw f28, (28 + 32) * REGBYTES(sp)
fsw f29, (29 + 32) * REGBYTES(sp)
fsw f30, (30 + 32) * REGBYTES(sp)
fsw f31, (31 + 32) * REGBYTES(sp)
.endm
.macro restore_context
ld x1, 1 * REGBYTES(a0)
ld x2, 2 * REGBYTES(a0)
ld x4, 4 * REGBYTES(a0)
ld x5, 5 * REGBYTES(a0)
ld x6, 6 * REGBYTES(a0)
ld x7, 7 * REGBYTES(a0)
ld x8, 8 * REGBYTES(a0)
ld x9, 9 * REGBYTES(a0)
ld x11, 11 * REGBYTES(a0)
ld x12, 12 * REGBYTES(a0)
ld x13, 13 * REGBYTES(a0)
ld x14, 14 * REGBYTES(a0)
ld x15, 15 * REGBYTES(a0)
ld x16, 16 * REGBYTES(a0)
ld x17, 17 * REGBYTES(a0)
ld x18, 18 * REGBYTES(a0)
ld x19, 19 * REGBYTES(a0)
ld x20, 20 * REGBYTES(a0)
ld x21, 21 * REGBYTES(a0)
ld x22, 22 * REGBYTES(a0)
ld x23, 23 * REGBYTES(a0)
ld x24, 24 * REGBYTES(a0)
ld x25, 25 * REGBYTES(a0)
ld x26, 26 * REGBYTES(a0)
ld x27, 27 * REGBYTES(a0)
ld x28, 28 * REGBYTES(a0)
ld x29, 29 * REGBYTES(a0)
ld x30, 30 * REGBYTES(a0)
ld x31, 31 * REGBYTES(a0)
flw f0, ( 0 + 32) * REGBYTES(a0)
flw f1, ( 1 + 32) * REGBYTES(a0)
flw f2, ( 2 + 32) * REGBYTES(a0)
flw f3, ( 3 + 32) * REGBYTES(a0)
flw f4, ( 4 + 32) * REGBYTES(a0)
flw f5, ( 5 + 32) * REGBYTES(a0)
flw f6, ( 6 + 32) * REGBYTES(a0)
flw f7, ( 7 + 32) * REGBYTES(a0)
flw f8, ( 8 + 32) * REGBYTES(a0)
flw f9, ( 9 + 32) * REGBYTES(a0)
flw f10, (10 + 32) * REGBYTES(a0)
flw f11, (11 + 32) * REGBYTES(a0)
flw f12, (12 + 32) * REGBYTES(a0)
flw f13, (13 + 32) * REGBYTES(a0)
flw f14, (14 + 32) * REGBYTES(a0)
flw f15, (15 + 32) * REGBYTES(a0)
flw f16, (16 + 32) * REGBYTES(a0)
flw f17, (17 + 32) * REGBYTES(a0)
flw f18, (18 + 32) * REGBYTES(a0)
flw f19, (19 + 32) * REGBYTES(a0)
flw f20, (20 + 32) * REGBYTES(a0)
flw f21, (21 + 32) * REGBYTES(a0)
flw f22, (22 + 32) * REGBYTES(a0)
flw f23, (23 + 32) * REGBYTES(a0)
flw f24, (24 + 32) * REGBYTES(a0)
flw f25, (25 + 32) * REGBYTES(a0)
flw f26, (26 + 32) * REGBYTES(a0)
flw f27, (27 + 32) * REGBYTES(a0)
flw f28, (28 + 32) * REGBYTES(a0)
flw f29, (29 + 32) * REGBYTES(a0)
flw f30, (30 + 32) * REGBYTES(a0)
flw f31, (31 + 32) * REGBYTES(a0)
# Restore a0
addi sp, sp, NUM_XCEPT_REGS * REGBYTES
.endm
.globl trap_entry
.type trap_entry, @function
.align 2
trap_entry:
csrw mscratch, t0
ld t0, _irq_enabled
bnez t0, 1f
# Disable interrupt
li t0, MSTATUS_MPIE
csrc mstatus, t0
csrr t0, mscratch
mret
1:
csrr t0, mscratch
# Save context
save_context
# Store mepc
csrr t0, mepc
@ -276,78 +350,26 @@ trap_entry:
# Restore mepc
ld t0, 0 * REGBYTES(a0)
csrw mepc, t0
# Store a0 to mscratch
ld t0, 10 * REGBYTES(a0)
csrw mscratch, t0
ld x1, 1 * REGBYTES(a0)
ld x2, 2 * REGBYTES(a0)
ld x4, 4 * REGBYTES(a0)
ld x5, 5 * REGBYTES(a0)
ld x6, 6 * REGBYTES(a0)
ld x7, 7 * REGBYTES(a0)
ld x8, 8 * REGBYTES(a0)
ld x9, 9 * REGBYTES(a0)
ld x11, 11 * REGBYTES(a0)
ld x12, 12 * REGBYTES(a0)
ld x13, 13 * REGBYTES(a0)
ld x14, 14 * REGBYTES(a0)
ld x15, 15 * REGBYTES(a0)
ld x16, 16 * REGBYTES(a0)
ld x17, 17 * REGBYTES(a0)
ld x18, 18 * REGBYTES(a0)
ld x19, 19 * REGBYTES(a0)
ld x20, 20 * REGBYTES(a0)
ld x21, 21 * REGBYTES(a0)
ld x22, 22 * REGBYTES(a0)
ld x23, 23 * REGBYTES(a0)
ld x24, 24 * REGBYTES(a0)
ld x25, 25 * REGBYTES(a0)
ld x26, 26 * REGBYTES(a0)
ld x27, 27 * REGBYTES(a0)
ld x28, 28 * REGBYTES(a0)
ld x29, 29 * REGBYTES(a0)
ld x30, 30 * REGBYTES(a0)
ld x31, 31 * REGBYTES(a0)
fld f0, ( 0 + 32) * REGBYTES(a0)
fld f1, ( 1 + 32) * REGBYTES(a0)
fld f2, ( 2 + 32) * REGBYTES(a0)
fld f3, ( 3 + 32) * REGBYTES(a0)
fld f4, ( 4 + 32) * REGBYTES(a0)
fld f5, ( 5 + 32) * REGBYTES(a0)
fld f6, ( 6 + 32) * REGBYTES(a0)
fld f7, ( 7 + 32) * REGBYTES(a0)
fld f8, ( 8 + 32) * REGBYTES(a0)
fld f9, ( 9 + 32) * REGBYTES(a0)
fld f10, (10 + 32) * REGBYTES(a0)
fld f11, (11 + 32) * REGBYTES(a0)
fld f12, (12 + 32) * REGBYTES(a0)
fld f13, (13 + 32) * REGBYTES(a0)
fld f14, (14 + 32) * REGBYTES(a0)
fld f15, (15 + 32) * REGBYTES(a0)
fld f16, (16 + 32) * REGBYTES(a0)
fld f17, (17 + 32) * REGBYTES(a0)
fld f18, (18 + 32) * REGBYTES(a0)
fld f19, (19 + 32) * REGBYTES(a0)
fld f20, (20 + 32) * REGBYTES(a0)
fld f21, (21 + 32) * REGBYTES(a0)
fld f22, (22 + 32) * REGBYTES(a0)
fld f23, (23 + 32) * REGBYTES(a0)
fld f24, (24 + 32) * REGBYTES(a0)
fld f25, (25 + 32) * REGBYTES(a0)
fld f26, (26 + 32) * REGBYTES(a0)
fld f27, (27 + 32) * REGBYTES(a0)
fld f28, (28 + 32) * REGBYTES(a0)
fld f29, (29 + 32) * REGBYTES(a0)
fld f30, (30 + 32) * REGBYTES(a0)
fld f31, (31 + 32) * REGBYTES(a0)
# Restore a0
restore_context
csrr a0, mscratch
addi sp, sp, 64 * REGBYTES
mret
sys_queue_apc:
addi sp, sp, -NUM_XCEPT_REGS * REGBYTES
ld t0, REG_APC_PROC * REGBYTES(sp)
jalr t0
csrw mscratch, a0
mv a0, sp
restore_context
csrr a0, mscratch
li a7, SYS_apc_return
ecall
j .
.global _init
.type _init, @function
@ -367,7 +389,7 @@ xPortStartScheduler:
j .restore
.align 3
_irq_count:
g_irq_count:
.8byte 0
.8byte 0
_irq_enabled:

View File

@ -96,6 +96,7 @@ static const char *TAG = "SYSCALL";
extern char _heap_start[];
extern char _heap_end[];
extern void sys_queue_apc();
char *_heap_cur = &_heap_start[0];
void __attribute__((noreturn)) sys_exit(int code)
@ -289,7 +290,6 @@ static void handle_ecall(uintptr_t *regs)
SYS_ID_CLOSE,
SYS_ID_GETTIMEOFDAY,
SYS_ID_LSEEK,
SYS_ID_SWITCHCONTEXT,
SYS_ID_MAX
};
@ -304,8 +304,7 @@ static void handle_ecall(uintptr_t *regs)
[SYS_ID_FSTAT] = (void *)sys_fstat,
[SYS_ID_CLOSE] = (void *)sys_close,
[SYS_ID_GETTIMEOFDAY] = (void *)sys_gettimeofday,
[SYS_ID_LSEEK] = (void *)sys_lseek,
[SYS_ID_SWITCHCONTEXT] = (void*)sys_switchcontext
[SYS_ID_LSEEK] = (void *)sys_lseek
};
#if defined(__GNUC__)
@ -313,56 +312,57 @@ static void handle_ecall(uintptr_t *regs)
#endif
uintptr_t n = regs[REG_A7];
uintptr_t syscall_id = SYS_ID_NOSYS;
switch (n)
if (n == SYS_switch_ctx)
{
case SYS_exit:
case SYS_exit_group:
syscall_id = SYS_ID_EXIT;
break;
case SYS_read:
syscall_id = SYS_ID_READ;
break;
case SYS_write:
syscall_id = SYS_ID_WRITE;
break;
case SYS_open:
syscall_id = SYS_ID_OPEN;
break;
case SYS_close:
syscall_id = SYS_ID_CLOSE;
break;
case SYS_lseek:
syscall_id = SYS_ID_LSEEK;
break;
case SYS_brk:
syscall_id = SYS_ID_BRK;
break;
case SYS_fstat:
syscall_id = SYS_ID_FSTAT;
break;
case SYS_gettimeofday:
syscall_id = SYS_ID_GETTIMEOFDAY;
case SYS_switch_ctx:
syscall_id = SYS_ID_SWITCHCONTEXT;
break;
sys_switchcontext();
regs[REG_EPC] += 4;
}
else if (n == SYS_apc_return)
{
regs[REG_EPC] = regs[REG_APC_RET];
}
else
{
uintptr_t syscall_id = SYS_ID_NOSYS;
switch (n)
{
case SYS_exit:
case SYS_exit_group:
syscall_id = SYS_ID_EXIT;
break;
case SYS_read:
syscall_id = SYS_ID_READ;
break;
case SYS_write:
syscall_id = SYS_ID_WRITE;
break;
case SYS_open:
syscall_id = SYS_ID_OPEN;
break;
case SYS_close:
syscall_id = SYS_ID_CLOSE;
break;
case SYS_lseek:
syscall_id = SYS_ID_LSEEK;
break;
case SYS_brk:
syscall_id = SYS_ID_BRK;
break;
case SYS_fstat:
syscall_id = SYS_ID_FSTAT;
break;
case SYS_gettimeofday:
syscall_id = SYS_ID_GETTIMEOFDAY;
break;
}
#if defined(__GNUC__)
#pragma GCC diagnostic warning "-Woverride-init"
#endif
uintptr_t ret = syscall_table[syscall_id](
regs[REG_A0], /* a0 */
regs[REG_A1], /* a1 */
regs[REG_A2], /* a2 */
regs[REG_A3], /* a3 */
regs[REG_A4], /* a4 */
regs[REG_A5], /* a5 */
n /* n */
);
regs[REG_A0] = ret;
regs[REG_EPC] += 4;
regs[REG_APC_PROC] = (uintptr_t)syscall_table[syscall_id];
regs[REG_APC_RET] = regs[REG_EPC] + 4;
regs[REG_EPC] = (uintptr_t)sys_queue_apc;
}
}
void __attribute__((weak, alias("handle_ecall"))) handle_ecall_u(uintptr_t *regs);

View File

@ -127,6 +127,7 @@ enum
#define INCLUDE_vTaskDelay 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1

View File

@ -25,20 +25,6 @@ extern "C"
{
#endif
#define REG_EPC 0
#define REG_RA 1
#define REG_SP 2
#define REG_A0 10
#define REG_A1 11
#define REG_A2 12
#define REG_A3 13
#define REG_A4 14
#define REG_A5 15
#define REG_A6 16
#define REG_A7 17
#define NUM_XCEPT_REGS (64)
typedef enum
{
CORE_SYNC_NONE,

View File

@ -1,26 +1,29 @@
#include <sys/lock.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "portmacro.h"
#include "semphr.h"
#include "task.h"
#include <stdlib.h>
#include <sys/lock.h>
typedef long _lock_t;
static void lock_init_generic(_lock_t *lock, uint8_t mutex_type)
{
portENTER_CRITICAL();
if (*lock)
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
{
/* nothing to do until the scheduler is running */
portEXIT_CRITICAL();
return;
}
else
if (!*lock)
{
xSemaphoreHandle new_sem = xQueueCreateMutex(mutex_type);
if (!new_sem)
{
abort();
}
*lock = (_lock_t)new_sem;
}
portEXIT_CRITICAL();
}
@ -42,12 +45,11 @@ void _lock_close(_lock_t *lock)
if (*lock)
{
xSemaphoreHandle h = (xSemaphoreHandle)(*lock);
#if (INCLUDE_xSemaphoreGetMutexHolder == 1)
configASSERT(xSemaphoreGetMutexHolder(h) == NULL);
#endif
vSemaphoreDelete(h);
*lock = 0;
}
portEXIT_CRITICAL();
}
@ -58,20 +60,43 @@ static int lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t mutex_typ
xSemaphoreHandle h = (xSemaphoreHandle)(*lock);
if (!h)
{
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
return 0; /* locking is a no-op before scheduler is up, so this "succeeds" */
lock_init_generic(lock, mutex_type);
h = (xSemaphoreHandle)(*lock);
configASSERT(h != NULL);
}
BaseType_t success;
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
if (uxPortIsInISR())
{
success = xSemaphoreTakeRecursive(h, delay);
/* In ISR Context */
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
{
vPortDebugBreak();
abort(); /* recursive mutexes make no sense in ISR context */
}
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
success = xSemaphoreTakeFromISR(h, &xHigherPriorityTaskWoken);
if (!success && delay > 0)
{
vPortDebugBreak();
abort(); /* Tried to block on mutex from ISR, couldn't... rewrite your program to avoid libc interactions in ISRs! */
}
if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR();
}
else
{
success = xSemaphoreTake(h, delay);
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
success = xSemaphoreTakeRecursive(h, delay);
else
success = xSemaphoreTake(h, delay);
}
return (success == pdTRUE) ? 0 : -1;
}
@ -103,15 +128,30 @@ static void lock_release_generic(_lock_t *lock, uint8_t mutex_type)
return;
}
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
if (uxPortIsInISR())
{
xSemaphoreGiveRecursive(h);
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
{
vPortDebugBreak();
abort(); /* recursive mutexes make no sense in ISR context */
}
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(h, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR();
}
else
{
xSemaphoreGive(h);
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX)
{
xSemaphoreGiveRecursive(h);
}
else
{
xSemaphoreGive(h);
}
}
}
void _lock_release(_lock_t *lock)

View File

@ -57,6 +57,8 @@
#include <sysctl.h>
#include <syslog.h>
extern volatile uintptr_t g_irq_count[portNUM_PROCESSORS];
/* A variable is used to keep track of the critical section nesting. This
variable has to be stored as part of the task context and must be initialised to
a non zero value to ensure interrupts don't inadvertently become unmasked before
@ -93,6 +95,11 @@ UBaseType_t uxPortGetProcessorId()
return (UBaseType_t)read_csr(mhartid);
}
UBaseType_t uxPortIsInISR()
{
return g_irq_count[uxPortGetProcessorId()] > 0;
}
/*-----------------------------------------------------------*/
/* Sets the next timer interrupt
@ -117,6 +124,8 @@ void handle_irq_m_timer(uintptr_t *regs, uintptr_t cause)
{
prvSetNextTimerInterrupt();
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
return;
/* Increment the RTOS tick. */
if (xTaskIncrementTick() != pdFALSE)
vTaskSwitchContext();
@ -216,3 +225,8 @@ UBaseType_t uxPortGetCPUClock()
{
return uxCPUClockRate;
}
void vPortDebugBreak(void)
{
asm volatile("sbreak");
}

View File

@ -94,8 +94,6 @@ typedef unsigned long UBaseType_t;
#define portCRITICAL_NESTING_IN_TCB 1
/*-----------------------------------------------------------*/
#define SYS_switch_ctx 2010
/* Scheduler utilities. */
extern void vPortYield(void);
extern void vPortYieldFromISR(void);
@ -137,7 +135,9 @@ void vPortAddNewTaskToReadyListAsync(UBaseType_t uxPsrId, void* pxNewTaskHandle)
void vPortEnterCritical(void);
void vPortExitCritical(void);
UBaseType_t uxPortGetCPUClock();
UBaseType_t uxPortGetCPUClock(void);
UBaseType_t uxPortIsInISR(void);
void vPortDebugBreak(void);
#define portGET_PROCESSOR_ID() uxPortGetProcessorId()

View File

@ -3874,7 +3874,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId();
}
else
{
if( uxSchedulerSuspended[uxPsrId] == ( UBaseType_t ) pdFALSE )
if( uxSchedulerSuspended[uxPortGetProcessorId()] == ( UBaseType_t ) pdFALSE )
{
xReturn = taskSCHEDULER_RUNNING;
}

View File

@ -5,7 +5,10 @@
#include "ff.h"
#include <FreeRTOS.h>
#include <task.h>
#include <semphr.h>
#include <stdlib.h>
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
@ -38,7 +41,6 @@ void ff_memfree (
#if FF_FS_REENTRANT /* Mutal exclusion */
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
@ -90,8 +92,24 @@ int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a gran
FF_SYNC_t sobj /* Sync object to wait */
)
{
/* FreeRTOS */
return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
if (uxPortIsInISR())
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
int success = (int)xSemaphoreTakeFromISR(sobj, &xHigherPriorityTaskWoken);
if (!success && FF_FS_TIMEOUT > 0)
{
vPortDebugBreak();
abort(); /* Tried to block on mutex from ISR, couldn't... rewrite your program to avoid libc interactions in ISRs! */
}
if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR();
return success;
}
else
{
/* FreeRTOS */
return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
}
}
@ -105,8 +123,18 @@ void ff_rel_grant (
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* FreeRTOS */
xSemaphoreGive(sobj);
if (uxPortIsInISR())
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(sobj, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR();
}
else
{
/* FreeRTOS */
xSemaphoreGive(sobj);
}
}
#endif

View File

@ -18,8 +18,8 @@ typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
typedef int LONG;
typedef unsigned int DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;