Minimal SMP program for the Zynq?

Jonathan Brandmeyer jonathan.brandmeyer at gmail.com
Thu May 7 03:19:14 UTC 2015


The enclosed program is intended to run on the Microzed platform with SMP
support enabled.  It is a POSIX version of the ticker sample program, and
it does run in single-core mode.  However, if the #defines for
CONFIGURE_SMP_APPLICATION and CONFIGURE_SMP_MAXIMUM_PROCESSORS are left
uncommented, the application does not run at all.  It does not reach the
first printf that marks entry into POSIX_Init().

The RTEMS BSP was built with
$ ../rtems/configure --prefix=$HOME/Programs/rtems_4_11 --enable-posix
--enable-smp --disable-networking --enable-cxx --enable-tests=samples
--enable-rtemsbsp="xilinx_zynq_zedboard" --target=arm-rtems4.11

I didn't see anything special in the Zynq manuals about the bitstream
design or FSBL configuration that needs changes to support SMP operation.
Unfortunately, my attempts to GDB into the target through OpenOCD have
failed, such that I cannot tell where RTEMS has locked up.

Any ideas would be greatly appreciated.

Thanks,
Jonathan


#include <bsp.h>
#include <stdlib.h>
#include <stdio.h>

void *POSIX_Init(void *args);
void *ticker_threadfunc(void *closure);

#define CONFIGURE_SMP_APPLICATION
#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER

#define CONFIGURE_UNIFIED_WORK_AREAS
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_POSIX_INIT_THREAD_TABLE

#define CONFIGURE_INIT
#include <rtems/confdefs.h>

void *
POSIX_Init(void *args)
{
    printf("Entry to POSIX_Init\n");
    const char *names[] = {
        "TAI1",
        "TAI2",
        "TAI3",
        NULL,
    };
    pthread_t threads[4];
    for (unsigned i = 0; names[i] != NULL; ++i) {
        pthread_create(&threads[i], NULL, ticker_threadfunc, (void
*)names[i]);
        // Spread the tasks' start times out a pinch.
        sleep(2);
    }

    // Verify SMP operation.
    printf("Running on %lu cores\n", rtems_get_processor_count());

    for (unsigned i = 0; names[i] != NULL; ++i) {
        pthread_join(threads[i], NULL);
        printf("joined with thread %d\n", i);
    }
    printf("Exiting\n");
    // Huh.  The following does not behave as expected.  Instead of calling
    // exit(), nothing happens.
    // pthread_exit(NULL);
    exit(EXIT_SUCCESS);
    return NULL;
}

#include <stdbool.h>
#include <time.h>
#include <unistd.h>

void *
ticker_threadfunc(void *closure)
{
    const char *threadname = closure;

    struct timespec begin;
    clock_gettime(CLOCK_REALTIME, &begin);
    while (true) {
        struct timespec now;
        clock_gettime(CLOCK_REALTIME, &now);

        struct tm formatted_now;
        gmtime_r(&now.tv_sec, &formatted_now);
        printf("%s: %04d-%02d-%02d %02d:%02d:%02d\n",
                threadname,
                formatted_now.tm_year,
                formatted_now.tm_mon,
                formatted_now.tm_mday,
                formatted_now.tm_hour,
                formatted_now.tm_min,
                formatted_now.tm_sec);

        sleep(5);
        if (now.tv_sec - begin.tv_sec >= 30) {
            pthread_exit(NULL);
        }
    }
    // Unreachable.
    return NULL;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20150506/37fd10d5/attachment.html>


More information about the users mailing list