建立工程,成功创建两个虚拟串口

This commit is contained in:
ranchuan
2023-06-21 18:00:56 +08:00
commit 3604192d8f
872 changed files with 428764 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
collect (PROJECT_LIB_TESTS main.c)
collect (PROJECT_LIB_TESTS atomic.c)
collect (PROJECT_LIB_TESTS mutex.c)
collect (PROJECT_LIB_TESTS shmem.c)
collect (PROJECT_LIB_TESTS condition.c)
collect (PROJECT_LIB_TESTS threads.c)
collect (PROJECT_LIB_TESTS spinlock.c)
collect (PROJECT_LIB_TESTS alloc.c)
collect (PROJECT_LIB_TESTS irq.c)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_MACHINE})
add_subdirectory(${PROJECT_MACHINE})
endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_MACHINE})
# vim: expandtab:ts=2:sw=2:smartindent

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdlib.h>
#include "metal-test.h"
#include <metal/alloc.h>
#include <metal/log.h>
#include <metal/sys.h>
static int alloc(void)
{
void *ptr;
ptr = metal_allocate_memory(1000);
if (!ptr) {
metal_log(METAL_LOG_DEBUG, "failed to allocate memmory\n");
return errno;
}
metal_free_memory(ptr);
return 0;
}
METAL_ADD_TEST(alloc);

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <pthread.h>
#include <stdlib.h>
#include "metal-test.h"
#include <metal/atomic.h>
#include <metal/log.h>
#include <metal/sys.h>
static const int atomic_test_count = 1000;
static void *atomic_thread(void *arg)
{
atomic_int *c = arg;
int i;
for (i = 0; i < atomic_test_count; i++)
atomic_fetch_add(c, 1);
return NULL;
}
static int atomic(void)
{
const int threads = 10;
atomic_int counter = ATOMIC_VAR_INIT(0);
int value, error;
error = metal_run(threads, atomic_thread, &counter);
if (!error) {
value = atomic_load(&counter);
value -= atomic_test_count * threads;
if (value) {
metal_log(METAL_LOG_DEBUG, "counter mismatch, delta = %d\n",
value);
error = -EINVAL;
}
}
return error;
}
METAL_ADD_TEST(atomic);

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <pthread.h>
#include "metal-test.h"
#include <metal/log.h>
#include <metal/sys.h>
#include <metal/mutex.h>
#include <metal/condition.h>
#define COUNTER_MAX 10
#define THREADS 10
METAL_MUTEX_DEFINE(lock);
static struct metal_condition nempty_condv = METAL_CONDITION_INIT;
static struct metal_condition nfull_condv = METAL_CONDITION_INIT;
static unsigned int counter;
static void *consumer_thread(void *arg)
{
(void)arg;
metal_mutex_acquire(&lock);
while (!counter)
metal_condition_wait(&nempty_condv, &lock);
counter--;
metal_condition_signal(&nfull_condv);
metal_mutex_release(&lock);
return NULL;
}
static void *producer_thread(void *arg)
{
(void)arg;
metal_mutex_acquire(&lock);
while (counter == COUNTER_MAX)
metal_condition_wait(&nfull_condv, &lock);
counter++;
metal_condition_signal(&nempty_condv);
metal_mutex_release(&lock);
return NULL;
}
static int condition(void)
{
int ret;
int ts_created;
pthread_t tids[THREADS];
/** TC1 consumer threads go first */
/** create 10 consumer threads first */
ret = metal_run_noblock(THREADS, consumer_thread, NULL, tids,
&ts_created);
if (ret < 0) {
metal_log(METAL_LOG_ERROR, "Failed to create consumer thread: %d.\n",
ret);
goto out;
}
/** create 10 producer threads next */
ret = metal_run(THREADS, producer_thread, NULL);
if (ret < 0) {
metal_log(METAL_LOG_ERROR, "Failed to create producer thread: %d.\n",
ret);
goto out;
}
/** wait for consumer threads to finish */
metal_finish_threads(THREADS, (void *)tids);
/** TC2 producer threads go first */
/** create 10 producer threads first */
ret = metal_run_noblock(THREADS, producer_thread, NULL, tids,
&ts_created);
if (ret < 0) {
metal_log(METAL_LOG_ERROR, "Failed to create consumer thread: %d.\n",
ret);
goto out;
}
/** create 10 consumer threads next */
ret = metal_run(THREADS, consumer_thread, NULL);
if (ret < 0) {
metal_log(METAL_LOG_ERROR, "Failed to create producer thread: %d.\n",
ret);
goto out;
}
out:
/** wait for producer threads to finish */
metal_finish_threads(THREADS, (void *)tids);
return ret;
}
METAL_ADD_TEST(condition);

View File

@@ -0,0 +1,213 @@
/*
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdlib.h>
#include <metal/errno.h>
#include <sys/eventfd.h>
/* We need to find the internal MAX_IRQS limit */
/* Could be retrieved from platform specific files in the future */
#define METAL_INTERNAL
#include "metal-test.h"
#include <metal/irq.h>
#include <metal/log.h>
#include <metal/sys.h>
#include <metal/list.h>
#include <metal/utilities.h>
int irq_handler(int irq, void *priv)
{
(void)irq;
(void)priv;
return 0;
}
static int irq(void)
{
int rc = 0;
char *err_msg="";
enum metal_log_level mll= metal_get_log_level();
int i, tst_irq[6];
/* Do not show LOG_ERROR or LOG_DEBUG for expected fail case */
metal_set_log_level(METAL_LOG_CRITICAL);
for (i=1; i < 6; i++) {
/* we only want to test the lib API, so create 'virtual' IRQs */
tst_irq[i] = eventfd(0,0);
metal_log(METAL_LOG_DEBUG, "%s: irq %d associated with fd %d\n", __func__, i, tst_irq[i]);
}
rc = metal_irq_register(tst_irq[1], irq_handler, 0, (void *)1);
if (rc) {
err_msg = "register irq 1 fail drv_id 1\n";
goto out;
}
rc = metal_irq_register(tst_irq[2], irq_handler, 0, (void *)1);
if (rc) {
err_msg = "register irq 2 fail drv_id 1\n";
goto out;
}
rc = metal_irq_register(tst_irq[2], irq_handler, 0, (void *)2);
if (rc) {
err_msg = "register irq 2 fail drv_id 2\n";
goto out;
}
rc = metal_irq_register(tst_irq[3], irq_handler, 0, (void *)1);
if (rc) {
err_msg = "register irq 3 fail drv_id 1\n";
goto out;
}
rc = metal_irq_register(tst_irq[4], irq_handler, 0, (void *)1);
if (rc) {
err_msg = "register irq 4 fail drv_id 1\n";
goto out;
}
rc = metal_irq_register(tst_irq[4], irq_handler, 0, (void *)2);
if (rc) {
err_msg = "register irq 4 fail drv_id 2\n";
goto out;
}
rc = metal_irq_register(tst_irq[1], irq_handler, 0, (void *)2);
if (rc) {
err_msg = "register irq 1 fail drv_id 2\n";
goto out;
}
rc = metal_irq_unregister(tst_irq[1], 0, 0, (void *)0);
if (rc) {
err_msg = "unregister irq 1 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[1], 0, 0, (void *)0);
if (!rc) {
err_msg = "unregister irq 1 success but fail expected\n";
goto out;
}
rc = metal_irq_unregister(tst_irq[2], 0, 0, (void *)2);
if (rc) {
err_msg = "unregister irq 2 drv_id 2 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[2], 0, 0, (void *)2);
if (!rc) {
err_msg = "unregister irq 2 drv_id 2 success but fail expected\n";
goto out;
}
rc = metal_irq_register(tst_irq[2], irq_handler, 0, (void *)2);
if (rc) {
err_msg = "register irq 2 fail drv_id 2\n";
goto out;
}
rc = metal_irq_unregister(tst_irq[2], 0, 0, (void *)1);
if (rc) {
err_msg = "unregister irq 2 drv_id 1 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[2], 0, 0, (void *)2);
if (rc) {
err_msg = "unregister irq 2 drv_id 2 failed \n";
goto out;
}
rc = metal_irq_register(tst_irq[3], irq_handler, 0, (void *)1);
if (!rc) {
err_msg = "register irq 3 drv_id 1 overwrite fail expected\n";
goto out;
}
rc = metal_irq_register(tst_irq[3], irq_handler, 0, (void *)2);
if (rc) {
err_msg = "register irq 3 fail drv_id 2\n";
goto out;
}
rc = metal_irq_unregister(tst_irq[3], irq_handler+1, 0, (void *)0);
if (!rc) {
err_msg = "unregister irq 3 match handler success but fail expected\n";
goto out;
}
rc = metal_irq_unregister(tst_irq[3], irq_handler, 0, (void *)0);
if (rc) {
err_msg = "unregister irq 3 match handler failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[4], irq_handler, 0, (void *)2);
if (rc) {
err_msg = "unregister irq 4 match handler and drv_id 2 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[4], irq_handler, 0, (void *)1);
if (rc) {
err_msg = "unregister irq 4 match handler and drv_id 1 failed \n";
goto out;
}
rc = metal_irq_register(tst_irq[5], irq_handler, (void *)10, (void *)1);
if (rc) {
err_msg = "register irq 5 fail dev 10 drv_id 1\n";
goto out;
}
rc = metal_irq_register(tst_irq[5], irq_handler, (void *)20, (void *)2);
if (rc) {
err_msg = "register irq 5 fail dev 20 drv_id 2\n";
goto out;
}
rc = metal_irq_register(tst_irq[5], irq_handler, (void *)10, (void *)3);
if (rc) {
err_msg = "register irq 5 fail dev 10 drv_id 3\n";
goto out;
}
rc = metal_irq_register(tst_irq[5], irq_handler, 0, (void *)4);
if (rc) {
err_msg = "register irq 5 fail drv_id 4\n";
goto out;
}
rc = metal_irq_register(tst_irq[5], irq_handler, (void *)10, (void *)5);
if (rc) {
err_msg = "register irq 5 fail dev 10 drv_id 5\n";
goto out;
}
rc = metal_irq_unregister(tst_irq[5], irq_handler, (void *)10, (void *)3);
if (rc) {
err_msg = "unregister irq 5 match handle, dev 10 and drv_id 3 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[5], 0, 0, (void *)4);
if (rc) {
err_msg = "unregister irq 5 drv_id 4 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[5], 0, (void *)10, 0);
if (rc) {
err_msg = "unregister irq 5 dev 10 failed \n";
goto out;
}
rc = metal_irq_unregister(tst_irq[5], 0, (void *)20, (void *)2);
if (rc) {
err_msg = "unregister irq 5 match dev 20 and drv_id 2 failed \n";
goto out;
}
rc = 0;
out:
for (i=1; i < 6; i++) {
close(tst_irq[i]);
}
metal_set_log_level(mll);
if ((err_msg[0] != '\0') && (!rc))
rc = -EINVAL;
if (rc) metal_log(METAL_LOG_ERROR, "%s", err_msg);
return rc;
}
METAL_ADD_TEST(irq);

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "metal-test.h"
int main(void)
{
int status;
status = metal_tests_run(NULL);
return status;
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <pthread.h>
#include "metal-test.h"
#include <metal/log.h>
#include <metal/sys.h>
#include <metal/mutex.h>
static const int mutex_test_count = 1000;
static void *mutex_thread(void *arg)
{
metal_mutex_t *l = arg;
int i;
for (i = 0; i < mutex_test_count; i++) {
metal_mutex_acquire(l);
usleep(1);
metal_mutex_release(l);
}
return NULL;
}
static int mutex(void)
{
metal_mutex_t lock;
const int threads = 10;
int rc;
metal_mutex_init(&lock);
rc = metal_run(threads, mutex_thread, &lock);
metal_mutex_deinit(&lock);
return rc;
}
METAL_ADD_TEST(mutex);

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "metal-test.h"
#include <metal/log.h>
#include <metal/mutex.h>
#include <metal/shmem.h>
#include <metal/sys.h>
#include <metal/atomic.h>
static atomic_int nb_err = ATOMIC_VAR_INIT(0);
static const int shmem_threads = 10;
static void *shmem_child(void *arg)
{
const char *name = arg;
struct {
metal_mutex_t mutex;
int counter;
} *virt;
struct metal_io_region *io;
unsigned long phys;
size_t size = 2 * 1024 * 1024;
int error;
error = metal_shmem_open(name, size, &io);
if (error) {
metal_log(METAL_LOG_ERROR, "Failed shmem_open: %d.\n", error);
atomic_fetch_add(&nb_err, 1);
return NULL;
}
virt = metal_io_virt(io, 0);
phys = metal_io_phys(io, 0);
if (phys != METAL_BAD_OFFSET) {
if (virt != metal_io_phys_to_virt(io, phys)) {
atomic_fetch_add(&nb_err, 1);
metal_log(METAL_LOG_ERROR, "Failed virt != phys.\n");
}
if (phys != metal_io_virt_to_phys(io, virt)) {
atomic_fetch_add(&nb_err, 1);
metal_log(METAL_LOG_ERROR, "Failed phys != virt.\n");
}
}
metal_io_finish(io);
return NULL;
}
static int shmem(void)
{
return atomic_load(&nb_err) || metal_run(shmem_threads, shmem_child, "/foo");
}
METAL_ADD_TEST(shmem);

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <pthread.h>
#include "metal-test.h"
#include <metal/log.h>
#include <metal/sys.h>
#include <metal/spinlock.h>
static const int spinlock_test_count = 1000;
static unsigned int total = 0;
static void *spinlock_thread(void *arg)
{
struct metal_spinlock *l = arg;
int i;
for (i = 0; i < spinlock_test_count; i++) {
metal_spinlock_acquire(l);
total++;
metal_spinlock_release(l);
}
return NULL;
}
static int spinlock(void)
{
struct metal_spinlock lock = METAL_SPINLOCK_INIT;
const int threads = 10;
int value, error;
error = metal_run(threads, spinlock_thread, &lock);
if (!error) {
value = total;
value -= spinlock_test_count * threads;
if (value) {
metal_log(METAL_LOG_DEBUG, "counter mismatch, delta = %d\n",
value);
error = -EINVAL;
}
}
return error;
}
METAL_ADD_TEST(spinlock);

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <metal/sys.h>
#include <metal/utilities.h>
#include "metal-test.h"
int metal_run(int threads, metal_thread_t child, void *arg)
{
pthread_t tids[threads];
int error, ts_created;
error = metal_run_noblock(threads, child, arg, tids, &ts_created);
metal_finish_threads(ts_created, (void *)tids);
return error;
}
int metal_run_noblock(int threads, metal_thread_t child,
void *arg, void *tids, int *threads_out)
{
int error, i;
pthread_t *tid_p = (pthread_t *)tids;
if (!tids) {
metal_log(METAL_LOG_ERROR, "invalid arguement, tids is NULL.\n");
return -EINVAL;
}
error = 0;
for (i = 0; i < threads; i++) {
error = -pthread_create(&tid_p[i], NULL, child, arg);
if (error) {
metal_log(METAL_LOG_ERROR, "failed to create thread - %s\n",
strerror(error));
break;
}
}
*threads_out = i;
return error;
}
void metal_finish_threads(int threads, void *tids)
{
int i;
pthread_t *tid_p = (pthread_t *)tids;
if (!tids) {
metal_log(METAL_LOG_ERROR, "invalid argument, tids is NULL.\n");
return;
}
for (i = 0; i < threads; i++)
(void)pthread_join(tid_p[i], NULL);
}

View File

@@ -0,0 +1,3 @@
collect (PROJECT_LIB_TESTS device.c)
# vim: expandtab:ts=2:sw=2:smartindent

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <unistd.h>
#include "metal-test.h"
#include <metal/device.h>
static int device(void)
{
struct metal_device *device;
struct metal_io_region *io;
uint32_t idcode;
int error;
error = metal_device_open("platform", "f8000000.slcr", &device);
if (error)
return error;
io = metal_device_io_region(device, 0);
if (!io) {
metal_device_close(device);
return -ENODEV;
}
idcode = metal_io_read32(io, 0x530);
metal_log(METAL_LOG_DEBUG, "Read id code %x\n", idcode);
metal_device_close(device);
return 0;
}
METAL_ADD_TEST(device);