2022-03-13 23:22:14 +00:00
|
|
|
|
/**
|
|
|
|
|
* @file irqmgr.c
|
|
|
|
|
*
|
|
|
|
|
* This file implements a manager for forwarding three key system interrupt events to
|
|
|
|
|
* registered clients. The architecture of this system appears to be derived in part from
|
|
|
|
|
* the libultra sched module.
|
|
|
|
|
*
|
|
|
|
|
* The interrupts the IRQ manager deals with are:
|
|
|
|
|
* - VI Retrace
|
|
|
|
|
* This event is sent to the IRQ manager by the OS VI manager which only supports
|
|
|
|
|
* the forwarding of VI events to a single message queue. The IRQ manager will
|
|
|
|
|
* forward these events to every registered client. VI retrace events are received
|
|
|
|
|
* when the Video Interface has reached the start of the vertical blanking interval,
|
|
|
|
|
* happening at approximately 60Hz on NTSC and 50Hz on PAL. Many threads sit idle
|
|
|
|
|
* until a VI Retrace event wakes them up, at which point they will perform their
|
|
|
|
|
* task and then return to idle to await the next retrace.
|
|
|
|
|
*
|
|
|
|
|
* - Pre-NMI
|
|
|
|
|
* This event is sent to the IRQ manager by the OS Interrupt Handler when the reset
|
|
|
|
|
* button on the N64 control deck is pressed. This event is forwarded to clients to
|
|
|
|
|
* inform them that a reset will occur in at least 0.5s / 500ms so they may begin any
|
|
|
|
|
* shutdown procedures.
|
|
|
|
|
*
|
|
|
|
|
* - NMI
|
|
|
|
|
* This event is sent at 450ms into the Pre-NMI phase, informing clients that the
|
|
|
|
|
* mandatory 0.5s of Pre-NMI is almost over and a reset may be imminent. This event
|
|
|
|
|
* is not to be confused with the hardware NMI interrupt signalled when the CPU is
|
|
|
|
|
* to fully reset, as by the time that interrupt is received there is no time left
|
|
|
|
|
* to do anything.
|
|
|
|
|
*/
|
2020-10-03 15:22:44 +00:00
|
|
|
|
#include "global.h"
|
|
|
|
|
#include "vt.h"
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
vu32 gIrqMgrResetStatus = IRQ_RESET_STATUS_IDLE;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
volatile OSTime sIrqMgrResetTime = 0;
|
2020-05-13 03:05:55 +00:00
|
|
|
|
volatile OSTime gIrqMgrRetraceTime = 0;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
u32 sIrqMgrRetraceCount = 0;
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
// Internal messages
|
|
|
|
|
#define IRQ_RETRACE_MSG 666
|
|
|
|
|
#define IRQ_PRENMI_MSG 669
|
|
|
|
|
#define IRQ_PRENMI450_MSG 671
|
|
|
|
|
#define IRQ_PRENMI480_MSG 672
|
|
|
|
|
#define IRQ_PRENMI500_MSG 673
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Registers a client and an associated message queue with the IRQ manager. When an
|
|
|
|
|
* interrupt event is received by the IRQ manager, these clients will be notified of
|
|
|
|
|
* the event.
|
|
|
|
|
*
|
|
|
|
|
* @param irqMgr the IrqMgr instance to register with.
|
|
|
|
|
* @param client client to register.
|
2022-04-09 00:20:23 +00:00
|
|
|
|
* @param msgQueue message queue to send notifications of interrupts to, associated with the client.
|
2022-03-13 23:22:14 +00:00
|
|
|
|
*/
|
2022-04-09 00:20:23 +00:00
|
|
|
|
void IrqMgr_AddClient(IrqMgr* irqMgr, IrqMgrClient* client, OSMesgQueue* msgQueue) {
|
2021-12-01 00:08:57 +00:00
|
|
|
|
OSIntMask prevInt;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
LogUtils_CheckNullPointer("this", irqMgr, "../irqmgr.c", 96);
|
|
|
|
|
LogUtils_CheckNullPointer("c", client, "../irqmgr.c", 97);
|
2022-04-09 00:20:23 +00:00
|
|
|
|
LogUtils_CheckNullPointer("msgQ", msgQueue, "../irqmgr.c", 98);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
prevInt = osSetIntMask(OS_IM_NONE);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-04-09 00:20:23 +00:00
|
|
|
|
client->queue = msgQueue;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
client->prev = irqMgr->clients;
|
|
|
|
|
irqMgr->clients = client;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2021-02-14 00:49:40 +00:00
|
|
|
|
osSetIntMask(prevInt);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
if (irqMgr->resetStatus >= IRQ_RESET_STATUS_PRENMI) {
|
|
|
|
|
osSendMesg(client->queue, (OSMesg)&irqMgr->prenmiMsg, OS_MESG_NOBLOCK);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
if (irqMgr->resetStatus >= IRQ_RESET_STATUS_NMI) {
|
|
|
|
|
osSendMesg(client->queue, (OSMesg)&irqMgr->nmiMsg, OS_MESG_NOBLOCK);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_RemoveClient(IrqMgr* irqMgr, IrqMgrClient* client) {
|
|
|
|
|
IrqMgrClient* iterClient = irqMgr->clients;
|
|
|
|
|
IrqMgrClient* lastClient = NULL;
|
2021-12-01 00:08:57 +00:00
|
|
|
|
OSIntMask prevInt;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
LogUtils_CheckNullPointer("this", irqMgr, "../irqmgr.c", 129);
|
|
|
|
|
LogUtils_CheckNullPointer("c", client, "../irqmgr.c", 130);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
// Disable interrupts to prevent a thread context switch while the linked list is modified
|
2022-02-02 21:43:34 +00:00
|
|
|
|
prevInt = osSetIntMask(OS_IM_NONE);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
// Remove the client
|
|
|
|
|
while (iterClient != NULL) {
|
|
|
|
|
if (iterClient == client) {
|
|
|
|
|
if (lastClient != NULL) {
|
|
|
|
|
lastClient->prev = client->prev;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-03-13 23:22:14 +00:00
|
|
|
|
irqMgr->clients = client->prev;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-03-13 23:22:14 +00:00
|
|
|
|
lastClient = iterClient;
|
|
|
|
|
iterClient = iterClient->prev;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-14 00:49:40 +00:00
|
|
|
|
osSetIntMask(prevInt);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
/**
|
|
|
|
|
* Send `msg` to every registered client if the message queue is not full. The message is
|
|
|
|
|
* appended to the back of the queue.
|
|
|
|
|
*/
|
|
|
|
|
void IrqMgr_SendMesgToClients(IrqMgr* irqMgr, OSMesg msg) {
|
|
|
|
|
IrqMgrClient* client;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
for (client = irqMgr->clients; client != NULL; client = client->prev) {
|
|
|
|
|
if (MQ_IS_FULL(client->queue)) {
|
2021-09-28 23:53:56 +00:00
|
|
|
|
// "irqmgr_SendMesgForClient: Message queue is overflowing mq=%08x cnt=%d"
|
2020-03-22 21:19:43 +00:00
|
|
|
|
osSyncPrintf(
|
|
|
|
|
VT_COL(RED, WHITE) "irqmgr_SendMesgForClient:メッセージキューがあふれています mq=%08x cnt=%d\n" VT_RST,
|
2022-03-13 23:22:14 +00:00
|
|
|
|
client->queue, MQ_GET_COUNT(client->queue));
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-03-13 23:22:14 +00:00
|
|
|
|
osSendMesg(client->queue, msg, OS_MESG_NOBLOCK);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
/**
|
|
|
|
|
* Send `msg` to every registered client if the message queue is not full. This appears to be for
|
|
|
|
|
* high-priority messages that should be jammed to the front of the queue, however a bug prevents
|
|
|
|
|
* this from working in this way and the message is appended to the back of the queue as in
|
|
|
|
|
* `IrqMgr_SendMesgToClients`.
|
|
|
|
|
*
|
|
|
|
|
* @see IrqMgr_SendMesgToClients
|
|
|
|
|
*/
|
|
|
|
|
void IrqMgr_JamMesgToClients(IrqMgr* irqMgr, OSMesg msg) {
|
|
|
|
|
IrqMgrClient* client;
|
|
|
|
|
|
|
|
|
|
for (client = irqMgr->clients; client != NULL; client = client->prev) {
|
|
|
|
|
if (MQ_IS_FULL(client->queue)) {
|
2021-09-28 23:53:56 +00:00
|
|
|
|
// "irqmgr_JamMesgForClient: Message queue is overflowing mq=%08x cnt=%d"
|
2020-03-22 21:19:43 +00:00
|
|
|
|
osSyncPrintf(
|
|
|
|
|
VT_COL(RED, WHITE) "irqmgr_JamMesgForClient:メッセージキューがあふれています mq=%08x cnt=%d\n" VT_RST,
|
2022-03-13 23:22:14 +00:00
|
|
|
|
client->queue, MQ_GET_COUNT(client->queue));
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-03-13 23:22:14 +00:00
|
|
|
|
//! @bug The function's name suggests this would use osJamMesg rather than osSendMesg, using the
|
|
|
|
|
//! latter makes this function no different than IrqMgr_SendMesgToClients.
|
|
|
|
|
osSendMesg(client->queue, msg, OS_MESG_NOBLOCK);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
/**
|
|
|
|
|
* Runs when the Pre-NMI OS Event is received. This indicates that the console will reset in at least
|
|
|
|
|
* 0.5s / 500ms. Updates the reset status and time before forwarding the Pre-NMI message to registered
|
|
|
|
|
* clients so they may begin shutting down in advance of the reset.
|
|
|
|
|
*/
|
|
|
|
|
void IrqMgr_HandlePreNMI(IrqMgr* irqMgr) {
|
|
|
|
|
u64 preNmi = IRQ_RESET_STATUS_PRENMI; // required to match
|
|
|
|
|
|
|
|
|
|
gIrqMgrResetStatus = preNmi;
|
|
|
|
|
irqMgr->resetStatus = IRQ_RESET_STATUS_PRENMI;
|
|
|
|
|
sIrqMgrResetTime = irqMgr->resetTime = osGetTime();
|
|
|
|
|
|
|
|
|
|
// Schedule a PRENMI450 message to be handled in 450ms
|
|
|
|
|
osSetTimer(&irqMgr->timer, OS_MSEC_TO_CYCLES(450), 0, &irqMgr->queue, (OSMesg)IRQ_PRENMI450_MSG);
|
|
|
|
|
IrqMgr_JamMesgToClients(irqMgr, (OSMesg)&irqMgr->prenmiMsg);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_CheckStacks(void) {
|
|
|
|
|
// "0.5 seconds after PRENMI"
|
|
|
|
|
osSyncPrintf("irqmgr.c: PRENMIから0.5秒経過\n");
|
|
|
|
|
|
|
|
|
|
if (StackCheck_Check(NULL) == STACK_STATUS_OK) {
|
|
|
|
|
// "The stack looks ok"
|
|
|
|
|
osSyncPrintf("スタックは大丈夫みたいです\n");
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-03-13 23:22:14 +00:00
|
|
|
|
osSyncPrintf("%c", BEL);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf(VT_FGCOL(RED));
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "Stack overflow or dangerous"
|
|
|
|
|
osSyncPrintf("スタックがオーバーフローしたか危険な状態です\n");
|
|
|
|
|
// "Increase stack size early or don't consume stack"
|
|
|
|
|
osSyncPrintf("早々にスタックサイズを増やすか、スタックを消費しないようにしてください\n");
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf(VT_RST);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_HandlePRENMI450(IrqMgr* irqMgr) {
|
|
|
|
|
u64 nmi = IRQ_RESET_STATUS_NMI; // required to match
|
2021-02-14 00:49:40 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
gIrqMgrResetStatus = nmi;
|
|
|
|
|
irqMgr->resetStatus = IRQ_RESET_STATUS_NMI;
|
|
|
|
|
|
|
|
|
|
// Schedule a PRENMI480 message to be handled in 30ms
|
|
|
|
|
osSetTimer(&irqMgr->timer, OS_MSEC_TO_CYCLES(30), 0, &irqMgr->queue, (OSMesg)IRQ_PRENMI480_MSG);
|
|
|
|
|
// Send the NMI event to clients
|
|
|
|
|
IrqMgr_SendMesgToClients(irqMgr, (OSMesg)&irqMgr->nmiMsg);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_HandlePRENMI480(IrqMgr* irqMgr) {
|
|
|
|
|
u32 result;
|
|
|
|
|
|
|
|
|
|
// Schedule a PRENMI500 message to be handled in 20ms
|
|
|
|
|
osSetTimer(&irqMgr->timer, OS_MSEC_TO_CYCLES(20), 0, &irqMgr->queue, (OSMesg)IRQ_PRENMI500_MSG);
|
2021-02-14 00:49:40 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
result = osAfterPreNMI();
|
|
|
|
|
if (result != 0) {
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "osAfterPreNMI returned %d !?"
|
2022-03-13 23:22:14 +00:00
|
|
|
|
osSyncPrintf("osAfterPreNMIが %d を返しました!?\n", result);
|
|
|
|
|
// osAfterPreNMI failed, try again in 1ms
|
|
|
|
|
//! @bug setting the same timer for a second time without letting the first one complete breaks
|
|
|
|
|
//! the timer linked list
|
|
|
|
|
osSetTimer(&irqMgr->timer, OS_MSEC_TO_CYCLES(1), 0, &irqMgr->queue, (OSMesg)IRQ_PRENMI480_MSG);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_HandlePRENMI500(IrqMgr* irqMgr) {
|
|
|
|
|
IrqMgr_CheckStacks();
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
/**
|
|
|
|
|
* Runs on each VI retrace, measures the time elapsed between the first and second VI retrace
|
|
|
|
|
* and dispatches VI retrace messages to each registered Irq Client
|
|
|
|
|
*/
|
|
|
|
|
void IrqMgr_HandleRetrace(IrqMgr* irqMgr) {
|
|
|
|
|
if (gIrqMgrRetraceTime == 0) {
|
|
|
|
|
if (irqMgr->retraceTime == 0) {
|
|
|
|
|
irqMgr->retraceTime = osGetTime();
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-03-13 23:22:14 +00:00
|
|
|
|
gIrqMgrRetraceTime = osGetTime() - irqMgr->retraceTime;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
sIrqMgrRetraceCount++;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
IrqMgr_SendMesgToClients(irqMgr, (OSMesg)&irqMgr->retraceMsg);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_ThreadEntry(void* arg) {
|
|
|
|
|
u32 msg = 0;
|
|
|
|
|
IrqMgr* irqMgr = (IrqMgr*)arg;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
u8 exit;
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
// "Start IRQ manager thread execution"
|
|
|
|
|
osSyncPrintf("IRQマネージャスレッド実行開始\n");
|
2020-03-17 04:31:30 +00:00
|
|
|
|
exit = false;
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
while (!exit) {
|
2022-03-13 23:22:14 +00:00
|
|
|
|
osRecvMesg(&irqMgr->queue, (OSMesg*)&msg, OS_MESG_BLOCK);
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case IRQ_RETRACE_MSG:
|
|
|
|
|
IrqMgr_HandleRetrace(irqMgr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
case IRQ_PRENMI_MSG:
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("PRE_NMI_MSG\n");
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "Scheduler: Receives PRE_NMI message"
|
|
|
|
|
osSyncPrintf("スケジューラ:PRE_NMIメッセージを受信\n");
|
2022-03-13 23:22:14 +00:00
|
|
|
|
IrqMgr_HandlePreNMI(irqMgr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
case IRQ_PRENMI450_MSG:
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("PRENMI450_MSG\n");
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "Scheduler: Receives PRENMI450 message"
|
|
|
|
|
osSyncPrintf("スケジューラ:PRENMI450メッセージを受信\n");
|
2022-03-13 23:22:14 +00:00
|
|
|
|
IrqMgr_HandlePRENMI450(irqMgr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
case IRQ_PRENMI480_MSG:
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("PRENMI480_MSG\n");
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "Scheduler: Receives PRENMI480 message"
|
|
|
|
|
osSyncPrintf("スケジューラ:PRENMI480メッセージを受信\n");
|
2022-03-13 23:22:14 +00:00
|
|
|
|
IrqMgr_HandlePRENMI480(irqMgr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
case IRQ_PRENMI500_MSG:
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("PRENMI500_MSG\n");
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "Scheduler: Receives PRENMI500 message"
|
|
|
|
|
osSyncPrintf("スケジューラ:PRENMI500メッセージを受信\n");
|
2020-03-17 04:31:30 +00:00
|
|
|
|
exit = true;
|
2022-03-13 23:22:14 +00:00
|
|
|
|
IrqMgr_HandlePRENMI500(irqMgr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2021-09-04 13:33:19 +00:00
|
|
|
|
// "Unexpected message received"
|
|
|
|
|
osSyncPrintf("irqmgr.c:予期しないメッセージを受け取りました(%08x)\n", msg);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
// "End of IRQ manager thread execution"
|
|
|
|
|
osSyncPrintf("IRQマネージャスレッド実行終了\n");
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
void IrqMgr_Init(IrqMgr* irqMgr, void* stack, OSPri pri, u8 retraceCount) {
|
|
|
|
|
LogUtils_CheckNullPointer("this", irqMgr, "../irqmgr.c", 346);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
LogUtils_CheckNullPointer("stack", stack, "../irqmgr.c", 347);
|
2021-02-14 00:49:40 +00:00
|
|
|
|
|
2022-03-13 23:22:14 +00:00
|
|
|
|
irqMgr->clients = NULL;
|
|
|
|
|
// Messages to send to each client message queue on each interrupt event
|
|
|
|
|
irqMgr->retraceMsg.type = OS_SC_RETRACE_MSG;
|
|
|
|
|
irqMgr->prenmiMsg.type = OS_SC_PRE_NMI_MSG;
|
|
|
|
|
irqMgr->nmiMsg.type = OS_SC_NMI_MSG;
|
|
|
|
|
irqMgr->resetStatus = IRQ_RESET_STATUS_IDLE;
|
|
|
|
|
irqMgr->resetTime = 0;
|
|
|
|
|
|
|
|
|
|
osCreateMesgQueue(&irqMgr->queue, irqMgr->msgBuf, ARRAY_COUNT(irqMgr->msgBuf));
|
|
|
|
|
osSetEventMesg(OS_EVENT_PRENMI, &irqMgr->queue, (OSMesg)IRQ_PRENMI_MSG);
|
|
|
|
|
osViSetEvent(&irqMgr->queue, (OSMesg)IRQ_RETRACE_MSG, retraceCount);
|
2022-04-09 00:20:23 +00:00
|
|
|
|
osCreateThread(&irqMgr->thread, THREAD_ID_IRQMGR, IrqMgr_ThreadEntry, irqMgr, stack, pri);
|
2022-03-13 23:22:14 +00:00
|
|
|
|
osStartThread(&irqMgr->thread);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|