Ejemplo n.º 1
0
/*..........................................................................*/
void QActive_start_(QActive * const me, uint_fast8_t prio,
                    QEvt const *qSto[], uint_fast16_t qLen,
                    void *stkSto, uint_fast16_t stkSize,
                    QEvt const *ie)
{
    /* create the embOS message box for the AO */
    OS_CreateMB(&me->eQueue,
                (OS_U16)sizeof(QEvt *),
                (OS_UINT)qLen,
                (void *)&qSto[0]);

    me->prio = prio;  /* save the QF priority */
    QF_add_(me);      /* make QF aware of this active object */
    QMSM_INIT(&me->super, ie);  /* thake the top-most initial tran. */
    QS_FLUSH(); /* flush the trace buffer to the host */

    /* create an embOS task for the AO */
    OS_CreateTaskEx(&me->thread,
                    "AO",
                    (OS_PRIO)prio, /* embOS uses the same numbering as QP */
                    &thread_function,
                    (void OS_STACKPTR *)stkSto,
                    (OS_UINT)stkSize,
                    (OS_UINT)0,    /* no AOs at the same prio */
                    (void *)me);
}
Ejemplo n.º 2
0
Archivo: main.c Proyecto: KnightSch/qpc
/*..........................................................................*/
int main() {
    printf("History state pattern\nQP version: %s\n"
           "Press 'o' to OPEN  the door\n"
           "Press 'c' to CLOSE the door\n"
           "Press 't' to start TOASTING\n"
           "Press 'b' to start BAKING\n"
           "Press 'f' to turn the oven OFF\n"
           "Press ESC to quit...\n",
           QP_versionStr);

      /* instantiate the ToastOven HSM and trigger the initial transition */
    ToastOven_ctor();
    QMSM_INIT(the_oven, (QEvt *)0);

    for (;;) {
        QEvt e;
        uint8_t c;

        printf("\n");
        c = (uint8_t)_getch();       /* read one character from the console */
        printf("%c: ", c);

        switch (c) {
            case 'o':  e.sig = OPEN_SIG;        break;
            case 'c':  e.sig = CLOSE_SIG;       break;
            case 't':  e.sig = TOAST_SIG;       break;
            case 'b':  e.sig = BAKE_SIG;        break;
            case 'f':  e.sig = OFF_SIG;         break;
            case 0x1B: e.sig = TERMINATE_SIG;   break;
        }
                               /* dispatch the event into the state machine */
        QMSM_DISPATCH(the_oven,  &e);
    }
    return 0;
}
Ejemplo n.º 3
0
/* QActive functions =======================================================*/
void QActive_start_(QActive * const me, uint_fast8_t prio,
                    QEvt const *qSto[], uint_fast16_t qLen,
                    void *stkSto, uint_fast16_t stkSize,
                    QEvt const *ie)
{
    DWORD threadId;
    int   win32Prio;
    void *fudgedQSto;
    uint_fast16_t fudgedQLen;

    Q_REQUIRE_ID(700, ((uint_fast8_t)0 < prio) /* priority must be in range */
                 && (prio <= (uint_fast8_t)QF_MAX_ACTIVE)
                 && (qSto != (QEvt const **)0) /* queue storage must be... */
                 && (qLen > (uint_fast16_t)0)  /* ...provided */
                 && (stkSto == (void *)0));    /* statck storage must NOT...
                                               * ... be provided */

    me->prio = prio; /* set QF priority of this AO before adding it to QF */
    QF_add_(me);     /* make QF aware of this active object */

    /* ignore the original storage for the event queue 'qSto' and
    * instead allocate an oversized "fudged" storage for the queue.
    * See also NOTE2 in qf_port.h.
    */
    Q_ASSERT_ID(710, (uint32_t)qLen * QF_WIN32_FUDGE_FACTOR < USHRT_MAX);
    fudgedQLen = qLen * QF_WIN32_FUDGE_FACTOR; /* fudge the queue length */
    fudgedQSto = calloc(fudgedQLen, sizeof(QEvt *)); /* new queue storage */
    Q_ASSERT_ID(720, fudgedQSto != (void *)0); /* allocation must succeed */
    QEQueue_init(&me->eQueue, (QEvt const **)fudgedQSto, fudgedQLen);

    /* save osObject as integer, in case it contains the Win32 priority */
    win32Prio = (me->osObject != (void *)0)
                ? (int)me->osObject
                : THREAD_PRIORITY_NORMAL;

    /* create the Win32 "event" to throttle the AO's event queue */
    me->osObject = CreateEvent(NULL, FALSE, FALSE, NULL);

    QMSM_INIT(&me->super, ie); /* take the top-most initial tran. */
    QS_FLUSH(); /* flush the QS trace buffer to the host */

    /* stack size not provided? */
    if (stkSize == 0U) {
        stkSize = 1024U; /* NOTE: will be rounded up to the nearest page */
    }

    /* create a Win32 thread for the AO;
    * The thread is created with THREAD_PRIORITY_NORMAL
    */
    me->thread = CreateThread(NULL, stkSize,
                              &ao_thread, me, 0, &threadId);
    Q_ASSERT_ID(730, me->thread != (HANDLE)0); /* thread must be created */

    /* was the thread priority provided? */
    if (win32Prio != 0) {
        SetThreadPriority(me->thread, win32Prio);
    }
}
Ejemplo n.º 4
0
/*..........................................................................*/
void QActive_start_(QActive * const me, uint_fast8_t prio,
                    QEvt const *qSto[], uint_fast16_t qLen,
                    void *stkSto, uint_fast16_t stkSize,
                    QEvt const *ie)
{
    pthread_t thread;
    pthread_attr_t attr;
    struct sched_param param;

    /* p-threads allocate stack internally */
    Q_REQUIRE_ID(600, stkSto == (void *)0);

    QEQueue_init(&me->eQueue, qSto, qLen);
    pthread_cond_init(&me->osObject, 0);

    me->prio = (uint8_t)prio;
    QF_add_(me); /* make QF aware of this active object */

    QMSM_INIT(&me->super, ie); /* take the top-most initial tran. */
    QS_FLUSH(); /* flush the QS trace buffer to the host */

    pthread_attr_init(&attr);

    /* SCHED_FIFO corresponds to real-time preemptive priority-based scheduler
    * NOTE: This scheduling policy requires the superuser privileges
    */
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);

    /* see NOTE04 */
    param.sched_priority = prio
                           + (sched_get_priority_max(SCHED_FIFO)
                              - QF_MAX_ACTIVE - 3);

    pthread_attr_setschedparam(&attr, &param);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    if (stkSize == 0U) {
        /* set the allowed minimum */
        stkSize = (uint_fast16_t)PTHREAD_STACK_MIN;
    }
    pthread_attr_setstacksize(&attr, (size_t)stkSize);

    if (pthread_create(&thread, &attr, &thread_routine, me) != 0) {
        /* Creating the p-thread with the SCHED_FIFO policy failed. Most
        * probably this application has no superuser privileges, so we just
        * fall back to the default SCHED_OTHER policy and priority 0.
        */
        pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
        param.sched_priority = 0;
        pthread_attr_setschedparam(&attr, &param);
        Q_ALLEGE(pthread_create(&thread, &attr, &thread_routine, me)== 0);
    }
    pthread_attr_destroy(&attr);
    me->thread = (uint8_t)1;
}
Ejemplo n.º 5
0
int main() {
    Calc_ctor(&l_calc);   /* Calc "constructor" invokes QMsm_ctor() */

    QMSM_INIT(&l_calc.super, (QEvt *)0); /* trigger initial transition */

    for (;;) { /* event loop */
        QEvt e;
        . . .
        /* wait for the next event and assign it to the event object e */
        . . .
        QMSM_DISPATCH(&l_calc.super, &e); /* dispatch e */
    }
Ejemplo n.º 6
0
/*..........................................................................*/
void QActive_start_(QActive * const me, uint_t prio,
                    QEvt const *qSto[], uint_t qLen,
                    void *stkSto, uint_t stkSize,
                    QEvt const *ie)
{
    DWORD threadId;
    int p;

    Q_REQUIRE((qSto != (QEvt const **)0)  /* queue storage must be provided */
       && (stkSto == (void *)0));     /* Windows allocates stack internally */

    me->prio = (uint8_t)prio;
    QF_add_(me);                     /* make QF aware of this active object */

    QEQueue_init(&me->eQueue, qSto, qLen);
    me->osObject = CreateEvent(NULL, FALSE, FALSE, NULL);
    QMSM_INIT(&me->super, ie);                /* execute initial transition */

    if (stkSize == 0U) {                        /* stack size not provided? */
        stkSize = 1024U;    /* NOTE: will be rounded up to the nearest page */
    }
    me->thread = CreateThread(NULL, stkSize,
                              &thread_function, me, 0, &threadId);
    Q_ASSERT(me->thread != (HANDLE)0);            /* thread must be created */

    switch (me->prio) {              /* remap QF priority to Win32 priority */
        case 1:
            p = THREAD_PRIORITY_IDLE;
            break;
        case 2:
            p = THREAD_PRIORITY_LOWEST;
            break;
        case 3:
            p = THREAD_PRIORITY_BELOW_NORMAL;
            break;
        case (QF_MAX_ACTIVE - 1):
            p = THREAD_PRIORITY_ABOVE_NORMAL;
            break;
        case QF_MAX_ACTIVE:
            p = THREAD_PRIORITY_HIGHEST;
            break;
        default:
            p = THREAD_PRIORITY_NORMAL;
            break;
    }
    SetThreadPriority(me->thread, p);
}
Ejemplo n.º 7
0
/*..........................................................................*/
void QActive_start_(QActive * const me, uint_fast8_t prio,
                    QEvt const *qSto[], uint_fast16_t qLen,
                    void *stkSto, uint_fast16_t stkSize,
                    QEvt const *ie)
{
    /*
    * The following os_thread_def_AO object specifies the attributes of the
    * RTX thread for Active Objects. This object is allocated on the stack,
    * because it only serves to create the specific task for this AO.
    */
    osThreadDef_t os_thread_def_AO;

    /* no stack storage because RTX pre-allocates stacks internally,
    * but the queue storage and size must be provided
    */
    Q_REQUIRE_ID(510, (stkSto == (void *)0)
                      && (qSto != (QEvt const **)0)
                      && (qLen > (uint_fast16_t)0));

    /* create the QP event queue for the AO */
    QEQueue_init(&me->eQueue, qSto, qLen);

    me->prio = prio;  /* save the QF priority */
    QF_add_(me);      /* make QF aware of this active object */
    QMSM_INIT(&me->super, ie);  /* thake the top-most initial tran. */
    QS_FLUSH(); /* flush the trace buffer to the host */

    /* create the RTX thread for the AO... */
    os_thread_def_AO.pthread   = &ao_thread;  /* RTX thread routine for AOs */
    os_thread_def_AO.instances = (uint32_t)1; /* # instances of this thread */
    os_thread_def_AO.stacksize = (uint32_t)stkSize; /* stack size [BYTES!] */
    os_thread_def_AO.tpriority =
        (me->osObject != (uint32_t)0)    /* RTX priority provided? */
            ? (osPriority)(me->osObject) /* use the provided value */
            : osPriorityNormal;          /* use the default */
    me->thread = osThreadCreate(&os_thread_def_AO, (void *)me);

    /* ensure that the thread was created correctly */
    Q_ENSURE_ID(520, me->thread != (osThreadId)0);
}
Ejemplo n.º 8
0
/*..........................................................................*/
int main() {
    Calc_ctor();            /* explicitly instantiate the calculator object */

    printf("Calculator example, QEP version: %s\n"
           "Press '0' .. '9'     to enter a digit\n"
           "Press '.'            to enter the decimal point\n"
           "Press '+'            to add\n"
           "Press '-'            to subtract or negate a number\n"
           "Press '*'            to multiply\n"
           "Press '/'            to divide\n"
           "Press '%%'            to perform percentage calculation\n"
           "Press '=' or <Enter> to get the result\n"
           "Press 'c' or 'C'     to Cancel\n"
           "Press 'e' or 'E'     to Cancel Entry\n"
           "Press <Esc>          to quit.\n\n",
           QEP_getVersion());

    QMSM_INIT(the_calc, (QEvt *)0);           /* trigger initial transition */

    for (;;) {                                                /* event loop */
        CalcEvt e;                                      /* Calculator event */

        BSP_display();                                  /* show the display */

        printf(": ");
        fflush(stdout);
        e.key_code = (uint8_t)_getche();            /* get a char with echo */
        printf(" ");

        switch (e.key_code) {
            case 'c':                         /* intentionally fall through */
            case 'C': {
                ((QEvt *)&e)->sig = C_SIG;
                break;
            }
            case 'e':                         /* intentionally fall through */
            case 'E': {
                ((QEvt *)&e)->sig = CE_SIG;
                break;
            }
            case '0': {
                ((QEvt *)&e)->sig = DIGIT_0_SIG;
                break;
            }
            case '1':                         /* intentionally fall through */
            case '2':                         /* intentionally fall through */
            case '3':                         /* intentionally fall through */
            case '4':                         /* intentionally fall through */
            case '5':                         /* intentionally fall through */
            case '6':                         /* intentionally fall through */
            case '7':                         /* intentionally fall through */
            case '8':                         /* intentionally fall through */
            case '9': {
                ((QEvt *)&e)->sig = DIGIT_1_9_SIG;
                break;
            }
            case '.': {
                ((QEvt *)&e)->sig = POINT_SIG;
                break;
            }
            case '+':                         /* intentionally fall through */
            case '-':                         /* intentionally fall through */
            case '*':                         /* intentionally fall through */
            case '/': {
                ((QEvt *)&e)->sig = OPER_SIG;
                break;
            }
            case '=':                         /* intentionally fall through */
            case '\r': {                                       /* Enter key */
                ((QEvt *)&e)->sig = EQUALS_SIG;
                break;
            }
            case '%': {                                      /* Percent key */
                ((QEvt *)&e)->sig = PERCENT_SIG;
                break;
            }
            case '\33': {                                        /* ESC key */
                ((QEvt *)&e)->sig = OFF_SIG;
                break;
            }
            default: {
                ((QEvt *)&e)->sig = 0;                   /* invalid event */
                break;
            }
        }

        if (((QEvt *)&e)->sig != 0) {           /* valid event generated? */
            QMSM_DISPATCH(the_calc, (QEvt *)&e);        /* dispatch event */
        }
    }
    return 0;
}
Ejemplo n.º 9
0
/*..........................................................................*/
int main(int argc, char *argv[]) {
    QMsmTst_ctor();                       /* instantiate the QMsmTst object */

    if (argc > 1) {                                  /* file name provided? */
        l_outFile = fopen(argv[1], "w");
    }

    if (l_outFile == (FILE *)0) {                   /* interactive version? */
        l_outFile = stdout;            /* use the stdout as the output file */

        printf("QMsmTst example, built on %s at %s,\n"
               "QP-nano: %s.\nPress ESC to quit...\n",
               __DATE__, __TIME__, QP_getVersion());

        QMSM_INIT(the_msm);                   /* the top-most initial tran. */

        for (;;) {                                            /* event loop */
            int c;

            printf("\n>");
            c = _getche();    /* get a character from the console with echo */
            printf(": ");

            if ('a' <= c && c <= 'i') {                        /* in range? */
                Q_SIG(the_msm) = (QSignal)(c - 'a' + A_SIG);
            }
            else if ('A' <= c && c <= 'I') {                   /* in range? */
                Q_SIG(the_msm) = (QSignal)(c - 'A' + A_SIG);
            }
            else if (c == '\33') {                          /* the ESC key? */
                Q_SIG(the_msm) = TERMINATE_SIG;
            }
            else {
                Q_SIG(the_msm) = IGNORE_SIG;
            }

            QMSM_DISPATCH(the_msm);                   /* dispatch the event */
        }
    }
    else {                                                 /* batch version */
        printf("QMsmTst example, built on %s at %s, QP-nano %s\n"
               "output saved to %s\n",
               __DATE__, __TIME__, QP_getVersion(),
               argv[1]);

        fprintf(l_outFile, "QMsmTst example, QP-nano %s\n",
                QP_getVersion());

        QMSM_INIT(the_msm);                 /* take the initial transitioin */

                                       /* testing of dynamic transitions... */
        dispatch(A_SIG);
        dispatch(B_SIG);
        dispatch(D_SIG);
        dispatch(E_SIG);
        dispatch(I_SIG);
        dispatch(F_SIG);
        dispatch(I_SIG);
        dispatch(I_SIG);
        dispatch(F_SIG);
        dispatch(A_SIG);
        dispatch(B_SIG);
        dispatch(D_SIG);
        dispatch(D_SIG);
        dispatch(E_SIG);
        dispatch(G_SIG);
        dispatch(H_SIG);
        dispatch(H_SIG);
        dispatch(C_SIG);
        dispatch(G_SIG);
        dispatch(C_SIG);
        dispatch(C_SIG);

        fclose(l_outFile);
    }

    return 0;
}